@@ -14,55 +14,60 @@ abstract class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::CallCfgNode
1414
1515private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck {
1616 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+ )
2531 }
2632}
2733
2834private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck {
2935 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
3238 |
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 ( )
4549 )
4650 }
4751}
4852
4953private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck {
5054 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
5357 |
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 ( )
6671 )
6772 }
6873}
@@ -77,11 +82,11 @@ private string clientIpParameterName() {
7782}
7883
7984/** A data flow sink for ip address forgery vulnerabilities. */
80- abstract class ClientSuppliedIpUsedInSecurityCheckSink extends DataFlow:: Node { }
85+ abstract class PossibleSecurityCheck extends DataFlow:: Node { }
8186
8287/** 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 ( ) }
8590}
8691
8792/**
@@ -90,7 +95,7 @@ private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink {
9095 * For example: `if not ipAddr.startswith('192.168.') : ...` determine whether the client ip starts
9196 * with `192.168.`, and the program can be deceived by forging the ip address.
9297 */
93- private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink {
98+ private class CompareSink extends PossibleSecurityCheck {
9499 CompareSink ( ) {
95100 exists ( Call call |
96101 call .getFunc ( ) .( Attribute ) .getName ( ) = "startswith" and
0 commit comments