mirror of
https://github.com/github/codeql.git
synced 2026-01-12 22:14:47 +01:00
99 lines
2.9 KiB
Plaintext
99 lines
2.9 KiB
Plaintext
/**
|
|
* Provides classes and predicates for working with the [http-proxy](https://www.npmjs.com/package/http-proxy) library.
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Provides classes and predicates modeling the [http-proxy](https://www.npmjs.com/package/http-proxy) library.
|
|
*/
|
|
private module HttpProxy {
|
|
/**
|
|
* A call that creates a http proxy.
|
|
*/
|
|
class CreateServerCall extends API::CallNode, ClientRequest::Range {
|
|
CreateServerCall() {
|
|
this =
|
|
API::moduleImport("http-proxy")
|
|
.getMember(["createServer", "createProxyServer", "createProxy"])
|
|
.getACall()
|
|
}
|
|
|
|
override DataFlow::Node getUrl() { result = getParameter(0).getMember("target").getARhs() }
|
|
|
|
override DataFlow::Node getHost() {
|
|
result = getParameter(0).getMember("target").getMember("host").getARhs()
|
|
}
|
|
|
|
override DataFlow::Node getADataNode() { none() }
|
|
}
|
|
|
|
/**
|
|
* A call that proxies a request to some target.
|
|
*/
|
|
class ProxyCall extends API::CallNode, ClientRequest::Range {
|
|
string method;
|
|
|
|
ProxyCall() {
|
|
method = ["ws", "web"] and
|
|
this = any(CreateServerCall server).getReturn().getMember(method).getACall()
|
|
}
|
|
|
|
private API::Node getOptionsObject() {
|
|
exists(int optionsIndex |
|
|
method = "web" and optionsIndex = 2
|
|
or
|
|
method = "ws" and optionsIndex = 3
|
|
|
|
|
result = getParameter(optionsIndex)
|
|
)
|
|
}
|
|
|
|
override DataFlow::Node getUrl() { result = getOptionsObject().getMember("target").getARhs() }
|
|
|
|
override DataFlow::Node getHost() {
|
|
result = getOptionsObject().getMember("target").getMember("host").getARhs()
|
|
}
|
|
|
|
override DataFlow::Node getADataNode() { none() }
|
|
}
|
|
|
|
/**
|
|
* Holds if an event handler for `event` has a HTTP request parameter at `req` and a HTTP response parameter at `res`.
|
|
*/
|
|
predicate routeHandlingEventHandler(string event, int req, int res) {
|
|
event = ["start", "end"] and req = 0 and res = 1
|
|
or
|
|
event = ["proxyReq", "proxyRes", "econnreset"] and req = 1 and res = 2
|
|
or
|
|
event = "proxyReqWs" and req = 1 and res = -10 // -10 for non-existent.
|
|
}
|
|
|
|
/**
|
|
* An http proxy event handler.
|
|
*/
|
|
class ProxyListenerCallback extends NodeJSLib::RouteHandler, DataFlow::FunctionNode {
|
|
string event;
|
|
|
|
ProxyListenerCallback() {
|
|
exists(API::CallNode call |
|
|
call = any(CreateServerCall server).getReturn().getMember(["on", "once"]).getACall() and
|
|
call.getParameter(0).getARhs().mayHaveStringValue(event) and
|
|
this = call.getParameter(1).getARhs().getAFunctionValue()
|
|
)
|
|
}
|
|
|
|
override Parameter getRequestParameter() {
|
|
exists(int req | routeHandlingEventHandler(event, req, _) |
|
|
result = getFunction().getParameter(req)
|
|
)
|
|
}
|
|
|
|
override Parameter getResponseParameter() {
|
|
exists(int res | routeHandlingEventHandler(event, _, res) |
|
|
result = getFunction().getParameter(res)
|
|
)
|
|
}
|
|
}
|
|
}
|