@@ -16,6 +16,109 @@ module Fasthttp {
16
16
/** Gets the path for the root package of fasthttp. */
17
17
string packagePath ( ) { result = package ( v1modulePath ( ) , "" ) }
18
18
19
+ private class HeaderWrite extends Http:: HeaderWrite:: Range , DataFlow:: MethodCallNode {
20
+ string methodName ;
21
+
22
+ HeaderWrite ( ) {
23
+ this .getTarget ( ) .hasQualifiedName ( packagePath ( ) , "ResponseHeader" , methodName ) and
24
+ methodName in [
25
+ "Add" , "AddBytesK" , "AddBytesKV" , "AddBytesV" , "Set" , "SetBytesK" , "SetBytesKV" ,
26
+ "SetCanonical" , "SetContentType" , "SetContentTypeBytes"
27
+ ]
28
+ or
29
+ this .getTarget ( ) .hasQualifiedName ( packagePath ( ) , "RequestCtx" , methodName ) and
30
+ methodName in [ "SetContentType" , "SetContentTypeBytes" , "Success" , "SuccessString" ]
31
+ }
32
+
33
+ override DataFlow:: Node getName ( ) {
34
+ methodName =
35
+ [
36
+ "Add" , "AddBytesK" , "AddBytesKV" , "AddBytesV" , "Set" , "SetBytesK" , "SetBytesKV" ,
37
+ "SetCanonical"
38
+ ] and
39
+ result = this .getArgument ( 0 )
40
+ }
41
+
42
+ override string getHeaderName ( ) {
43
+ result = Http:: HeaderWrite:: Range .super .getHeaderName ( )
44
+ or
45
+ methodName = [ "SetContentType" , "SetContentTypeBytes" , "Success" , "SuccessString" ] and
46
+ result = "content-type"
47
+ }
48
+
49
+ override DataFlow:: Node getValue ( ) {
50
+ if methodName = [ "SetContentType" , "SetContentTypeBytes" , "Success" , "SuccessString" ]
51
+ then result = this .getArgument ( 0 )
52
+ else result = this .getArgument ( 1 )
53
+ }
54
+
55
+ override Http:: ResponseWriter getResponseWriter ( ) {
56
+ result .( ResponseWriter ) .getAHeaderObject ( ) = this
57
+ }
58
+ }
59
+
60
+ private class ResponseWriter extends Http:: ResponseWriter:: Range {
61
+ SsaWithFields v ;
62
+
63
+ ResponseWriter ( ) {
64
+ this = v .getBaseVariable ( ) .getSourceVariable ( ) and
65
+ (
66
+ v .getType ( ) .hasQualifiedName ( packagePath ( ) , [ "Response" , "ResponseHeader" ] ) or
67
+ v .getType ( ) .( PointerType ) .getBaseType ( ) .hasQualifiedName ( packagePath ( ) , "RequestCtx" )
68
+ )
69
+ }
70
+
71
+ override DataFlow:: Node getANode ( ) { result = v .similar ( ) .getAUse ( ) .getASuccessor * ( ) }
72
+
73
+ /** Gets a header object that corresponds to this HTTP response. */
74
+ DataFlow:: MethodCallNode getAHeaderObject ( ) {
75
+ result .getTarget ( ) .getName ( ) =
76
+ [
77
+ "Add" , "AddBytesK" , "AddBytesKV" , "AddBytesV" , "Set" , "SetBytesK" , "SetBytesKV" ,
78
+ "SetCanonical" , "SetContentType" , "SetContentTypeBytes" , "Success" , "SuccessString"
79
+ ] and
80
+ this .getANode ( ) = result .getReceiver ( )
81
+ }
82
+ }
83
+
84
+ /**
85
+ * The methods that can write to HTTP Response Body.
86
+ * These methods can be dangerous if they are user controllable.
87
+ */
88
+ class HttpResponseBodySink extends SharedXss:: Sink {
89
+ HttpResponseBodySink ( ) {
90
+ exists ( Method m |
91
+ m .hasQualifiedName ( packagePath ( ) , "RequestCtx" , [ "Success" , "SuccessString" ] ) and
92
+ this = m .getACall ( ) .getArgument ( 1 )
93
+ )
94
+ }
95
+ }
96
+
97
+ private class ResponseBody extends Http:: ResponseBody:: Range {
98
+ DataFlow:: MethodCallNode call ;
99
+ string methodName ;
100
+
101
+ ResponseBody ( ) {
102
+ exists ( Method m |
103
+ m .hasQualifiedName ( packagePath ( ) , "Response" , methodName ) and
104
+ call = m .getACall ( ) and
105
+ this = call .getArgument ( 0 )
106
+ or
107
+ m .hasQualifiedName ( packagePath ( ) , "RequestCtx" , [ "Success" , "SuccessString" ] ) and
108
+ this = m .getACall ( ) .getArgument ( 1 )
109
+ ) and
110
+ methodName =
111
+ [
112
+ "AppendBody" , "AppendBodyString" , "SetBody" , "SetBodyRaw" , "SetBodyStream" ,
113
+ "SetBodyString" , "Success" , "SuccessString"
114
+ ]
115
+ }
116
+
117
+ override Http:: ResponseWriter getResponseWriter ( ) { result .getANode ( ) = call .getReceiver ( ) }
118
+
119
+ override string getAContentType ( ) { result = super .getAContentType ( ) }
120
+ }
121
+
19
122
/**
20
123
* Provide models for sanitizer/Dangerous Functions of fasthttp.
21
124
*/
@@ -208,7 +311,7 @@ module Fasthttp {
208
311
*/
209
312
module Response {
210
313
/**
211
- * A Method That send files from its input.
314
+ * A Method that sends files from its input.
212
315
* It does not check the input path against path traversal attacks, So it is a dangerous method.
213
316
*/
214
317
class FileSystemAccess extends FileSystemAccess:: Range , DataFlow:: CallNode {
@@ -221,39 +324,6 @@ module Fasthttp {
221
324
222
325
override DataFlow:: Node getAPathArgument ( ) { result = this .getArgument ( 0 ) }
223
326
}
224
-
225
- /**
226
- * The methods that can write to HTTP Response Body.
227
- * These methods can be dangerous if they are user controllable.
228
- */
229
- class HttpResponseBodySink extends SharedXss:: Sink {
230
- HttpResponseBodySink ( ) {
231
- exists ( Method m |
232
- m .hasQualifiedName ( packagePath ( ) , "Response" ,
233
- [
234
- "AppendBody" , "AppendBodyString" , "SetBody" , "SetBodyRaw" , "SetBodyStream" ,
235
- "SetBodyString"
236
- ] ) and
237
- this = m .getACall ( ) .getArgument ( 0 )
238
- )
239
- or
240
- exists ( Method write , DataFlow:: CallNode writeCall |
241
- write .hasQualifiedName ( "io" , "Writer" , "Write" ) and
242
- writeCall = write .getACall ( ) and
243
- ResponseBodyWriterFlow:: flowsTo ( writeCall .getReceiver ( ) ) and
244
- this = writeCall .getArgument ( 0 )
245
- )
246
- }
247
- }
248
-
249
- private predicate responseBodyWriterResult ( DataFlow:: Node src ) {
250
- exists ( Method responseBodyWriter |
251
- responseBodyWriter .hasQualifiedName ( packagePath ( ) , "Response" , "BodyWriter" ) and
252
- src = responseBodyWriter .getACall ( ) .getResult ( 0 )
253
- )
254
- }
255
-
256
- private module ResponseBodyWriterFlow = DataFlow:: SimpleGlobal< responseBodyWriterResult / 1 > ;
257
327
}
258
328
259
329
/**
@@ -348,19 +418,6 @@ module Fasthttp {
348
418
)
349
419
}
350
420
}
351
-
352
- /**
353
- * The methods that can write to HTTP Response Body.
354
- * These methods can be dangerous if they are user controllable.
355
- */
356
- class HttpResponseBodySink extends SharedXss:: Sink {
357
- HttpResponseBodySink ( ) {
358
- exists ( Method m |
359
- m .hasQualifiedName ( packagePath ( ) , "RequestCtx" , [ "Success" , "SuccessString" ] ) and
360
- this = m .getACall ( ) .getArgument ( 1 )
361
- )
362
- }
363
- }
364
421
}
365
422
366
423
/**
0 commit comments