Skip to content

Commit f8caec7

Browse files
committed
move the Fetch module to ClientRequests
1 parent aa463d8 commit f8caec7

File tree

2 files changed

+61
-59
lines changed

2 files changed

+61
-59
lines changed

javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,48 +1134,4 @@ module NodeJSLib {
11341134
result = moduleImport().getAPropertyRead(member)
11351135
}
11361136
}
1137-
1138-
/**
1139-
* Provides predicates for working with `fetch` and its platform-specific instances as a single module.
1140-
*/
1141-
module Fetch {
1142-
/**
1143-
* Gets a node that refers to `fetch`, or an import of one of its platform-specific instances.
1144-
*/
1145-
DataFlow::SourceNode moduleImport() {
1146-
result = DataFlow::moduleImport(["node-fetch", "cross-fetch", "isomorphic-fetch"])
1147-
or
1148-
result = DataFlow::globalVarRef("fetch") // https://fetch.spec.whatwg.org/#fetch-api
1149-
}
1150-
1151-
/**
1152-
* Gets an instance of the `Headers` class.
1153-
*/
1154-
private DataFlow::NewNode header() {
1155-
result = moduleImport().getAConstructorInvocation("Headers")
1156-
or
1157-
result = DataFlow::globalVarRef("Headers").getAnInstantiation() // https://fetch.spec.whatwg.org/#headers-class
1158-
}
1159-
1160-
/** An expression that is used as a credential in fetch-request. */
1161-
private class FetchAuthorization extends CredentialsExpr {
1162-
FetchAuthorization() {
1163-
exists(DataFlow::Node headers |
1164-
headers = header().getArgument(0)
1165-
or
1166-
headers = moduleImport().getACall().getOptionArgument(1, "headers")
1167-
|
1168-
this = headers.getALocalSource().getAPropertyWrite("Authorization").getRhs().asExpr()
1169-
)
1170-
or
1171-
exists(DataFlow::MethodCallNode appendCall |
1172-
appendCall = header().getAMethodCall(["append", "set"]) and
1173-
appendCall.getArgument(0).mayHaveStringValue("Authorization") and
1174-
this = appendCall.getArgument(1).asExpr()
1175-
)
1176-
}
1177-
1178-
override string getCredentialsKind() { result = "authorization headers" }
1179-
}
1180-
}
11811137
}

0 commit comments

Comments
 (0)