@@ -16,6 +16,109 @@ module Fasthttp {
1616 /** Gets the path for the root package of fasthttp. */
1717 string packagePath ( ) { result = package ( v1modulePath ( ) , "" ) }
1818
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+
19122 /**
20123 * Provide models for sanitizer/Dangerous Functions of fasthttp.
21124 */
@@ -208,7 +311,7 @@ module Fasthttp {
208311 */
209312 module Response {
210313 /**
211- * A Method That send files from its input.
314+ * A Method that sends files from its input.
212315 * It does not check the input path against path traversal attacks, So it is a dangerous method.
213316 */
214317 class FileSystemAccess extends FileSystemAccess:: Range , DataFlow:: CallNode {
@@ -221,39 +324,6 @@ module Fasthttp {
221324
222325 override DataFlow:: Node getAPathArgument ( ) { result = this .getArgument ( 0 ) }
223326 }
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 > ;
257327 }
258328
259329 /**
@@ -348,19 +418,6 @@ module Fasthttp {
348418 )
349419 }
350420 }
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- }
364421 }
365422
366423 /**
0 commit comments