@@ -261,28 +261,74 @@ module ClientRequest {
261261 }
262262
263263 /**
264- * A model of a URL request made using an implementation of the `fetch` API .
264+ * Provides predicates for working with `fetch` and its platform-specific instances as a single module .
265265 */
266- class FetchUrlRequest extends ClientRequest:: Range {
267- DataFlow:: Node url ;
268-
269- FetchUrlRequest ( ) {
270- this = NodeJSLib:: Fetch:: moduleImport ( ) and
271- url = getArgument ( 0 )
266+ module Fetch {
267+ /**
268+ * Gets a node that refers to `fetch`, or an import of one of its platform-specific instances.
269+ */
270+ DataFlow:: SourceNode moduleImport ( ) {
271+ result = DataFlow:: moduleImport ( [ "node-fetch" , "cross-fetch" , "isomorphic-fetch" ] )
272+ or
273+ result = DataFlow:: globalVarRef ( "fetch" ) // https://fetch.spec.whatwg.org/#fetch-api
272274 }
273275
274- override DataFlow:: Node getUrl ( ) { result = url }
276+ /**
277+ * Gets an instance of the `Headers` class.
278+ */
279+ private DataFlow:: NewNode header ( ) {
280+ result = moduleImport ( ) .getAConstructorInvocation ( "Headers" )
281+ or
282+ result = DataFlow:: globalVarRef ( "Headers" ) .getAnInstantiation ( ) // https://fetch.spec.whatwg.org/#headers-class
283+ }
275284
276- override DataFlow:: Node getHost ( ) { none ( ) }
285+ /** An expression that is used as a credential in fetch-request. */
286+ private class FetchAuthorization extends CredentialsExpr {
287+ FetchAuthorization ( ) {
288+ exists ( DataFlow:: Node headerObject |
289+ headerObject = header ( ) .getArgument ( 0 )
290+ or
291+ headerObject = moduleImport ( ) .getACall ( ) .getOptionArgument ( 1 , "headers" )
292+ |
293+ this = headerObject .getALocalSource ( ) .getAPropertyWrite ( "Authorization" ) .getRhs ( ) .asExpr ( )
294+ )
295+ or
296+ exists ( DataFlow:: MethodCallNode appendCall |
297+ appendCall = header ( ) .getAMethodCall ( [ "append" , "set" ] ) and
298+ appendCall .getArgument ( 0 ) .mayHaveStringValue ( "Authorization" ) and
299+ this = appendCall .getArgument ( 1 ) .asExpr ( )
300+ )
301+ }
277302
278- override DataFlow:: Node getADataNode ( ) {
279- exists ( string name | name = "headers" or name = "body" | result = getOptionArgument ( 1 , name ) )
303+ override string getCredentialsKind ( ) { result = "authorization headers" }
280304 }
281305
282- override DataFlow:: Node getAResponseDataNode ( string responseType , boolean promise ) {
283- responseType = "fetch.response" and
284- promise = true and
285- result = this
306+ /**
307+ * A model of a URL request made using an implementation of the `fetch` API.
308+ */
309+ class FetchUrlRequest extends ClientRequest:: Range {
310+ DataFlow:: Node url ;
311+
312+ FetchUrlRequest ( ) {
313+ this = moduleImport ( ) .getACall ( ) and
314+ url = getArgument ( 0 )
315+ }
316+
317+ override DataFlow:: Node getUrl ( ) { result = url }
318+
319+ override DataFlow:: Node getHost ( ) { none ( ) }
320+
321+ override DataFlow:: Node getADataNode ( ) {
322+ exists ( string name | name = "headers" or name = "body" |
323+ result = getOptionArgument ( 1 , name )
324+ )
325+ }
326+
327+ override DataFlow:: Node getAResponseDataNode ( string responseType , boolean promise ) {
328+ responseType = "fetch.response" and
329+ promise = true and
330+ result = this
331+ }
286332 }
287333 }
288334
0 commit comments