@@ -2,20 +2,15 @@ import python
22import semmle.python.web.Http
33
44/** The flask app class */
5- ClassValue theFlaskClass ( ) {
6- result = Value:: named ( "flask.Flask" )
7- }
5+ ClassValue theFlaskClass ( ) { result = Value:: named ( "flask.Flask" ) }
86
97/** The flask MethodView class */
10- ClassValue theFlaskMethodViewClass ( ) {
11- result = Value:: named ( "flask.views.MethodView" )
12- }
8+ ClassValue theFlaskMethodViewClass ( ) { result = Value:: named ( "flask.views.MethodView" ) }
139
14- ClassValue theFlaskReponseClass ( ) {
15- result = Value:: named ( "flask.Response" )
16- }
10+ ClassValue theFlaskReponseClass ( ) { result = Value:: named ( "flask.Response" ) }
1711
18- /** Holds if `route` is routed to `func`
12+ /**
13+ * Holds if `route` is routed to `func`
1914 * by decorating `func` with `app.route(route)`
2015 */
2116predicate app_route ( ControlFlowNode route , Function func ) {
@@ -31,29 +26,28 @@ predicate app_route(ControlFlowNode route, Function func) {
3126private predicate add_url_rule_call ( ControlFlowNode regex , ControlFlowNode callable ) {
3227 exists ( CallNode call |
3328 call .getFunction ( ) .( AttrNode ) .getObject ( "add_url_rule" ) .pointsTo ( ) .getClass ( ) = theFlaskClass ( ) and
34- regex = call .getArg ( 0 ) |
29+ regex = call .getArg ( 0 )
30+ |
3531 callable = call .getArg ( 2 ) or
3632 callable = call .getArgByName ( "view_func" )
3733 )
3834}
3935
4036/** Holds if urls matching `regex` are routed to `func` */
4137predicate add_url_rule ( ControlFlowNode regex , Function func ) {
42- exists ( ControlFlowNode callable |
43- add_url_rule_call ( regex , callable )
44- |
38+ exists ( ControlFlowNode callable | add_url_rule_call ( regex , callable ) |
4539 exists ( PythonFunctionValue f | f .getScope ( ) = func and callable .pointsTo ( f ) )
4640 or
4741 /* MethodView.as_view() */
48- exists ( MethodViewClass view_cls |
49- view_cls .asTaint ( ) .taints ( callable ) |
42+ exists ( MethodViewClass view_cls | view_cls .asTaint ( ) .taints ( callable ) |
5043 func = view_cls .lookup ( httpVerbLower ( ) ) .( FunctionValue ) .getScope ( )
5144 )
5245 /* TODO: -- Handle Views that aren't MethodViews */
5346 )
5447}
5548
56- /** Holds if urls matching `regex` are routed to `func` using
49+ /**
50+ * Holds if urls matching `regex` are routed to `func` using
5751 * any of flask's routing mechanisms.
5852 */
5953predicate flask_routing ( ControlFlowNode regex , Function func ) {
@@ -64,55 +58,39 @@ predicate flask_routing(ControlFlowNode regex, Function func) {
6458
6559/** A class that extends flask.views.MethodView */
6660private class MethodViewClass extends ClassValue {
67-
68- MethodViewClass ( ) {
69- this .getASuperType ( ) = theFlaskMethodViewClass ( )
70- }
61+ MethodViewClass ( ) { this .getASuperType ( ) = theFlaskMethodViewClass ( ) }
7162
7263 /* As we are restricted to strings for taint kinds, we need to map these classes to strings. */
73- string taintString ( ) {
74- result = "flask/" + this .getQualifiedName ( ) + ".as.view"
75- }
64+ string taintString ( ) { result = "flask/" + this .getQualifiedName ( ) + ".as.view" }
7665
7766 /* As we are restricted to strings for taint kinds, we need to map these classes to strings. */
78- TaintKind asTaint ( ) {
79- result = this .taintString ( )
80- }
67+ TaintKind asTaint ( ) { result = this .taintString ( ) }
8168}
8269
8370private class MethodViewTaint extends TaintKind {
84-
85- MethodViewTaint ( ) {
86- any ( MethodViewClass cls ) .taintString ( ) = this
87- }
71+ MethodViewTaint ( ) { any ( MethodViewClass cls ) .taintString ( ) = this }
8872}
8973
9074/** A source of method view "taint"s. */
9175private class AsView extends TaintSource {
92-
9376 AsView ( ) {
9477 exists ( ClassValue view_class |
9578 view_class .getASuperType ( ) = theFlaskMethodViewClass ( ) and
9679 this .( CallNode ) .getFunction ( ) .( AttrNode ) .getObject ( "as_view" ) .pointsTo ( view_class )
9780 )
9881 }
9982
100- override string toString ( ) {
101- result = "flask.MethodView.as_view()"
102- }
83+ override string toString ( ) { result = "flask.MethodView.as_view()" }
10384
10485 override predicate isSourceOf ( TaintKind kind ) {
10586 exists ( MethodViewClass view_class |
10687 kind = view_class .asTaint ( ) and
10788 this .( CallNode ) .getFunction ( ) .( AttrNode ) .getObject ( "as_view" ) .pointsTo ( view_class )
10889 )
10990 }
110-
11191}
11292
113-
11493class FlaskCookieSet extends CookieSet , CallNode {
115-
11694 FlaskCookieSet ( ) {
11795 this .getFunction ( ) .( AttrNode ) .getObject ( "set_cookie" ) .pointsTo ( ) .getClass ( ) = theFlaskReponseClass ( )
11896 }
@@ -122,6 +100,4 @@ class FlaskCookieSet extends CookieSet, CallNode {
122100 override ControlFlowNode getKey ( ) { result = this .getArg ( 0 ) }
123101
124102 override ControlFlowNode getValue ( ) { result = this .getArg ( 1 ) }
125-
126-
127103}
0 commit comments