Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d6afd43

Browse files
committed
add model for chrome-remote-interface as a ClientRequest
1 parent de45b1a commit d6afd43

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

change-notes/1.24/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- [for-in](https://www.npmjs.com/package/for-in)
2626
- [for-own](https://www.npmjs.com/package/for-own)
2727
- [send](https://www.npmjs.com/package/send)
28+
- [chrome-remote-interface](https://www.npmjs.com/package/chrome-remote-interface)
2829

2930
## New queries
3031

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,4 +549,72 @@ module ClientRequest {
549549
)
550550
}
551551
}
552+
553+
/**
554+
* Gets a reference to a instance of `chrome-remote-interface`.
555+
*
556+
* An instantiation of `chrome-remote-interface` either accepts a callback or returns a promise.
557+
*
558+
* The `isPromise` parameter reflects whether the reference is a promise containing
559+
* an instance of `chrome-remote-interface`, or an instance of `chrome-remote-interface`.
560+
*/
561+
private DataFlow::SourceNode chromeRemoteInterface(DataFlow::TypeTracker t, boolean isPromise) {
562+
t.start() and
563+
exists(DataFlow::CallNode call |
564+
call = DataFlow::moduleImport("chrome-remote-interface").getAnInvocation()
565+
|
566+
result = call and isPromise = true
567+
or
568+
result = call.getCallback([0 .. 1]).getParameter(0) and isPromise = false
569+
)
570+
or
571+
exists(DataFlow::TypeTracker t2 | result = chromeRemoteInterface(t2, isPromise).track(t2, t))
572+
or
573+
// Simple promise tracking.
574+
exists(DataFlow::TypeTracker t2, DataFlow::SourceNode pred |
575+
pred = chromeRemoteInterface(t2, true) and
576+
isPromise = false and
577+
(
578+
t2 = t and
579+
exists(AwaitExpr await | DataFlow::valueNode(await.getOperand()).getALocalSource() = pred |
580+
result.getEnclosingExpr() = await
581+
)
582+
or
583+
t2 = t and
584+
exists(DataFlow::MethodCallNode thenCall |
585+
thenCall.getMethodName() = "then" and pred = thenCall.getReceiver().getALocalSource()
586+
|
587+
result = thenCall.getCallback(0).getParameter(0)
588+
)
589+
)
590+
)
591+
}
592+
593+
/**
594+
* A call to navigate a browser controlled by `chrome-remote-interface` to a specific URL.
595+
*/
596+
class ChromeRemoteInterfaceRequest extends ClientRequest::Range, DataFlow::CallNode {
597+
int optionsArg;
598+
599+
ChromeRemoteInterfaceRequest() {
600+
exists(DataFlow::SourceNode instance |
601+
instance = chromeRemoteInterface(DataFlow::TypeTracker::end(), false)
602+
|
603+
optionsArg = 0 and
604+
this = instance.getAPropertyRead("Page").getAMemberCall("navigate")
605+
or
606+
optionsArg = 1 and
607+
this = instance.getAMemberCall("send") and
608+
this.getArgument(0).mayHaveStringValue("Page.navigate")
609+
)
610+
}
611+
612+
override DataFlow::Node getUrl() {
613+
result = getArgument(optionsArg).getALocalSource().getAPropertyWrite("url").getRhs()
614+
}
615+
616+
override DataFlow::Node getHost() { none() }
617+
618+
override DataFlow::Node getADataNode() { none() }
619+
}
552620
}

0 commit comments

Comments
 (0)