@@ -134,40 +134,44 @@ module NetHttp {
134134 result = call .getReceiver ( )
135135 }
136136
137- private class ResponseBody extends Http:: ResponseBody:: Range , DataFlow:: ArgumentNode {
137+ private class ResponseBody extends Http:: ResponseBody:: Range , DataFlow:: Node {
138138 DataFlow:: Node responseWriter ;
139139
140140 ResponseBody ( ) {
141- exists ( DataFlow:: CallNode call |
142- // A direct call to ResponseWriter.Write, conveying taint from the argument to the receiver
143- call .getTarget ( ) .( Method ) .implements ( "net/http" , "ResponseWriter" , "Write" ) and
144- this = call .getArgument ( 0 ) and
145- responseWriter = call .( DataFlow:: MethodCallNode ) .getReceiver ( )
146- )
147- or
148- exists ( TaintTracking:: FunctionModel model |
149- // A modeled function conveying taint from some input to the response writer,
150- // e.g. `io.Copy(responseWriter, someTaintedReader)`
151- model .taintStep ( this , responseWriter ) and
152- responseWriter .getType ( ) .implements ( "net/http" , "ResponseWriter" )
153- )
154- or
155- exists (
156- SummarizedCallable callable , DataFlow:: CallNode call , SummaryComponentStack input ,
157- SummaryComponentStack output
158- |
159- callable = call .getACalleeIncludingExternals ( ) and callable .propagatesFlow ( input , output , _)
160- |
161- // A modeled function conveying taint from some input to the response writer,
162- // e.g. `io.Copy(responseWriter, someTaintedReader)`
163- // NB. SummarizedCallables do not implement a direct call-site-crossing flow step; instead
164- // they are implemented by a function body with internal dataflow nodes, so we mimic the
165- // one-step style for the particular case of taint propagation direct from an argument or receiver
166- // to another argument, receiver or return value, matching the behavior for a `TaintTracking::FunctionModel`.
167- this = getSummaryInputOrOutputNode ( call , input ) and
168- responseWriter .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) =
169- getSummaryInputOrOutputNode ( call , output ) and
170- responseWriter .getType ( ) .implements ( "net/http" , "ResponseWriter" )
141+ this = any ( DataFlow:: CallNode call ) .getASyntacticArgument ( ) and
142+ (
143+ exists ( DataFlow:: CallNode call |
144+ // A direct call to ResponseWriter.Write, conveying taint from the argument to the receiver
145+ call .getTarget ( ) .( Method ) .implements ( "net/http" , "ResponseWriter" , "Write" ) and
146+ this = call .getArgument ( 0 ) and
147+ responseWriter = call .( DataFlow:: MethodCallNode ) .getReceiver ( )
148+ )
149+ or
150+ exists ( TaintTracking:: FunctionModel model |
151+ // A modeled function conveying taint from some input to the response writer,
152+ // e.g. `io.Copy(responseWriter, someTaintedReader)`
153+ model .taintStep ( this , responseWriter ) and
154+ responseWriter .getType ( ) .implements ( "net/http" , "ResponseWriter" )
155+ )
156+ or
157+ exists (
158+ SummarizedCallable callable , DataFlow:: CallNode call , SummaryComponentStack input ,
159+ SummaryComponentStack output
160+ |
161+ callable = call .getACalleeIncludingExternals ( ) and
162+ callable .propagatesFlow ( input , output , _)
163+ |
164+ // A modeled function conveying taint from some input to the response writer,
165+ // e.g. `io.Copy(responseWriter, someTaintedReader)`
166+ // NB. SummarizedCallables do not implement a direct call-site-crossing flow step; instead
167+ // they are implemented by a function body with internal dataflow nodes, so we mimic the
168+ // one-step style for the particular case of taint propagation direct from an argument or receiver
169+ // to another argument, receiver or return value, matching the behavior for a `TaintTracking::FunctionModel`.
170+ this = getSummaryInputOrOutputNode ( call , input ) and
171+ responseWriter .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) =
172+ getSummaryInputOrOutputNode ( call , output ) and
173+ responseWriter .getType ( ) .implements ( "net/http" , "ResponseWriter" )
174+ )
171175 )
172176 }
173177
0 commit comments