@@ -14,55 +14,60 @@ abstract class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::CallCfgNode
14
14
15
15
private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck {
16
16
FlaskClientSuppliedIpUsedInSecurityCheck ( ) {
17
- this =
18
- API:: moduleImport ( "flask" )
19
- .getMember ( "request" )
20
- .getMember ( "headers" )
21
- .getMember ( [ "get" , "get_all" , "getlist" ] )
22
- .getACall ( ) and
23
- this .getArg ( 0 ) .asCfgNode ( ) .getNode ( ) .( StrConst ) .getText ( ) .toLowerCase ( ) =
24
- clientIpParameterName ( )
17
+ exists ( RemoteFlowSource rfs , DataFlow:: AttrRead get |
18
+ rfs .getSourceType ( ) = "flask.request" and this .getFunction ( ) = get
19
+ |
20
+ // `get` is a call to request.headers.get or request.headers.get_all or request.headers.getlist
21
+ // request.headers
22
+ get .getObject ( )
23
+ .( DataFlow:: AttrRead )
24
+ // request
25
+ .getObject ( )
26
+ .getALocalSource ( ) = rfs and
27
+ get .getAttributeName ( ) in [ "get" , "get_all" , "getlist" ] and
28
+ get .getObject ( ) .( DataFlow:: AttrRead ) .getAttributeName ( ) = "headers" and
29
+ this .getArg ( 0 ) .asExpr ( ) .( StrConst ) .getText ( ) .toLowerCase ( ) = clientIpParameterName ( )
30
+ )
25
31
}
26
32
}
27
33
28
34
private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck {
29
35
DjangoClientSuppliedIpUsedInSecurityCheck ( ) {
30
- exists ( RemoteFlowSource rfs , DataFlow:: LocalSourceNode lsn |
31
- rfs .getSourceType ( ) = "django.http.request.HttpRequest" and rfs . asCfgNode ( ) = lsn . asCfgNode ( )
36
+ exists ( RemoteFlowSource rfs , DataFlow:: AttrRead get |
37
+ rfs .getSourceType ( ) = "django.http.request.HttpRequest" and this . getFunction ( ) = get
32
38
|
33
- lsn .flowsTo ( DataFlow:: exprNode ( this .getFunction ( )
34
- .asExpr ( )
35
- .( Attribute )
36
- .getObject ( )
37
- .( Attribute )
38
- .getObject ( ) ) ) and
39
- this .getFunction ( ) .asExpr ( ) .( Attribute ) .getName ( ) = "get" and
40
- this .getFunction ( ) .asExpr ( ) .( Attribute ) .getObject ( ) .( Attribute ) .getName ( ) in [
41
- "headers" , "META"
42
- ] and
43
- this .getArg ( 0 ) .asCfgNode ( ) .getNode ( ) .( StrConst ) .getText ( ) .toLowerCase ( ) =
44
- clientIpParameterName ( )
39
+ // `get` is a call to request.headers.get or request.META.get
40
+ // request.headers
41
+ get .getObject ( )
42
+ .( DataFlow:: AttrRead )
43
+ // request
44
+ .getObject ( )
45
+ .getALocalSource ( ) = rfs and
46
+ get .getAttributeName ( ) = "get" and
47
+ get .getObject ( ) .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "headers" , "META" ] and
48
+ this .getArg ( 0 ) .asExpr ( ) .( StrConst ) .getText ( ) .toLowerCase ( ) = clientIpParameterName ( )
45
49
)
46
50
}
47
51
}
48
52
49
53
private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck {
50
54
TornadoClientSuppliedIpUsedInSecurityCheck ( ) {
51
- exists ( RemoteFlowSource rfs , DataFlow:: LocalSourceNode lsn |
52
- rfs .getSourceType ( ) = "tornado.web.RequestHandler" and rfs . asCfgNode ( ) = lsn . asCfgNode ( )
55
+ exists ( RemoteFlowSource rfs , DataFlow:: AttrRead get |
56
+ rfs .getSourceType ( ) = "tornado.web.RequestHandler" and this . getFunction ( ) = get
53
57
|
54
- lsn .flowsTo ( DataFlow:: exprNode ( this .getFunction ( )
55
- .asExpr ( )
56
- .( Attribute )
57
- .getObject ( )
58
- .( Attribute )
59
- .getObject ( )
60
- .( Attribute )
61
- .getObject ( ) ) ) and
62
- this .getFunction ( ) .asExpr ( ) .( Attribute ) .getName ( ) in [ "get" , "get_list" ] and
63
- this .getFunction ( ) .asExpr ( ) .( Attribute ) .getObject ( ) .( Attribute ) .getName ( ) = "headers" and
64
- this .getArg ( 0 ) .asCfgNode ( ) .getNode ( ) .( StrConst ) .getText ( ) .toLowerCase ( ) =
65
- clientIpParameterName ( )
58
+ // `get` is a call to `rfs`.request.headers.get
59
+ // `rfs`.request.headers
60
+ get .getObject ( )
61
+ .( DataFlow:: AttrRead )
62
+ // `rfs`.request
63
+ .getObject ( )
64
+ .( DataFlow:: AttrRead )
65
+ // `rfs`
66
+ .getObject ( )
67
+ .getALocalSource ( ) = rfs and
68
+ get .getAttributeName ( ) in [ "get" , "get_list" ] and
69
+ get .getObject ( ) .( DataFlow:: AttrRead ) .getAttributeName ( ) = "headers" and
70
+ this .getArg ( 0 ) .asExpr ( ) .( StrConst ) .getText ( ) .toLowerCase ( ) = clientIpParameterName ( )
66
71
)
67
72
}
68
73
}
@@ -77,11 +82,11 @@ private string clientIpParameterName() {
77
82
}
78
83
79
84
/** A data flow sink for ip address forgery vulnerabilities. */
80
- abstract class ClientSuppliedIpUsedInSecurityCheckSink extends DataFlow:: Node { }
85
+ abstract class PossibleSecurityCheck extends DataFlow:: Node { }
81
86
82
87
/** A data flow sink for sql operation. */
83
- private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink {
84
- SqlOperationSink ( ) { this = any ( SqlExecution e ) .getSql ( ) }
88
+ private class SqlOperationAsSecurityCheck extends PossibleSecurityCheck {
89
+ SqlOperationAsSecurityCheck ( ) { this = any ( SqlExecution e ) .getSql ( ) }
85
90
}
86
91
87
92
/**
@@ -90,7 +95,7 @@ private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink {
90
95
* For example: `if not ipAddr.startswith('192.168.') : ...` determine whether the client ip starts
91
96
* with `192.168.`, and the program can be deceived by forging the ip address.
92
97
*/
93
- private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink {
98
+ private class CompareSink extends PossibleSecurityCheck {
94
99
CompareSink ( ) {
95
100
exists ( Call call |
96
101
call .getFunc ( ) .( Attribute ) .getName ( ) = "startswith" and
0 commit comments