mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge branch 'main' into aliasFlow
This commit is contained in:
@@ -42,10 +42,10 @@ module SinkEndpointFilter {
|
||||
result = "modeled database access"
|
||||
or
|
||||
// Remove calls to APIs that aren't relevant to NoSQL injection
|
||||
call.getReceiver() instanceof HTTP::RequestNode and
|
||||
call.getReceiver() instanceof Http::RequestNode and
|
||||
result = "receiver is a HTTP request expression"
|
||||
or
|
||||
call.getReceiver() instanceof HTTP::ResponseNode and
|
||||
call.getReceiver() instanceof Http::ResponseNode and
|
||||
result = "receiver is a HTTP response expression"
|
||||
)
|
||||
or
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.2.5
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
5
javascript/ql/lib/change-notes/2022-09-12-uppercase.md
Normal file
5
javascript/ql/lib/change-notes/2022-09-12-uppercase.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* Some classes/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
1
javascript/ql/lib/change-notes/released/0.2.5.md
Normal file
1
javascript/ql/lib/change-notes/released/0.2.5.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.2.5
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.4
|
||||
lastReleaseVersion: 0.2.5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-all
|
||||
version: 0.2.5-dev
|
||||
version: 0.2.6-dev
|
||||
groups: javascript
|
||||
dbscheme: semmlecode.javascript.dbscheme
|
||||
extractor: javascript
|
||||
|
||||
@@ -652,7 +652,7 @@ module API {
|
||||
exports(m, _, _)
|
||||
or
|
||||
exists(NodeModule nm | nm = mod |
|
||||
exists(SSA::implicitInit([nm.getModuleVariable(), nm.getExportsVariable()]))
|
||||
exists(Ssa::implicitInit([nm.getModuleVariable(), nm.getExportsVariable()]))
|
||||
)
|
||||
)
|
||||
} or
|
||||
|
||||
@@ -103,7 +103,7 @@ module RangeAnalysis {
|
||||
* the given increment/decrement expression.
|
||||
*/
|
||||
private DataFlow::Node updateExprResult(UpdateExpr expr) {
|
||||
result = DataFlow::ssaDefinitionNode(SSA::definition(expr))
|
||||
result = DataFlow::ssaDefinitionNode(Ssa::definition(expr))
|
||||
or
|
||||
expr.isPrefix() and
|
||||
result = expr.flow()
|
||||
@@ -113,7 +113,7 @@ module RangeAnalysis {
|
||||
* Gets a data flow node holding the result of the given componund assignment.
|
||||
*/
|
||||
private DataFlow::Node compoundAssignResult(CompoundAssignExpr expr) {
|
||||
result = DataFlow::ssaDefinitionNode(SSA::definition(expr))
|
||||
result = DataFlow::ssaDefinitionNode(Ssa::definition(expr))
|
||||
or
|
||||
result = expr.flow()
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ module Routing {
|
||||
* Gets an HTTP method name which this node will accept, or nothing if the node accepts all HTTP methods, not
|
||||
* taking into account the context from ancestors or children nodes.
|
||||
*/
|
||||
HTTP::RequestMethodName getOwnHttpMethod() { none() } // Overridden in subclass
|
||||
Http::RequestMethodName getOwnHttpMethod() { none() } // Overridden in subclass
|
||||
|
||||
private Node getAUseSiteInRouteSetup() {
|
||||
if this.getParent() instanceof RouteSetup
|
||||
@@ -383,7 +383,7 @@ module Routing {
|
||||
* Gets an HTTP request method name (in upper case) matched by this node, or nothing
|
||||
* if all HTTP request method names are accepted.
|
||||
*/
|
||||
HTTP::RequestMethodName getHttpMethod() { none() }
|
||||
Http::RequestMethodName getHttpMethod() { none() }
|
||||
}
|
||||
|
||||
private class ValueNodeImpl extends Node, MkValueNode {
|
||||
@@ -407,7 +407,7 @@ module Routing {
|
||||
|
||||
override string getRelativePath() { result = range.getRelativePath() }
|
||||
|
||||
override HTTP::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() }
|
||||
override Http::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() }
|
||||
}
|
||||
|
||||
private StepSummary routeStepSummary() {
|
||||
@@ -434,7 +434,7 @@ module Routing {
|
||||
or
|
||||
StepSummary::smallstep(result, this, routeStepSummary())
|
||||
or
|
||||
HTTP::routeHandlerStep(result, this)
|
||||
Http::routeHandlerStep(result, this)
|
||||
or
|
||||
RouteHandlerTrackingStep::step(result, this)
|
||||
or
|
||||
@@ -599,7 +599,7 @@ module Routing {
|
||||
* Gets an HTTP request method name (in upper case) matched by this node, or nothing
|
||||
* if all HTTP request method names are accepted.
|
||||
*/
|
||||
HTTP::RequestMethodName getHttpMethod() { none() }
|
||||
Http::RequestMethodName getHttpMethod() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this route setup targets `router` and occurs at the given `cfgNode`.
|
||||
@@ -635,7 +635,7 @@ module Routing {
|
||||
|
||||
override string getRelativePath() { result = range.getRelativePath() }
|
||||
|
||||
override HTTP::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() }
|
||||
override Http::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -737,7 +737,7 @@ class SsaRefinementNode extends SsaPseudoDefinition, TRefinement {
|
||||
}
|
||||
}
|
||||
|
||||
module SSA {
|
||||
module Ssa {
|
||||
/** Gets the SSA definition corresponding to the implicit initialization of `v`. */
|
||||
SsaImplicitInit implicitInit(SsaSourceVariable v) { result.getSourceVariable() = v }
|
||||
|
||||
@@ -747,3 +747,6 @@ module SSA {
|
||||
/** Gets the SSA variable corresponding to `d`. */
|
||||
SsaVariable variable(VarDef d) { result.getDefinition() = definition(d) }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for Ssa */
|
||||
deprecated module SSA = Ssa;
|
||||
|
||||
@@ -770,7 +770,7 @@ private class FlowStepThroughImport extends SharedFlowStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(ImportSpecifier specifier |
|
||||
pred = DataFlow::valueNode(specifier) and
|
||||
succ = DataFlow::ssaDefinitionNode(SSA::definition(specifier))
|
||||
succ = DataFlow::ssaDefinitionNode(Ssa::definition(specifier))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1777,7 +1777,7 @@ class MidPathNode extends PathNode, MkMidNode {
|
||||
SsaImplicitDefinition
|
||||
or
|
||||
// Skip SSA definition of parameter as its location coincides with the parameter node
|
||||
nd = DataFlow::ssaDefinitionNode(SSA::definition(any(SimpleParameter p)))
|
||||
nd = DataFlow::ssaDefinitionNode(Ssa::definition(any(SimpleParameter p)))
|
||||
or
|
||||
// Skip to the top of big left-leaning string concatenation trees.
|
||||
nd = any(AddExpr add).flow() and
|
||||
|
||||
@@ -348,7 +348,7 @@ private class NodeModuleSourcesNodes extends SourceNode::Range {
|
||||
|
||||
NodeModuleSourcesNodes() {
|
||||
exists(NodeModule m |
|
||||
this = DataFlow::ssaDefinitionNode(SSA::implicitInit(v)) and
|
||||
this = DataFlow::ssaDefinitionNode(Ssa::implicitInit(v)) and
|
||||
v = [m.getModuleVariable(), m.getExportsVariable()]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -984,7 +984,7 @@ module TaintTracking {
|
||||
*
|
||||
* `<contains>` is one of: `contains`, `has`, `hasOwnProperty`
|
||||
*
|
||||
* Note that the `includes` method is covered by `StringInclusionSanitizer`.
|
||||
* Note that the `includes` method is covered by `MembershipTestSanitizer`.
|
||||
*/
|
||||
class WhitelistContainmentCallSanitizer extends AdditionalSanitizerGuardNode,
|
||||
DataFlow::MethodCallNode {
|
||||
@@ -1171,7 +1171,7 @@ module TaintTracking {
|
||||
/**
|
||||
* A check of form `x.indexOf(y) > 0` or similar, which sanitizes `y` in the "then" branch.
|
||||
*
|
||||
* The more typical case of `x.indexOf(y) >= 0` is covered by `StringInclusionSanitizer`.
|
||||
* The more typical case of `x.indexOf(y) >= 0` is covered by `MembershipTestSanitizer`.
|
||||
*/
|
||||
class PositiveIndexOfSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode {
|
||||
MethodCallExpr indexOf;
|
||||
|
||||
@@ -112,7 +112,7 @@ module ClientRequest {
|
||||
/**
|
||||
* Gets the name of an HTTP request method, in all-lowercase.
|
||||
*/
|
||||
private string httpMethodName() { result = any(HTTP::RequestMethodName m).toLowerCase() }
|
||||
private string httpMethodName() { result = any(Http::RequestMethodName m).toLowerCase() }
|
||||
|
||||
/**
|
||||
* Gets a model of an instance of the `request` library, or one of
|
||||
|
||||
@@ -10,7 +10,7 @@ module Connect {
|
||||
/**
|
||||
* An expression that creates a new Connect server.
|
||||
*/
|
||||
class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::CallNode {
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::CallNode {
|
||||
ServerDefinition() {
|
||||
// `app = connect()`
|
||||
this = DataFlow::moduleImport("connect").getAnInvocation()
|
||||
@@ -61,7 +61,7 @@ module Connect {
|
||||
/**
|
||||
* A call to a Connect method that sets up a route.
|
||||
*/
|
||||
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
|
||||
class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup {
|
||||
ServerDefinition server;
|
||||
|
||||
RouteSetup() {
|
||||
@@ -125,7 +125,7 @@ module Connect {
|
||||
/**
|
||||
* An access to a user-controlled Connect request input.
|
||||
*/
|
||||
private class RequestInputAccess extends HTTP::RequestInputAccess instanceof DataFlow::MethodCallNode {
|
||||
private class RequestInputAccess extends Http::RequestInputAccess instanceof DataFlow::MethodCallNode {
|
||||
RequestNode request;
|
||||
string kind;
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ module ConnectExpressShared {
|
||||
*
|
||||
* For example, this could be the function `function(req, res, next){...}`.
|
||||
*/
|
||||
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate {
|
||||
class RouteHandlerCandidate extends Http::RouteHandlerCandidate {
|
||||
RouteHandlerCandidate() {
|
||||
matchesSignature(this, _) and
|
||||
not (
|
||||
|
||||
@@ -368,7 +368,7 @@ private class HttpCookieWrite extends CookieWrites::CookieWrite {
|
||||
string header;
|
||||
|
||||
HttpCookieWrite() {
|
||||
exists(HTTP::CookieDefinition setCookie |
|
||||
exists(Http::CookieDefinition setCookie |
|
||||
this = setCookie.getHeaderArgument() and
|
||||
not this instanceof DataFlow::ArrayCreationNode
|
||||
or
|
||||
|
||||
@@ -70,7 +70,7 @@ module Express {
|
||||
result = "param" or
|
||||
result = "all" or
|
||||
result = "use" or
|
||||
result = any(HTTP::RequestMethodName m).toLowerCase() or
|
||||
result = any(Http::RequestMethodName m).toLowerCase() or
|
||||
// deprecated methods
|
||||
result = "error" or
|
||||
result = "del"
|
||||
@@ -92,7 +92,7 @@ module Express {
|
||||
result = this.getArgument(0).getStringValue()
|
||||
}
|
||||
|
||||
override HTTP::RequestMethodName getHttpMethod() { result.toLowerCase() = this.getMethodName() }
|
||||
override Http::RequestMethodName getHttpMethod() { result.toLowerCase() = this.getMethodName() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,7 +136,7 @@ module Express {
|
||||
/**
|
||||
* A call to an Express router method that sets up a route.
|
||||
*/
|
||||
class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode {
|
||||
class RouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::MethodCallNode {
|
||||
RouteSetup() {
|
||||
isRouter(this.getReceiver()) and
|
||||
this.getMethodName() = routeSetupMethodName()
|
||||
@@ -219,7 +219,7 @@ module Express {
|
||||
|
|
||||
result = succ.backtrack(t2, t)
|
||||
or
|
||||
HTTP::routeHandlerStep(result, succ) and
|
||||
Http::routeHandlerStep(result, succ) and
|
||||
t = t2
|
||||
)
|
||||
}
|
||||
@@ -233,7 +233,7 @@ module Express {
|
||||
*
|
||||
* Has no result for `use`, `all`, or `param` calls.
|
||||
*/
|
||||
HTTP::RequestMethodName getRequestMethod() { result.toLowerCase() = this.getMethodName() }
|
||||
Http::RequestMethodName getRequestMethod() { result.toLowerCase() = this.getMethodName() }
|
||||
|
||||
/**
|
||||
* Holds if this registers a route for all request methods.
|
||||
@@ -260,7 +260,7 @@ module Express {
|
||||
/**
|
||||
* A call that sets up a Passport router that includes the request object.
|
||||
*/
|
||||
private class PassportRouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode {
|
||||
private class PassportRouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::CallNode {
|
||||
DataFlow::ModuleImportNode importNode;
|
||||
DataFlow::FunctionNode callback;
|
||||
|
||||
@@ -285,7 +285,7 @@ module Express {
|
||||
/**
|
||||
* The callback given to passport in PassportRouteSetup.
|
||||
*/
|
||||
private class PassportRouteHandler extends RouteHandler, HTTP::Servers::StandardRouteHandler,
|
||||
private class PassportRouteHandler extends RouteHandler, Http::Servers::StandardRouteHandler,
|
||||
DataFlow::FunctionNode {
|
||||
PassportRouteHandler() { this = any(PassportRouteSetup setup).getARouteHandler() }
|
||||
|
||||
@@ -470,7 +470,7 @@ module Express {
|
||||
* but support for other kinds of route handlers can be added by implementing
|
||||
* additional subclasses of this class.
|
||||
*/
|
||||
abstract class RouteHandler extends HTTP::RouteHandler {
|
||||
abstract class RouteHandler extends Http::RouteHandler {
|
||||
/**
|
||||
* Gets the parameter of kind `kind` of this route handler.
|
||||
*
|
||||
@@ -501,7 +501,7 @@ module Express {
|
||||
/**
|
||||
* An Express route handler installed by a route setup.
|
||||
*/
|
||||
class StandardRouteHandler extends RouteHandler, HTTP::Servers::StandardRouteHandler,
|
||||
class StandardRouteHandler extends RouteHandler, Http::Servers::StandardRouteHandler,
|
||||
DataFlow::FunctionNode {
|
||||
RouteSetup routeSetup;
|
||||
|
||||
@@ -530,7 +530,7 @@ module Express {
|
||||
}
|
||||
|
||||
/** An Express response source. */
|
||||
abstract class ResponseSource extends HTTP::Servers::ResponseSource { }
|
||||
abstract class ResponseSource extends Http::Servers::ResponseSource { }
|
||||
|
||||
/**
|
||||
* An Express response source, that is, the response parameter of a
|
||||
@@ -561,7 +561,7 @@ module Express {
|
||||
}
|
||||
|
||||
/** An Express request source. */
|
||||
abstract class RequestSource extends HTTP::Servers::RequestSource { }
|
||||
abstract class RequestSource extends Http::Servers::RequestSource { }
|
||||
|
||||
/**
|
||||
* An Express request source, that is, the request parameter of a
|
||||
@@ -632,7 +632,7 @@ module Express {
|
||||
}
|
||||
|
||||
/** The input parameter to an `app.param()` route handler. */
|
||||
private class ParamHandlerInputAccess extends HTTP::RequestInputAccess {
|
||||
private class ParamHandlerInputAccess extends Http::RequestInputAccess {
|
||||
RouteHandler rh;
|
||||
|
||||
ParamHandlerInputAccess() {
|
||||
@@ -641,7 +641,7 @@ module Express {
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = rh }
|
||||
override Http::RouteHandler getRouteHandler() { result = rh }
|
||||
|
||||
override string getKind() { result = "parameter" }
|
||||
}
|
||||
@@ -675,7 +675,7 @@ module Express {
|
||||
/**
|
||||
* An access to a user-controlled Express request input.
|
||||
*/
|
||||
class RequestInputAccess extends HTTP::RequestInputAccess {
|
||||
class RequestInputAccess extends Http::RequestInputAccess {
|
||||
RequestSource request;
|
||||
string kind;
|
||||
|
||||
@@ -733,7 +733,7 @@ module Express {
|
||||
/**
|
||||
* An access to a header on an Express request.
|
||||
*/
|
||||
private class RequestHeaderAccess extends HTTP::RequestHeaderAccess {
|
||||
private class RequestHeaderAccess extends Http::RequestHeaderAccess {
|
||||
RequestSource request;
|
||||
|
||||
RequestHeaderAccess() {
|
||||
@@ -762,7 +762,7 @@ module Express {
|
||||
/**
|
||||
* HTTP headers created by Express calls
|
||||
*/
|
||||
abstract private class ExplicitHeader extends HTTP::ExplicitHeaderDefinition { }
|
||||
abstract private class ExplicitHeader extends Http::ExplicitHeaderDefinition { }
|
||||
|
||||
/**
|
||||
* Holds if `e` is an HTTP request object.
|
||||
@@ -781,7 +781,7 @@ module Express {
|
||||
RequestBodyAccess() { any(RouteHandler h).getARequestBodyAccess() = this }
|
||||
}
|
||||
|
||||
abstract private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition {
|
||||
abstract private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition {
|
||||
HeaderDefinition() { isResponse(this.getReceiver()) }
|
||||
|
||||
override RouteHandler getRouteHandler() { this.getReceiver() = result.getAResponseNode() }
|
||||
@@ -790,7 +790,7 @@ module Express {
|
||||
/**
|
||||
* An invocation of the `redirect` method of an HTTP response object.
|
||||
*/
|
||||
private class RedirectInvocation extends HTTP::RedirectInvocation, DataFlow::MethodCallNode {
|
||||
private class RedirectInvocation extends Http::RedirectInvocation, DataFlow::MethodCallNode {
|
||||
ResponseSource response;
|
||||
|
||||
RedirectInvocation() { this = response.ref().getAMethodCall("redirect") }
|
||||
@@ -854,7 +854,7 @@ module Express {
|
||||
/**
|
||||
* An argument passed to the `send` or `end` method of an HTTP response object.
|
||||
*/
|
||||
private class ResponseSendArgument extends HTTP::ResponseSendArgument {
|
||||
private class ResponseSendArgument extends Http::ResponseSendArgument {
|
||||
ResponseSource response;
|
||||
|
||||
ResponseSendArgument() { this = response.ref().getAMethodCall("send").getArgument(0) }
|
||||
@@ -865,7 +865,7 @@ module Express {
|
||||
/**
|
||||
* An invocation of the `cookie` method on an HTTP response object.
|
||||
*/
|
||||
class SetCookie extends HTTP::CookieDefinition, DataFlow::MethodCallNode {
|
||||
class SetCookie extends Http::CookieDefinition, DataFlow::MethodCallNode {
|
||||
ResponseSource response;
|
||||
|
||||
SetCookie() { this = response.ref().getAMethodCall("cookie") }
|
||||
@@ -881,7 +881,7 @@ module Express {
|
||||
* An expression passed to the `render` method of an HTTP response object
|
||||
* as the value of a template variable.
|
||||
*/
|
||||
private class TemplateInput extends HTTP::ResponseBody {
|
||||
private class TemplateInput extends Http::ResponseBody {
|
||||
TemplateObjectInput obj;
|
||||
|
||||
TemplateInput() {
|
||||
@@ -913,13 +913,13 @@ module Express {
|
||||
/**
|
||||
* An Express server application.
|
||||
*/
|
||||
private class Application extends HTTP::ServerDefinition {
|
||||
private class Application extends Http::ServerDefinition {
|
||||
Application() { this = appCreation() }
|
||||
|
||||
/**
|
||||
* Gets a route handler of the application, regardless of nesting.
|
||||
*/
|
||||
override HTTP::RouteHandler getARouteHandler() {
|
||||
override Http::RouteHandler getARouteHandler() {
|
||||
result = this.(RouterDefinition).getASubRouter*().getARouteHandler()
|
||||
}
|
||||
}
|
||||
@@ -960,7 +960,7 @@ module Express {
|
||||
*
|
||||
* Example: `fun` for `router1.use(fun)` or `router.use("/route", fun)`
|
||||
*/
|
||||
HTTP::RouteHandler getARouteHandler() {
|
||||
Http::RouteHandler getARouteHandler() {
|
||||
result.(DataFlow::SourceNode).flowsTo(this.getARouteSetup().getAnArgument())
|
||||
}
|
||||
|
||||
@@ -1044,7 +1044,7 @@ module Express {
|
||||
* A function that flows to a route setup.
|
||||
*/
|
||||
private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
RouteSetup routeSetup;
|
||||
|
||||
TrackedRouteHandlerCandidateWithSetup() { this = routeSetup.getARouteHandler() }
|
||||
@@ -1063,14 +1063,14 @@ module Express {
|
||||
* `router.post(handler)` where it is unknown if `router` is an
|
||||
* Express router.
|
||||
*/
|
||||
class RouteSetupCandidate extends HTTP::RouteSetupCandidate, DataFlow::MethodCallNode {
|
||||
class RouteSetupCandidate extends Http::RouteSetupCandidate, DataFlow::MethodCallNode {
|
||||
DataFlow::ValueNode routeHandlerArg;
|
||||
|
||||
RouteSetupCandidate() {
|
||||
exists(string methodName |
|
||||
methodName = "all" or
|
||||
methodName = "use" or
|
||||
methodName = any(HTTP::RequestMethodName m).toLowerCase()
|
||||
methodName = any(Http::RequestMethodName m).toLowerCase()
|
||||
|
|
||||
this.getMethodName() = methodName and
|
||||
exists(DataFlow::ValueNode arg | arg = this.getAnArgument() |
|
||||
|
||||
@@ -18,25 +18,25 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A header produced by a route handler of the "x-frame-options" module.
|
||||
*/
|
||||
class XFrameOptionsRouteHandlerHeader extends HTTP::ImplicitHeaderDefinition {
|
||||
class XFrameOptionsRouteHandlerHeader extends Http::ImplicitHeaderDefinition {
|
||||
XFrameOptionsRouteHandlerHeader() { this instanceof XFrameOptionsRouteHandler }
|
||||
|
||||
override predicate defines(string headerName, string headerValue) {
|
||||
xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = this }
|
||||
override Http::RouteHandler getRouteHandler() { result = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A route handler from the "x-frame-options" module.
|
||||
*/
|
||||
class XFrameOptionsRouteHandler extends HTTP::RouteHandler {
|
||||
class XFrameOptionsRouteHandler extends Http::RouteHandler {
|
||||
XFrameOptionsRouteHandler() {
|
||||
this = DataFlow::moduleImport("x-frame-options").getAnInvocation()
|
||||
}
|
||||
|
||||
override HTTP::HeaderDefinition getAResponseHeader(string name) {
|
||||
override Http::HeaderDefinition getAResponseHeader(string name) {
|
||||
name = this.(XFrameOptionsRouteHandlerHeader).getAHeaderName() and
|
||||
result = this
|
||||
}
|
||||
@@ -45,23 +45,23 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A header produced by a route handler of the "frameguard" module.
|
||||
*/
|
||||
class FrameGuardRouteHandlerHeader extends HTTP::ImplicitHeaderDefinition {
|
||||
class FrameGuardRouteHandlerHeader extends Http::ImplicitHeaderDefinition {
|
||||
FrameGuardRouteHandlerHeader() { this instanceof FrameGuardRouteHandler }
|
||||
|
||||
override predicate defines(string headerName, string headerValue) {
|
||||
xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = this }
|
||||
override Http::RouteHandler getRouteHandler() { result = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A route handler from the "frameguard" module.
|
||||
*/
|
||||
class FrameGuardRouteHandler extends HTTP::RouteHandler {
|
||||
class FrameGuardRouteHandler extends Http::RouteHandler {
|
||||
FrameGuardRouteHandler() { this = DataFlow::moduleImport("frameguard").getAnInvocation() }
|
||||
|
||||
override HTTP::HeaderDefinition getAResponseHeader(string name) {
|
||||
override Http::HeaderDefinition getAResponseHeader(string name) {
|
||||
name = this.(FrameGuardRouteHandlerHeader).getAHeaderName() and
|
||||
result = this
|
||||
}
|
||||
@@ -70,20 +70,20 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A header produced by a route handler of the "helmet" module.
|
||||
*/
|
||||
class HelmetRouteHandlerHeader extends HTTP::ImplicitHeaderDefinition {
|
||||
class HelmetRouteHandlerHeader extends Http::ImplicitHeaderDefinition {
|
||||
HelmetRouteHandlerHeader() { this instanceof HelmetRouteHandler }
|
||||
|
||||
override predicate defines(string headerName, string headerValue) {
|
||||
xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = this }
|
||||
override Http::RouteHandler getRouteHandler() { result = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A route handler from the "helmet" module.
|
||||
*/
|
||||
class HelmetRouteHandler extends HTTP::RouteHandler {
|
||||
class HelmetRouteHandler extends Http::RouteHandler {
|
||||
HelmetRouteHandler() {
|
||||
exists(DataFlow::ModuleImportNode m | "helmet" = m.getPath() |
|
||||
this = m.getAnInvocation() or
|
||||
@@ -91,7 +91,7 @@ module ExpressLibraries {
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::HeaderDefinition getAResponseHeader(string name) {
|
||||
override Http::HeaderDefinition getAResponseHeader(string name) {
|
||||
name = this.(HelmetRouteHandlerHeader).getAHeaderName() and
|
||||
result = this
|
||||
}
|
||||
@@ -108,7 +108,7 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A call that creates an `express-session` middleware instance.
|
||||
*/
|
||||
class MiddlewareInstance extends DataFlow::InvokeNode, HTTP::CookieMiddlewareInstance {
|
||||
class MiddlewareInstance extends DataFlow::InvokeNode, Http::CookieMiddlewareInstance {
|
||||
MiddlewareInstance() { this = expressSession().getACall() }
|
||||
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A call that creates a `cookie-parser` middleware instance.
|
||||
*/
|
||||
class MiddlewareInstance extends DataFlow::InvokeNode, HTTP::CookieMiddlewareInstance {
|
||||
class MiddlewareInstance extends DataFlow::InvokeNode, Http::CookieMiddlewareInstance {
|
||||
MiddlewareInstance() { this = cookieParser().getACall() }
|
||||
|
||||
/**
|
||||
@@ -164,7 +164,7 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A call that creates a `cookie-session` middleware instance.
|
||||
*/
|
||||
class MiddlewareInstance extends DataFlow::InvokeNode, HTTP::CookieMiddlewareInstance {
|
||||
class MiddlewareInstance extends DataFlow::InvokeNode, Http::CookieMiddlewareInstance {
|
||||
MiddlewareInstance() { this = cookieSession().getACall() }
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@ module Fastify {
|
||||
/**
|
||||
* An expression that creates a new Fastify server.
|
||||
*/
|
||||
abstract class ServerDefinition extends HTTP::Servers::StandardServerDefinition { }
|
||||
abstract class ServerDefinition extends Http::Servers::StandardServerDefinition { }
|
||||
|
||||
/**
|
||||
* A standard way to create a Fastify server.
|
||||
@@ -76,7 +76,7 @@ module Fastify {
|
||||
* but support for other kinds of route handlers can be added by implementing
|
||||
* additional subclasses of this class.
|
||||
*/
|
||||
abstract class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::ValueNode {
|
||||
abstract class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::ValueNode {
|
||||
/**
|
||||
* Gets the parameter of the route handler that contains the request object.
|
||||
*/
|
||||
@@ -103,7 +103,7 @@ module Fastify {
|
||||
* A Fastify reply source, that is, the `reply` parameter of a
|
||||
* route handler.
|
||||
*/
|
||||
private class ReplySource extends HTTP::Servers::ResponseSource {
|
||||
private class ReplySource extends Http::Servers::ResponseSource {
|
||||
RouteHandler rh;
|
||||
|
||||
ReplySource() { this = rh.getReplyParameter() }
|
||||
@@ -118,7 +118,7 @@ module Fastify {
|
||||
* A Fastify request source, that is, the request parameter of a
|
||||
* route handler.
|
||||
*/
|
||||
private class RequestSource extends HTTP::Servers::RequestSource {
|
||||
private class RequestSource extends Http::Servers::RequestSource {
|
||||
RouteHandler rh;
|
||||
|
||||
RequestSource() { this = rh.getRequestParameter() }
|
||||
@@ -132,7 +132,7 @@ module Fastify {
|
||||
/**
|
||||
* A call to a Fastify method that sets up a route.
|
||||
*/
|
||||
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
|
||||
class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup {
|
||||
ServerDefinition server;
|
||||
string methodName;
|
||||
|
||||
@@ -176,7 +176,7 @@ module Fastify {
|
||||
|
||||
override string getRelativePath() { result = this.getArgument(0).getStringValue() }
|
||||
|
||||
override HTTP::RequestMethodName getHttpMethod() { result = this.getMethodName().toUpperCase() }
|
||||
override Http::RequestMethodName getHttpMethod() { result = this.getMethodName().toUpperCase() }
|
||||
}
|
||||
|
||||
/** Gets the name of the `n`th handler function that can be installed a route setup, in order of execution. */
|
||||
@@ -194,7 +194,7 @@ module Fastify {
|
||||
|
||||
override string getRelativePath() { result = this.getOptionArgument(0, "url").getStringValue() }
|
||||
|
||||
override HTTP::RequestMethodName getHttpMethod() {
|
||||
override Http::RequestMethodName getHttpMethod() {
|
||||
result = this.getOptionArgument(0, "method").getStringValue().toUpperCase()
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ module Fastify {
|
||||
result = this.pluginBody(DataFlow::TypeBackTracker::end())
|
||||
}
|
||||
|
||||
override HTTP::RequestMethodName getHttpMethod() {
|
||||
override Http::RequestMethodName getHttpMethod() {
|
||||
result = this.getOptionArgument(1, "method").getStringValue().toUpperCase()
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ module Fastify {
|
||||
/**
|
||||
* An access to a user-controlled Fastify request input.
|
||||
*/
|
||||
private class RequestInputAccess extends HTTP::RequestInputAccess {
|
||||
private class RequestInputAccess extends Http::RequestInputAccess {
|
||||
RouteHandler rh;
|
||||
string kind;
|
||||
|
||||
@@ -308,7 +308,7 @@ module Fastify {
|
||||
/**
|
||||
* An access to a header on a Fastify request.
|
||||
*/
|
||||
private class RequestHeaderAccess extends HTTP::RequestHeaderAccess {
|
||||
private class RequestHeaderAccess extends Http::RequestHeaderAccess {
|
||||
RouteHandler rh;
|
||||
|
||||
RequestHeaderAccess() {
|
||||
@@ -327,7 +327,7 @@ module Fastify {
|
||||
/**
|
||||
* An argument passed to the `send` or `end` method of an HTTP response object.
|
||||
*/
|
||||
private class ResponseSendArgument extends HTTP::ResponseSendArgument {
|
||||
private class ResponseSendArgument extends Http::ResponseSendArgument {
|
||||
RouteHandler rh;
|
||||
|
||||
ResponseSendArgument() {
|
||||
@@ -342,7 +342,7 @@ module Fastify {
|
||||
/**
|
||||
* An invocation of the `redirect` method of an HTTP response object.
|
||||
*/
|
||||
private class RedirectInvocation extends HTTP::RedirectInvocation, DataFlow::MethodCallNode {
|
||||
private class RedirectInvocation extends Http::RedirectInvocation, DataFlow::MethodCallNode {
|
||||
RouteHandler rh;
|
||||
|
||||
RedirectInvocation() { this = rh.getAResponseSource().ref().getAMethodCall("redirect") }
|
||||
@@ -355,7 +355,7 @@ module Fastify {
|
||||
/**
|
||||
* An invocation that sets a single header of the HTTP response.
|
||||
*/
|
||||
private class SetOneHeader extends HTTP::Servers::StandardHeaderDefinition,
|
||||
private class SetOneHeader extends Http::Servers::StandardHeaderDefinition,
|
||||
DataFlow::MethodCallNode {
|
||||
RouteHandler rh;
|
||||
|
||||
@@ -370,7 +370,7 @@ module Fastify {
|
||||
/**
|
||||
* An invocation that sets any number of headers of the HTTP response.
|
||||
*/
|
||||
class SetMultipleHeaders extends HTTP::ExplicitHeaderDefinition, DataFlow::MethodCallNode {
|
||||
class SetMultipleHeaders extends Http::ExplicitHeaderDefinition, DataFlow::MethodCallNode {
|
||||
RouteHandler rh;
|
||||
|
||||
SetMultipleHeaders() {
|
||||
@@ -414,7 +414,7 @@ module Fastify {
|
||||
override DataFlow::Node getTemplateParamsNode() { result = this.getArgument(1) }
|
||||
}
|
||||
|
||||
private class FastifyCookieMiddleware extends HTTP::CookieMiddlewareInstance {
|
||||
private class FastifyCookieMiddleware extends Http::CookieMiddlewareInstance {
|
||||
FastifyCookieMiddleware() {
|
||||
this = DataFlow::moduleImport(["fastify-cookie", "fastify-session", "fastify-secure-session"])
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ module Firebase {
|
||||
/**
|
||||
* A call to a Firebase method that sets up a route.
|
||||
*/
|
||||
private class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode {
|
||||
private class RouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::CallNode {
|
||||
RouteSetup() { this = namespace().getAPropertyRead("https").getAMemberCall("onRequest") }
|
||||
|
||||
override DataFlow::SourceNode getARouteHandler() {
|
||||
@@ -215,7 +215,7 @@ module Firebase {
|
||||
/**
|
||||
* A function used as a route handler.
|
||||
*/
|
||||
private class RouteHandler extends Express::RouteHandler, HTTP::Servers::StandardRouteHandler,
|
||||
private class RouteHandler extends Express::RouteHandler, Http::Servers::StandardRouteHandler,
|
||||
DataFlow::FunctionNode {
|
||||
RouteHandler() { this = any(RouteSetup setup).getARouteHandler() }
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ private import semmle.javascript.dataflow.internal.StepSummary
|
||||
private import semmle.javascript.dataflow.internal.CallGraphs
|
||||
private import DataFlow::PseudoProperties as PseudoProperties
|
||||
|
||||
module HTTP {
|
||||
module Http {
|
||||
/**
|
||||
* A function invocation that causes a redirect response to be sent.
|
||||
*/
|
||||
@@ -242,7 +242,7 @@ module HTTP {
|
||||
DataFlow::functionOneWayForwardingStep(pred.getALocalUse(), succ)
|
||||
or
|
||||
// a container containing route-handlers.
|
||||
exists(HTTP::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ))
|
||||
exists(Http::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ))
|
||||
or
|
||||
// (function (req, res) {}).bind(this);
|
||||
exists(DataFlow::PartialInvokeNode call |
|
||||
@@ -677,7 +677,7 @@ module HTTP {
|
||||
/**
|
||||
* A collection that contains one or more route potential handlers.
|
||||
*/
|
||||
private class ContainerCollection extends HTTP::RouteHandlerCandidateContainer::Range,
|
||||
private class ContainerCollection extends Http::RouteHandlerCandidateContainer::Range,
|
||||
DataFlow::NewNode {
|
||||
ContainerCollection() {
|
||||
this = DataFlow::globalVarRef("Map").getAnInstantiation() and // restrict to Map for now
|
||||
@@ -699,3 +699,6 @@ module HTTP {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for Http */
|
||||
deprecated module HTTP = Http;
|
||||
|
||||
@@ -9,7 +9,7 @@ module Hapi {
|
||||
/**
|
||||
* An expression that creates a new Hapi server.
|
||||
*/
|
||||
class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::NewNode {
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::NewNode {
|
||||
ServerDefinition() {
|
||||
// `server = new Hapi.Server()`
|
||||
this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation()
|
||||
@@ -19,7 +19,7 @@ module Hapi {
|
||||
/**
|
||||
* A Hapi route handler.
|
||||
*/
|
||||
class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
RouteHandler() { exists(RouteSetup setup | this = setup.getARouteHandler()) }
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ module Hapi {
|
||||
* A Hapi response source, that is, an access to the `response` property
|
||||
* of a request object.
|
||||
*/
|
||||
private class ResponseSource extends HTTP::Servers::ResponseSource {
|
||||
private class ResponseSource extends Http::Servers::ResponseSource {
|
||||
RequestNode req;
|
||||
|
||||
ResponseSource() { this.(DataFlow::PropRead).accesses(req, "response") }
|
||||
@@ -58,7 +58,7 @@ module Hapi {
|
||||
* A Hapi request source, that is, the request parameter of a
|
||||
* route handler.
|
||||
*/
|
||||
private class RequestSource extends HTTP::Servers::RequestSource {
|
||||
private class RequestSource extends Http::Servers::RequestSource {
|
||||
RouteHandler rh;
|
||||
|
||||
RequestSource() { this = rh.getRequestParameter() }
|
||||
@@ -80,7 +80,7 @@ module Hapi {
|
||||
/**
|
||||
* A Hapi response node.
|
||||
*/
|
||||
class ResponseNode extends HTTP::Servers::StandardResponseNode {
|
||||
class ResponseNode extends Http::Servers::StandardResponseNode {
|
||||
override ResponseSource src;
|
||||
}
|
||||
|
||||
@@ -95,14 +95,14 @@ module Hapi {
|
||||
/**
|
||||
* A Hapi request node.
|
||||
*/
|
||||
class RequestNode extends HTTP::Servers::StandardRequestNode {
|
||||
class RequestNode extends Http::Servers::StandardRequestNode {
|
||||
override RequestSource src;
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to a user-controlled Hapi request input.
|
||||
*/
|
||||
private class RequestInputAccess extends HTTP::RequestInputAccess {
|
||||
private class RequestInputAccess extends Http::RequestInputAccess {
|
||||
RouteHandler rh;
|
||||
string kind;
|
||||
|
||||
@@ -156,7 +156,7 @@ module Hapi {
|
||||
/**
|
||||
* An access to an HTTP header on a Hapi request.
|
||||
*/
|
||||
private class RequestHeaderAccess extends HTTP::RequestHeaderAccess {
|
||||
private class RequestHeaderAccess extends Http::RequestHeaderAccess {
|
||||
RouteHandler rh;
|
||||
|
||||
RequestHeaderAccess() {
|
||||
@@ -181,7 +181,7 @@ module Hapi {
|
||||
/**
|
||||
* An HTTP header defined in a Hapi server.
|
||||
*/
|
||||
private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition {
|
||||
private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition {
|
||||
ResponseNode res;
|
||||
|
||||
HeaderDefinition() {
|
||||
@@ -195,7 +195,7 @@ module Hapi {
|
||||
/**
|
||||
* A call to a Hapi method that sets up a route.
|
||||
*/
|
||||
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
|
||||
class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup {
|
||||
ServerDefinition server;
|
||||
DataFlow::Node handler;
|
||||
|
||||
@@ -236,7 +236,7 @@ module Hapi {
|
||||
*
|
||||
* For example, this could be the function `function(request, h){...}`.
|
||||
*/
|
||||
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate {
|
||||
class RouteHandlerCandidate extends Http::RouteHandlerCandidate {
|
||||
RouteHandlerCandidate() {
|
||||
exists(string request, string responseToolkit |
|
||||
(request = "request" or request = "req") and
|
||||
@@ -256,7 +256,7 @@ module Hapi {
|
||||
* A function that looks like a Hapi route handler and flows to a route setup.
|
||||
*/
|
||||
private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() }
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ module Hapi {
|
||||
/**
|
||||
* A return from a route handler.
|
||||
*/
|
||||
private class HandlerReturn extends HTTP::ResponseSendArgument {
|
||||
private class HandlerReturn extends Http::ResponseSendArgument {
|
||||
RouteHandler handler;
|
||||
|
||||
HandlerReturn() { this = handler.(DataFlow::FunctionNode).getAReturn() }
|
||||
|
||||
@@ -9,7 +9,7 @@ module Koa {
|
||||
/**
|
||||
* An expression that creates a new Koa application.
|
||||
*/
|
||||
class AppDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::InvokeNode {
|
||||
class AppDefinition extends Http::Servers::StandardServerDefinition, DataFlow::InvokeNode {
|
||||
AppDefinition() {
|
||||
// `app = new Koa()` / `app = Koa()`
|
||||
this = DataFlow::moduleImport("koa").getAnInvocation()
|
||||
@@ -19,7 +19,7 @@ module Koa {
|
||||
/**
|
||||
* An HTTP header defined in a Koa application.
|
||||
*/
|
||||
private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition {
|
||||
private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition {
|
||||
RouteHandler rh;
|
||||
|
||||
HeaderDefinition() {
|
||||
@@ -36,7 +36,7 @@ module Koa {
|
||||
/**
|
||||
* A Koa route handler.
|
||||
*/
|
||||
abstract class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::SourceNode {
|
||||
abstract class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::SourceNode {
|
||||
/**
|
||||
* Gets the parameter of the route handler that contains the context object.
|
||||
*/
|
||||
@@ -227,7 +227,7 @@ module Koa {
|
||||
* A Koa request source, that is, an access to the `request` property
|
||||
* of a context object.
|
||||
*/
|
||||
private class RequestSource extends HTTP::Servers::RequestSource instanceof DataFlow::PropRead {
|
||||
private class RequestSource extends Http::Servers::RequestSource instanceof DataFlow::PropRead {
|
||||
ContextNode ctx;
|
||||
|
||||
RequestSource() { super.accesses(ctx, "request") }
|
||||
@@ -242,7 +242,7 @@ module Koa {
|
||||
* A Koa request source, accessed through the a request property of a
|
||||
* generator route handler (deprecated in Koa 3).
|
||||
*/
|
||||
private class GeneratorRequestSource extends HTTP::Servers::RequestSource {
|
||||
private class GeneratorRequestSource extends Http::Servers::RequestSource {
|
||||
RouteHandler rh;
|
||||
|
||||
GeneratorRequestSource() {
|
||||
@@ -262,7 +262,7 @@ module Koa {
|
||||
* A Koa response source, that is, an access to the `response` property
|
||||
* of a context object.
|
||||
*/
|
||||
private class ResponseSource extends HTTP::Servers::ResponseSource instanceof DataFlow::PropRead {
|
||||
private class ResponseSource extends Http::Servers::ResponseSource instanceof DataFlow::PropRead {
|
||||
ContextNode ctx;
|
||||
|
||||
ResponseSource() { super.accesses(ctx, "response") }
|
||||
@@ -311,7 +311,7 @@ module Koa {
|
||||
/**
|
||||
* An expression that may hold a Koa request object.
|
||||
*/
|
||||
class RequestNode extends HTTP::Servers::StandardRequestNode {
|
||||
class RequestNode extends Http::Servers::StandardRequestNode {
|
||||
override RequestSource src;
|
||||
}
|
||||
|
||||
@@ -326,14 +326,14 @@ module Koa {
|
||||
/**
|
||||
* An expression that may hold a Koa response object.
|
||||
*/
|
||||
class ResponseNode extends HTTP::Servers::StandardResponseNode {
|
||||
class ResponseNode extends Http::Servers::StandardResponseNode {
|
||||
override ResponseSource src;
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to a user-controlled Koa request input.
|
||||
*/
|
||||
private class RequestInputAccess extends HTTP::RequestInputAccess {
|
||||
private class RequestInputAccess extends Http::RequestInputAccess {
|
||||
RouteHandler rh;
|
||||
string kind;
|
||||
|
||||
@@ -399,7 +399,7 @@ module Koa {
|
||||
/**
|
||||
* An access to an HTTP header on a Koa request.
|
||||
*/
|
||||
private class RequestHeaderAccess extends HTTP::RequestHeaderAccess {
|
||||
private class RequestHeaderAccess extends Http::RequestHeaderAccess {
|
||||
RouteHandler rh;
|
||||
|
||||
RequestHeaderAccess() {
|
||||
@@ -435,7 +435,7 @@ module Koa {
|
||||
/**
|
||||
* A call to a Koa method that sets up a route.
|
||||
*/
|
||||
class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode {
|
||||
class RouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::MethodCallNode {
|
||||
AppDefinition server;
|
||||
|
||||
RouteSetup() {
|
||||
@@ -457,7 +457,7 @@ module Koa {
|
||||
/**
|
||||
* A value assigned to the body of an HTTP response object.
|
||||
*/
|
||||
private class ResponseSendArgument extends HTTP::ResponseSendArgument {
|
||||
private class ResponseSendArgument extends Http::ResponseSendArgument {
|
||||
RouteHandler rh;
|
||||
|
||||
ResponseSendArgument() {
|
||||
@@ -470,7 +470,7 @@ module Koa {
|
||||
/**
|
||||
* An invocation of the `redirect` method of an HTTP response object.
|
||||
*/
|
||||
private class RedirectInvocation extends HTTP::RedirectInvocation instanceof DataFlow::MethodCallNode {
|
||||
private class RedirectInvocation extends Http::RedirectInvocation instanceof DataFlow::MethodCallNode {
|
||||
RouteHandler rh;
|
||||
|
||||
RedirectInvocation() { super.calls(rh.getAResponseOrContextNode(), "redirect") }
|
||||
|
||||
@@ -9,7 +9,7 @@ private module LiveServer {
|
||||
/**
|
||||
* An expression that imports the live-server package, seen as a server-definition.
|
||||
*/
|
||||
class ServerDefinition extends HTTP::Servers::StandardServerDefinition {
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition {
|
||||
ServerDefinition() { this = DataFlow::moduleImport("live-server") }
|
||||
|
||||
API::Node getImportNode() { result.asSource() = this }
|
||||
@@ -30,7 +30,7 @@ private module LiveServer {
|
||||
/**
|
||||
* The call to `require("live-server").start()`, seen as a route setup.
|
||||
*/
|
||||
class RouteSetup extends HTTP::Servers::StandardRouteSetup instanceof API::CallNode {
|
||||
class RouteSetup extends Http::Servers::StandardRouteSetup instanceof API::CallNode {
|
||||
ServerDefinition server;
|
||||
|
||||
RouteSetup() { this = server.getImportNode().getMember("start").getACall() }
|
||||
|
||||
@@ -349,7 +349,7 @@ private module Pino {
|
||||
or
|
||||
// `pino` is installed as the "log" property on the request object in `Express` and similar libraries.
|
||||
// in `Hapi` the property is "logger".
|
||||
exists(HTTP::RequestNode req, API::Node reqNode |
|
||||
exists(Http::RequestNode req, API::Node reqNode |
|
||||
reqNode.asSource() = req.getALocalSource() and
|
||||
result = reqNode.getMember(["log", "logger"])
|
||||
)
|
||||
|
||||
@@ -42,24 +42,24 @@ private module Micro {
|
||||
/**
|
||||
* A function passed to `micro` or `micro.run`.
|
||||
*/
|
||||
class MicroRouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
class MicroRouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
MicroRouteHandler() { this = microRouteHandler().getAFunctionValue() }
|
||||
}
|
||||
|
||||
class MicroRequestSource extends HTTP::Servers::RequestSource {
|
||||
class MicroRequestSource extends Http::Servers::RequestSource {
|
||||
MicroRouteHandler h;
|
||||
|
||||
MicroRequestSource() { this = h.getParameter(0) }
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = h }
|
||||
override Http::RouteHandler getRouteHandler() { result = h }
|
||||
}
|
||||
|
||||
class MicroResponseSource extends HTTP::Servers::ResponseSource {
|
||||
class MicroResponseSource extends Http::Servers::ResponseSource {
|
||||
MicroRouteHandler h;
|
||||
|
||||
MicroResponseSource() { this = h.getParameter(1) }
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = h }
|
||||
override Http::RouteHandler getRouteHandler() { result = h }
|
||||
}
|
||||
|
||||
deprecated class MicroRequestExpr extends NodeJSLib::RequestExpr {
|
||||
@@ -78,19 +78,19 @@ private module Micro {
|
||||
override MicroResponseSource src;
|
||||
}
|
||||
|
||||
private HTTP::RouteHandler getRouteHandlerFromReqRes(DataFlow::Node node) {
|
||||
exists(HTTP::Servers::RequestSource src |
|
||||
private Http::RouteHandler getRouteHandlerFromReqRes(DataFlow::Node node) {
|
||||
exists(Http::Servers::RequestSource src |
|
||||
src.ref().flowsTo(node) and
|
||||
result = src.getRouteHandler()
|
||||
)
|
||||
or
|
||||
exists(HTTP::Servers::ResponseSource src |
|
||||
exists(Http::Servers::ResponseSource src |
|
||||
src.ref().flowsTo(node) and
|
||||
result = src.getRouteHandler()
|
||||
)
|
||||
}
|
||||
|
||||
class MicroBodyParserCall extends HTTP::RequestInputAccess, DataFlow::CallNode {
|
||||
class MicroBodyParserCall extends Http::RequestInputAccess, DataFlow::CallNode {
|
||||
string name;
|
||||
|
||||
MicroBodyParserCall() {
|
||||
@@ -100,14 +100,14 @@ private module Micro {
|
||||
|
||||
override string getKind() { result = "body" }
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() {
|
||||
override Http::RouteHandler getRouteHandler() {
|
||||
result = getRouteHandlerFromReqRes(getArgument(0))
|
||||
}
|
||||
|
||||
override predicate isUserControlledObject() { name = "json" }
|
||||
}
|
||||
|
||||
class MicroSendArgument extends HTTP::ResponseSendArgument {
|
||||
class MicroSendArgument extends Http::ResponseSendArgument {
|
||||
CallNode send;
|
||||
|
||||
MicroSendArgument() {
|
||||
@@ -115,7 +115,7 @@ private module Micro {
|
||||
this = send.getLastArgument()
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() {
|
||||
override Http::RouteHandler getRouteHandler() {
|
||||
result = getRouteHandlerFromReqRes(send.getArgument([0, 1]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ module NestJS {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
private class NestJSRouteHandler extends HTTP::RouteHandler, DataFlow::FunctionNode {
|
||||
private class NestJSRouteHandler extends Http::RouteHandler, DataFlow::FunctionNode {
|
||||
NestJSRouteHandler() {
|
||||
getAFunctionDecorator(this) =
|
||||
nestjs()
|
||||
@@ -42,7 +42,7 @@ module NestJS {
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override HTTP::HeaderDefinition getAResponseHeader(string name) { none() }
|
||||
override Http::HeaderDefinition getAResponseHeader(string name) { none() }
|
||||
|
||||
/**
|
||||
* Holds if this has the `@Redirect()` decorator.
|
||||
@@ -257,7 +257,7 @@ module NestJS {
|
||||
* The type of remote flow depends on which decorator is applied at the parameter, so
|
||||
* we just classify it as a `RemoteFlowSource`.
|
||||
*/
|
||||
private class NestJSCustomPipeInput extends HTTP::RequestInputAccess {
|
||||
private class NestJSCustomPipeInput extends Http::RequestInputAccess {
|
||||
CustomPipeClass pipe;
|
||||
|
||||
NestJSCustomPipeInput() {
|
||||
@@ -273,7 +273,7 @@ module NestJS {
|
||||
result = pipe.getAnAffectedParameter().getInputKind()
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() {
|
||||
override Http::RouteHandler getRouteHandler() {
|
||||
result = pipe.getAnAffectedParameter().getNestRouteHandler()
|
||||
}
|
||||
}
|
||||
@@ -295,13 +295,13 @@ module NestJS {
|
||||
* as a source of untrusted data.
|
||||
*/
|
||||
private class NestJSRequestInputAsRequestInputAccess extends NestJSRequestInput,
|
||||
HTTP::RequestInputAccess {
|
||||
Http::RequestInputAccess {
|
||||
NestJSRequestInputAsRequestInputAccess() {
|
||||
not this.isSanitizedByPipe() and
|
||||
not this = any(CustomPipeClass cls).getAnAffectedParameter()
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = this.getNestRouteHandler() }
|
||||
override Http::RouteHandler getRouteHandler() { result = this.getNestRouteHandler() }
|
||||
|
||||
override string getKind() { result = this.getInputKind() }
|
||||
|
||||
@@ -316,7 +316,7 @@ module NestJS {
|
||||
}
|
||||
|
||||
private class NestJSHeaderAccess extends NestJSRequestInputAsRequestInputAccess,
|
||||
HTTP::RequestHeaderAccess {
|
||||
Http::RequestHeaderAccess {
|
||||
NestJSHeaderAccess() { decoratorName = "Headers" and decorator.getNumArgument() > 0 }
|
||||
|
||||
override string getAHeaderName() {
|
||||
@@ -344,7 +344,7 @@ module NestJS {
|
||||
* ```
|
||||
* writes `<b>Hello</b>` to the response.
|
||||
*/
|
||||
private class ReturnValueAsResponseSend extends HTTP::ResponseSendArgument {
|
||||
private class ReturnValueAsResponseSend extends Http::ResponseSendArgument {
|
||||
NestJSRouteHandler handler;
|
||||
|
||||
ReturnValueAsResponseSend() {
|
||||
@@ -357,7 +357,7 @@ module NestJS {
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = handler }
|
||||
override Http::RouteHandler getRouteHandler() { result = handler }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -439,7 +439,7 @@ module NestJS {
|
||||
/**
|
||||
* Gets the route handler that handles this request.
|
||||
*/
|
||||
override HTTP::RouteHandler getRouteHandler() {
|
||||
override Http::RouteHandler getRouteHandler() {
|
||||
result.(DataFlow::FunctionNode).getAParameter() = this
|
||||
}
|
||||
}
|
||||
@@ -456,7 +456,7 @@ module NestJS {
|
||||
/**
|
||||
* Gets the route handler that handles this request.
|
||||
*/
|
||||
override HTTP::RouteHandler getRouteHandler() {
|
||||
override Http::RouteHandler getRouteHandler() {
|
||||
result.(DataFlow::FunctionNode).getAParameter() = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,14 +153,14 @@ module NextJS {
|
||||
/**
|
||||
* A Next.js function that is exected on the server for every request, seen as a routehandler.
|
||||
*/
|
||||
class NextHttpRouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
class NextHttpRouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
NextHttpRouteHandler() { this = getServerSidePropsFunction(_) or this = getInitialProps(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that handles both a request and response from Next.js, seen as a routehandler.
|
||||
*/
|
||||
class NextReqResHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
class NextReqResHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
DataFlow::ParameterNode req;
|
||||
DataFlow::ParameterNode res;
|
||||
|
||||
@@ -182,28 +182,28 @@ module NextJS {
|
||||
* A NodeJS HTTP request object in a Next.js page.
|
||||
*/
|
||||
class NextHttpRequestSource extends NodeJSLib::RequestSource {
|
||||
HTTP::RouteHandler rh;
|
||||
Http::RouteHandler rh;
|
||||
|
||||
NextHttpRequestSource() {
|
||||
this = rh.(NextHttpRouteHandler).getParameter(0).getAPropertyRead("req") or
|
||||
this = rh.(NextReqResHandler).getRequest()
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = rh }
|
||||
override Http::RouteHandler getRouteHandler() { result = rh }
|
||||
}
|
||||
|
||||
/**
|
||||
* A NodeJS HTTP response object in a Next.js page.
|
||||
*/
|
||||
class NextHttpResponseSource extends NodeJSLib::ResponseSource {
|
||||
HTTP::RouteHandler rh;
|
||||
Http::RouteHandler rh;
|
||||
|
||||
NextHttpResponseSource() {
|
||||
this = rh.(NextHttpRouteHandler).getParameter(0).getAPropertyRead("res") or
|
||||
this = rh.(NextReqResHandler).getResponse()
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = rh }
|
||||
override Http::RouteHandler getRouteHandler() { result = rh }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +222,7 @@ module NextJS {
|
||||
* and we therefore model the routehandler as an Express.js routehandler.
|
||||
*/
|
||||
class NextApiRouteHandler extends DataFlow::FunctionNode, Express::RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler {
|
||||
Http::Servers::StandardRouteHandler {
|
||||
NextApiRouteHandler() {
|
||||
exists(Module mod | mod.getFile().getParentContainer() = apiFolder() |
|
||||
this = mod.getAnExportedValue("default").getAFunctionValue()
|
||||
|
||||
@@ -81,7 +81,7 @@ module NodeJSLib {
|
||||
* A server library that provides an (enhanced) NodesJS HTTP response
|
||||
* object should implement a library specific subclass of this class.
|
||||
*/
|
||||
abstract class ResponseNode extends HTTP::Servers::StandardResponseNode { }
|
||||
abstract class ResponseNode extends Http::Servers::StandardResponseNode { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RequestNode` instead.
|
||||
@@ -100,7 +100,7 @@ module NodeJSLib {
|
||||
* A server library that provides an (enhanced) NodesJS HTTP request
|
||||
* object should implement a library specific subclass of this class.
|
||||
*/
|
||||
abstract class RequestNode extends HTTP::Servers::StandardRequestNode { }
|
||||
abstract class RequestNode extends Http::Servers::StandardRequestNode { }
|
||||
|
||||
/**
|
||||
* A function used as an Node.js server route handler.
|
||||
@@ -109,7 +109,7 @@ module NodeJSLib {
|
||||
* but support for other kinds of route handlers can be added by implementing
|
||||
* additional subclasses of this class.
|
||||
*/
|
||||
abstract class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
abstract class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
/**
|
||||
* Gets the parameter of the route handler that contains the request object.
|
||||
*/
|
||||
@@ -131,7 +131,7 @@ module NodeJSLib {
|
||||
/**
|
||||
* A Node.js response source.
|
||||
*/
|
||||
abstract class ResponseSource extends HTTP::Servers::ResponseSource { }
|
||||
abstract class ResponseSource extends Http::Servers::ResponseSource { }
|
||||
|
||||
/**
|
||||
* A standard Node.js response source, that is, the response parameter of a
|
||||
@@ -151,7 +151,7 @@ module NodeJSLib {
|
||||
/**
|
||||
* A Node.js request source.
|
||||
*/
|
||||
abstract class RequestSource extends HTTP::Servers::RequestSource { }
|
||||
abstract class RequestSource extends Http::Servers::RequestSource { }
|
||||
|
||||
/**
|
||||
* A standard Node.js request source, that is, the request parameter of a
|
||||
@@ -201,7 +201,7 @@ module NodeJSLib {
|
||||
/**
|
||||
* An access to a user-controlled Node.js request input.
|
||||
*/
|
||||
private class RequestInputAccess extends HTTP::RequestInputAccess {
|
||||
private class RequestInputAccess extends Http::RequestInputAccess {
|
||||
RequestNode request;
|
||||
string kind;
|
||||
|
||||
@@ -223,7 +223,7 @@ module NodeJSLib {
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = request.getRouteHandler() }
|
||||
override Http::RouteHandler getRouteHandler() { result = request.getRouteHandler() }
|
||||
|
||||
override string getKind() { result = kind }
|
||||
}
|
||||
@@ -231,7 +231,7 @@ module NodeJSLib {
|
||||
/**
|
||||
* An access to an HTTP header (other than "Cookie") on an incoming Node.js request object.
|
||||
*/
|
||||
private class RequestHeaderAccess extends HTTP::RequestHeaderAccess {
|
||||
private class RequestHeaderAccess extends Http::RequestHeaderAccess {
|
||||
RequestNode request;
|
||||
|
||||
RequestHeaderAccess() {
|
||||
@@ -247,14 +247,14 @@ module NodeJSLib {
|
||||
result = this.(DataFlow::PropRead).getPropertyName().toLowerCase()
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = request.getRouteHandler() }
|
||||
override Http::RouteHandler getRouteHandler() { result = request.getRouteHandler() }
|
||||
|
||||
override string getKind() { result = "header" }
|
||||
|
||||
RequestNode getRequest() { result = request }
|
||||
}
|
||||
|
||||
class RouteSetup extends DataFlow::CallNode, HTTP::Servers::StandardRouteSetup {
|
||||
class RouteSetup extends DataFlow::CallNode, Http::Servers::StandardRouteSetup {
|
||||
ServerDefinition server;
|
||||
DataFlow::Node handler;
|
||||
|
||||
@@ -282,7 +282,7 @@ module NodeJSLib {
|
||||
result = succ.backtrack(t2, t)
|
||||
or
|
||||
t = t2 and
|
||||
HTTP::routeHandlerStep(result, succ)
|
||||
Http::routeHandlerStep(result, succ)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -300,12 +300,12 @@ module NodeJSLib {
|
||||
DataFlow::Node getRouteHandlerNode() { result = handler }
|
||||
}
|
||||
|
||||
abstract private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition {
|
||||
abstract private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition {
|
||||
ResponseNode r;
|
||||
|
||||
HeaderDefinition() { this.getReceiver() = r }
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = r.getRouteHandler() }
|
||||
override Http::RouteHandler getRouteHandler() { result = r.getRouteHandler() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,8 +403,8 @@ module NodeJSLib {
|
||||
* An expression passed as the first argument to the `write` or `end` method
|
||||
* of an HTTP response.
|
||||
*/
|
||||
private class ResponseSendArgument extends HTTP::ResponseSendArgument {
|
||||
HTTP::RouteHandler rh;
|
||||
private class ResponseSendArgument extends Http::ResponseSendArgument {
|
||||
Http::RouteHandler rh;
|
||||
|
||||
ResponseSendArgument() {
|
||||
exists(DataFlow::MethodCallNode mcn, string m | m = "write" or m = "end" |
|
||||
@@ -415,13 +415,13 @@ module NodeJSLib {
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = rh }
|
||||
override Http::RouteHandler getRouteHandler() { result = rh }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that creates a new Node.js server.
|
||||
*/
|
||||
class ServerDefinition extends HTTP::Servers::StandardServerDefinition {
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition {
|
||||
ServerDefinition() { isCreateServer(this) }
|
||||
}
|
||||
|
||||
@@ -820,7 +820,7 @@ module NodeJSLib {
|
||||
*
|
||||
* For example, this could be the function `function(req, res){...}`.
|
||||
*/
|
||||
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate {
|
||||
class RouteHandlerCandidate extends Http::RouteHandlerCandidate {
|
||||
RouteHandlerCandidate() {
|
||||
exists(string request, string response |
|
||||
(request = "request" or request = "req") and
|
||||
@@ -840,7 +840,7 @@ module NodeJSLib {
|
||||
* A function that flows to a route setup.
|
||||
*/
|
||||
private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
Http::Servers::StandardRouteHandler, DataFlow::FunctionNode {
|
||||
TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() }
|
||||
}
|
||||
|
||||
@@ -871,7 +871,7 @@ module NodeJSLib {
|
||||
* For example, this could be the call `server.on("request", handler)`
|
||||
* where it is unknown if `server` is a Node.js server.
|
||||
*/
|
||||
class RouteSetupCandidate extends HTTP::RouteSetupCandidate, DataFlow::MethodCallNode {
|
||||
class RouteSetupCandidate extends Http::RouteSetupCandidate, DataFlow::MethodCallNode {
|
||||
DataFlow::ValueNode arg;
|
||||
|
||||
RouteSetupCandidate() {
|
||||
@@ -912,7 +912,7 @@ module NodeJSLib {
|
||||
exists(string moduleName, DataFlow::SourceNode callee | this = callee.getACall() |
|
||||
(moduleName = "http" or moduleName = "https") and
|
||||
(
|
||||
callee = DataFlow::moduleMember(moduleName, any(HTTP::RequestMethodName m).toLowerCase())
|
||||
callee = DataFlow::moduleMember(moduleName, any(Http::RequestMethodName m).toLowerCase())
|
||||
or
|
||||
callee = DataFlow::moduleMember(moduleName, "request")
|
||||
) and
|
||||
|
||||
@@ -17,7 +17,7 @@ module Request {
|
||||
action = mod.getAnInvocation()
|
||||
or
|
||||
// specialized form: `request.get(...)`
|
||||
action = mod.getAMemberCall(any(HTTP::RequestMethodName n).toLowerCase())
|
||||
action = mod.getAMemberCall(any(Http::RequestMethodName n).toLowerCase())
|
||||
)
|
||||
|
|
||||
exists(DataFlow::MethodCallNode auth, int argIndex |
|
||||
|
||||
@@ -9,7 +9,7 @@ module Restify {
|
||||
/**
|
||||
* An expression that creates a new Restify server.
|
||||
*/
|
||||
class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::CallNode {
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::CallNode {
|
||||
ServerDefinition() {
|
||||
// `server = restify.createServer()`
|
||||
this = DataFlow::moduleMember("restify", "createServer").getACall()
|
||||
@@ -19,7 +19,7 @@ module Restify {
|
||||
/**
|
||||
* A Restify route handler.
|
||||
*/
|
||||
class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::ValueNode {
|
||||
class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::ValueNode {
|
||||
Function function;
|
||||
|
||||
RouteHandler() {
|
||||
@@ -42,7 +42,7 @@ module Restify {
|
||||
* A Restify response source, that is, the response parameter of a
|
||||
* route handler.
|
||||
*/
|
||||
private class ResponseSource extends HTTP::Servers::ResponseSource {
|
||||
private class ResponseSource extends Http::Servers::ResponseSource {
|
||||
RouteHandler rh;
|
||||
|
||||
ResponseSource() { this = DataFlow::parameterNode(rh.getResponseParameter()) }
|
||||
@@ -57,7 +57,7 @@ module Restify {
|
||||
* A Restify request source, that is, the request parameter of a
|
||||
* route handler.
|
||||
*/
|
||||
private class RequestSource extends HTTP::Servers::RequestSource {
|
||||
private class RequestSource extends Http::Servers::RequestSource {
|
||||
RouteHandler rh;
|
||||
|
||||
RequestSource() { this = DataFlow::parameterNode(rh.getRequestParameter()) }
|
||||
@@ -101,7 +101,7 @@ module Restify {
|
||||
/**
|
||||
* An access to a user-controlled Restify request input.
|
||||
*/
|
||||
private class RequestInputAccess extends HTTP::RequestInputAccess {
|
||||
private class RequestInputAccess extends Http::RequestInputAccess {
|
||||
RequestNode request;
|
||||
string kind;
|
||||
|
||||
@@ -140,7 +140,7 @@ module Restify {
|
||||
/**
|
||||
* An HTTP header defined in a Restify server.
|
||||
*/
|
||||
private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition {
|
||||
private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition {
|
||||
HeaderDefinition() {
|
||||
// response.header('Cache-Control', 'no-cache')
|
||||
this.getReceiver() instanceof ResponseNode and
|
||||
@@ -153,13 +153,13 @@ module Restify {
|
||||
/**
|
||||
* A call to a Restify method that sets up a route.
|
||||
*/
|
||||
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
|
||||
class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup {
|
||||
ServerDefinition server;
|
||||
|
||||
RouteSetup() {
|
||||
// server.get('/', fun)
|
||||
// server.head('/', fun)
|
||||
server.ref().getAMethodCall(any(HTTP::RequestMethodName m).toLowerCase()) = this
|
||||
server.ref().getAMethodCall(any(Http::RequestMethodName m).toLowerCase()) = this
|
||||
}
|
||||
|
||||
override DataFlow::SourceNode getARouteHandler() { result.flowsTo(this.getArgument(1)) }
|
||||
|
||||
@@ -151,7 +151,7 @@ module Templating {
|
||||
|
||||
/** Gets the data flow node representing the initialization of the given variable in this scope. */
|
||||
DataFlow::Node getVariableInit(string name) {
|
||||
result = DataFlow::ssaDefinitionNode(SSA::implicitInit(this.getScope().getVariable(name)))
|
||||
result = DataFlow::ssaDefinitionNode(Ssa::implicitInit(this.getScope().getVariable(name)))
|
||||
}
|
||||
|
||||
/** Gets a data flow node corresponding to a use of the given template variable within this top-level. */
|
||||
|
||||
@@ -226,21 +226,21 @@ module ServerWebSocket {
|
||||
* A `socket.on("connection", (msg, req) => {})` call seen as a HTTP route handler.
|
||||
* `req` is a `HTTP::IncomingMessage` instance.
|
||||
*/
|
||||
class ConnectionCallAsRouteHandler extends HTTP::RouteHandler, DataFlow::CallNode {
|
||||
class ConnectionCallAsRouteHandler extends Http::RouteHandler, DataFlow::CallNode {
|
||||
ConnectionCallAsRouteHandler() { this = getAConnectionCall(_) }
|
||||
|
||||
override HTTP::HeaderDefinition getAResponseHeader(string name) { none() }
|
||||
override Http::HeaderDefinition getAResponseHeader(string name) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `req` parameter of a `socket.on("connection", (msg, req) => {})` call.
|
||||
*/
|
||||
class ServerHttpRequest extends HTTP::Servers::RequestSource {
|
||||
class ServerHttpRequest extends Http::Servers::RequestSource {
|
||||
ConnectionCallAsRouteHandler handler;
|
||||
|
||||
ServerHttpRequest() { this = handler.getCallback(1).getParameter(1) }
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = handler }
|
||||
override Http::RouteHandler getRouteHandler() { result = handler }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for ServerHttpRequest */
|
||||
@@ -249,7 +249,7 @@ module ServerWebSocket {
|
||||
/**
|
||||
* An access user-controlled HTTP request input in a request to a WebSocket server.
|
||||
*/
|
||||
class WebSocketRequestInput extends HTTP::RequestInputAccess {
|
||||
class WebSocketRequestInput extends Http::RequestInputAccess {
|
||||
ServerHttpRequest request;
|
||||
string kind;
|
||||
|
||||
@@ -267,7 +267,7 @@ module ServerWebSocket {
|
||||
|
||||
override string getKind() { result = kind }
|
||||
|
||||
override HTTP::RouteHandler getRouteHandler() { result = request.getRouteHandler() }
|
||||
override Http::RouteHandler getRouteHandler() { result = request.getRouteHandler() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,14 +11,14 @@ private import semmle.javascript.frameworks.ConnectExpressShared
|
||||
* Add `NodeJSLib::RouteHandlerCandidate` to the extent of `NodeJSLib::RouteHandler`.
|
||||
*/
|
||||
private class PromotedNodeJSLibCandidate extends NodeJSLib::RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler {
|
||||
Http::Servers::StandardRouteHandler {
|
||||
PromotedNodeJSLibCandidate() { this instanceof NodeJSLib::RouteHandlerCandidate }
|
||||
}
|
||||
|
||||
/**
|
||||
* Add `Hapi::RouteHandlerCandidate` to the extent of `Hapi::RouteHandler`.
|
||||
*/
|
||||
private class PromotedHapiCandidate extends Hapi::RouteHandler, HTTP::Servers::StandardRouteHandler {
|
||||
private class PromotedHapiCandidate extends Hapi::RouteHandler, Http::Servers::StandardRouteHandler {
|
||||
PromotedHapiCandidate() { this instanceof Hapi::RouteHandlerCandidate }
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ private class PromotedHapiCandidate extends Hapi::RouteHandler, HTTP::Servers::S
|
||||
* Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Express::RouteHandler`.
|
||||
*/
|
||||
private class PromotedExpressCandidate extends Express::RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler {
|
||||
Http::Servers::StandardRouteHandler {
|
||||
PromotedExpressCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate }
|
||||
|
||||
override DataFlow::ParameterNode getRouteHandlerParameter(string kind) {
|
||||
@@ -38,7 +38,7 @@ private class PromotedExpressCandidate extends Express::RouteHandler,
|
||||
* Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Connect::RouteHandler`.
|
||||
*/
|
||||
private class PromotedConnectCandidate extends Connect::RouteHandler,
|
||||
HTTP::Servers::StandardRouteHandler {
|
||||
Http::Servers::StandardRouteHandler {
|
||||
PromotedConnectCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate }
|
||||
|
||||
override DataFlow::ParameterNode getRouteHandlerParameter(string kind) {
|
||||
|
||||
@@ -96,7 +96,10 @@ class OverlyWideRange extends RegExpCharacterRange {
|
||||
toCodePoint("A") <= high
|
||||
or
|
||||
// a non-alphanumeric char as part of the range boundaries
|
||||
exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode()))
|
||||
exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode())) and
|
||||
// while still being ascii
|
||||
low < 128 and
|
||||
high < 128
|
||||
) and
|
||||
// allowlist for known ranges
|
||||
not this = allowedWideRanges()
|
||||
|
||||
@@ -96,7 +96,7 @@ private predicate writesProperty(DataFlow::Node node, string name) {
|
||||
exists(VarDef v | v.getAVariable().getName() = name |
|
||||
if exists(v.getSource())
|
||||
then v.getSource() = node.asExpr()
|
||||
else node = DataFlow::ssaDefinitionNode(SSA::definition(v))
|
||||
else node = DataFlow::ssaDefinitionNode(Ssa::definition(v))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ module TaintedObject {
|
||||
|
||||
/** Request input accesses as a JSON source. */
|
||||
private class RequestInputAsSource extends Source {
|
||||
RequestInputAsSource() { this.(HTTP::RequestInputAccess).isUserControlledObject() }
|
||||
RequestInputAsSource() { this.(Http::RequestInputAccess).isUserControlledObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,7 +127,7 @@ class UselessCat extends CommandCall {
|
||||
or
|
||||
// `exec` can use 3 parameters, `readFile` can only use two, so it is OK to have a third parameter if it is unused,
|
||||
func.getNumParameter() = 3 and
|
||||
not exists(SSA::definition(func.getParameter(2).getParameter()))
|
||||
not exists(Ssa::definition(func.getParameter(2).getParameter()))
|
||||
)
|
||||
) and
|
||||
// The process returned by an async call is unused.
|
||||
|
||||
@@ -49,7 +49,7 @@ module CleartextStorage {
|
||||
*/
|
||||
class CookieStorageSink extends Sink {
|
||||
CookieStorageSink() {
|
||||
exists(HTTP::CookieDefinition cookieDef |
|
||||
exists(Http::CookieDefinition cookieDef |
|
||||
this = cookieDef.getValueArgument() or
|
||||
this = cookieDef.getHeaderArgument()
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ module CodeInjection {
|
||||
/**
|
||||
* Gets the substitute for `X` in the message `User-provided value flows to X`.
|
||||
*/
|
||||
string getMessageSuffix() { result = "here and is interpreted as code" }
|
||||
string getMessageSuffix() { result = "this location and is interpreted as code" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +126,8 @@ module CodeInjection {
|
||||
}
|
||||
|
||||
override string getMessageSuffix() {
|
||||
result = "here and is interpreted by " + templateType + ", which may evaluate it as code"
|
||||
result =
|
||||
"this location and is interpreted by " + templateType + ", which may evaluate it as code"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +289,7 @@ module CodeInjection {
|
||||
/** A sink for code injection via template injection. */
|
||||
abstract private class TemplateSink extends Sink {
|
||||
override string getMessageSuffix() {
|
||||
result = "here and is interpreted as a template, which may contain code"
|
||||
result = "this location and is interpreted as a template, which may contain code"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ module CorsMisconfigurationForCredentials {
|
||||
/**
|
||||
* Gets the "Access-Control-Allow-Credentials" header definition.
|
||||
*/
|
||||
abstract HTTP::HeaderDefinition getCredentialsHeader();
|
||||
abstract Http::HeaderDefinition getCredentialsHeader();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,11 +41,11 @@ module CorsMisconfigurationForCredentials {
|
||||
* HTTP header with a truthy value.
|
||||
*/
|
||||
class CorsOriginHeaderWithAssociatedCredentialHeader extends Sink, DataFlow::ValueNode {
|
||||
HTTP::ExplicitHeaderDefinition credentials;
|
||||
Http::ExplicitHeaderDefinition credentials;
|
||||
|
||||
CorsOriginHeaderWithAssociatedCredentialHeader() {
|
||||
exists(
|
||||
HTTP::RouteHandler routeHandler, HTTP::ExplicitHeaderDefinition origin,
|
||||
Http::RouteHandler routeHandler, Http::ExplicitHeaderDefinition origin,
|
||||
DataFlow::Node credentialsValue
|
||||
|
|
||||
routeHandler.getAResponseHeader(_) = origin and
|
||||
@@ -58,7 +58,7 @@ module CorsMisconfigurationForCredentials {
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::HeaderDefinition getCredentialsHeader() { result = credentials }
|
||||
override Http::HeaderDefinition getCredentialsHeader() { result = credentials }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,7 @@ module DifferentKindsComparisonBypass {
|
||||
* A HTTP request input that is suspicious to compare with another HTTP request input of a different kind.
|
||||
*/
|
||||
class RequestInputComparisonSource extends Source {
|
||||
HTTP::RequestInputAccess input;
|
||||
Http::RequestInputAccess input;
|
||||
|
||||
RequestInputComparisonSource() { input = this }
|
||||
|
||||
@@ -42,7 +42,7 @@ module DifferentKindsComparisonBypass {
|
||||
/**
|
||||
* Gets the HTTP request input of this source.
|
||||
*/
|
||||
private HTTP::RequestInputAccess getInput() { result = input }
|
||||
private Http::RequestInputAccess getInput() { result = input }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,7 @@ module HardcodedDataInterpretedAsCode {
|
||||
|
||||
override DataFlow::FlowLabel getLabel() { result.isTaint() }
|
||||
|
||||
override string getKind() { result = "code" }
|
||||
override string getKind() { result = "Code" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,6 +65,6 @@ module HardcodedDataInterpretedAsCode {
|
||||
|
||||
override DataFlow::FlowLabel getLabel() { result.isDataOrTaint() }
|
||||
|
||||
override string getKind() { result = "an import path" }
|
||||
override string getKind() { result = "An import path" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "TaintedHostHeader" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
exists(HTTP::RequestHeaderAccess input | node = input |
|
||||
exists(Http::RequestHeaderAccess input | node = input |
|
||||
input.getKind() = "header" and
|
||||
input.getAHeaderName() = "host"
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ private import HttpToFileAccessCustomizations::HttpToFileAccess
|
||||
* An access to a user-controlled HTTP request input, considered as a flow source for writing user-controlled data to files
|
||||
*/
|
||||
private class RequestInputAccessAsSource extends Source {
|
||||
RequestInputAccessAsSource() { this instanceof HTTP::RequestInputAccess }
|
||||
RequestInputAccessAsSource() { this instanceof Http::RequestInputAccess }
|
||||
}
|
||||
|
||||
/** A response from a server, considered as a flow source for writing user-controlled data to files. */
|
||||
|
||||
@@ -24,15 +24,15 @@ module ReflectedXss {
|
||||
* a content type that does not (case-insensitively) contain the string "html". This
|
||||
* is to prevent us from flagging plain-text or JSON responses as vulnerable.
|
||||
*/
|
||||
class HttpResponseSink extends Sink instanceof HTTP::ResponseSendArgument {
|
||||
class HttpResponseSink extends Sink instanceof Http::ResponseSendArgument {
|
||||
HttpResponseSink() { not exists(getANonHtmlHeaderDefinition(this)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a HeaderDefinition that defines a non-html content-type for `send`.
|
||||
*/
|
||||
HTTP::HeaderDefinition getANonHtmlHeaderDefinition(HTTP::ResponseSendArgument send) {
|
||||
exists(HTTP::RouteHandler h |
|
||||
Http::HeaderDefinition getANonHtmlHeaderDefinition(Http::ResponseSendArgument send) {
|
||||
exists(Http::RouteHandler h |
|
||||
send.getRouteHandler() = h and
|
||||
result = nonHtmlContentTypeHeader(h)
|
||||
|
|
||||
@@ -44,7 +44,7 @@ module ReflectedXss {
|
||||
/**
|
||||
* Holds if `h` may send a response with a content type other than HTML.
|
||||
*/
|
||||
HTTP::HeaderDefinition nonHtmlContentTypeHeader(HTTP::RouteHandler h) {
|
||||
Http::HeaderDefinition nonHtmlContentTypeHeader(Http::RouteHandler h) {
|
||||
result = h.getAResponseHeader("content-type") and
|
||||
not exists(string tp | result.defines("content-type", tp) | tp.regexpMatch("(?i).*html.*"))
|
||||
}
|
||||
@@ -52,7 +52,7 @@ module ReflectedXss {
|
||||
/**
|
||||
* Holds if a header set in `header` is likely to affect a response sent at `sender`.
|
||||
*/
|
||||
predicate headerAffects(HTTP::HeaderDefinition header, HTTP::ResponseSendArgument sender) {
|
||||
predicate headerAffects(Http::HeaderDefinition header, Http::ResponseSendArgument sender) {
|
||||
sender.getRouteHandler() = header.getRouteHandler() and
|
||||
(
|
||||
// `sender` is affected by a dominating `header`.
|
||||
@@ -60,7 +60,7 @@ module ReflectedXss {
|
||||
or
|
||||
// There is no dominating header, and `header` is non-local.
|
||||
not isLocalHeaderDefinition(header) and
|
||||
not exists(HTTP::HeaderDefinition dominatingHeader |
|
||||
not exists(Http::HeaderDefinition dominatingHeader |
|
||||
dominatingHeader.getBasicBlock().(ReachableBasicBlock).dominates(sender.getBasicBlock())
|
||||
)
|
||||
)
|
||||
@@ -77,10 +77,10 @@ module ReflectedXss {
|
||||
* return;
|
||||
* ```
|
||||
*/
|
||||
predicate isLocalHeaderDefinition(HTTP::HeaderDefinition header) {
|
||||
predicate isLocalHeaderDefinition(Http::HeaderDefinition header) {
|
||||
exists(ReachableBasicBlock headerBlock | headerBlock = header.getBasicBlock() |
|
||||
1 =
|
||||
strictcount(HTTP::ResponseSendArgument sender |
|
||||
strictcount(Http::ResponseSendArgument sender |
|
||||
sender.getRouteHandler() = header.getRouteHandler() and
|
||||
header.getBasicBlock().(ReachableBasicBlock).dominates(sender.getBasicBlock())
|
||||
) and
|
||||
@@ -108,9 +108,9 @@ module ReflectedXss {
|
||||
/** A third-party controllable request input, considered as a flow source for reflected XSS. */
|
||||
class ThirdPartyRequestInputAccessAsSource extends Source {
|
||||
ThirdPartyRequestInputAccessAsSource() {
|
||||
this.(HTTP::RequestInputAccess).isThirdPartyControllable()
|
||||
this.(Http::RequestInputAccess).isThirdPartyControllable()
|
||||
or
|
||||
this.(HTTP::RequestHeaderAccess).getAHeaderName() = "referer"
|
||||
this.(Http::RequestHeaderAccess).getAHeaderName() = "referer"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ module RemotePropertyInjection {
|
||||
exists(DeleteExpr expr | expr.getOperand().(PropAccess).getPropertyNameExpr() = astNode)
|
||||
}
|
||||
|
||||
override string getMessage() { result = " a property name to write to." }
|
||||
override string getMessage() { result = "A property name to write to" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,12 +59,12 @@ module RemotePropertyInjection {
|
||||
*/
|
||||
class HeaderNameSink extends Sink {
|
||||
HeaderNameSink() {
|
||||
exists(HTTP::ExplicitHeaderDefinition hd |
|
||||
exists(Http::ExplicitHeaderDefinition hd |
|
||||
not hd instanceof Express::SetMultipleHeaders and
|
||||
this = hd.getNameNode()
|
||||
)
|
||||
}
|
||||
|
||||
override string getMessage() { result = " a header name." }
|
||||
override string getMessage() { result = "A header name" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ module ServerSideUrlRedirect {
|
||||
/** A source of third-party user input, considered as a flow source for URL redirects. */
|
||||
class ThirdPartyRequestInputAccessAsSource extends Source {
|
||||
ThirdPartyRequestInputAccessAsSource() {
|
||||
this.(HTTP::RequestInputAccess).isThirdPartyControllable()
|
||||
this.(Http::RequestInputAccess).isThirdPartyControllable()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ module ServerSideUrlRedirect {
|
||||
* An HTTP redirect, considered as a sink for `Configuration`.
|
||||
*/
|
||||
class RedirectSink extends Sink {
|
||||
RedirectSink() { this = any(HTTP::RedirectInvocation redir).getUrlArgument() }
|
||||
RedirectSink() { this = any(Http::RedirectInvocation redir).getUrlArgument() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ module ServerSideUrlRedirect {
|
||||
*/
|
||||
class LocationHeaderSink extends Sink {
|
||||
LocationHeaderSink() {
|
||||
any(HTTP::ExplicitHeaderDefinition def).definesHeaderValue("location", this)
|
||||
any(Http::ExplicitHeaderDefinition def).definesHeaderValue("location", this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,5 +32,5 @@ module StackTraceExposure {
|
||||
* An expression that can become part of an HTTP response body, viewed
|
||||
* as a data flow sink for stack trace exposure vulnerabilities.
|
||||
*/
|
||||
class DefaultSink extends Sink instanceof HTTP::ResponseBody { }
|
||||
class DefaultSink extends Sink instanceof Http::ResponseBody { }
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ module TypeConfusionThroughParameterTampering {
|
||||
* Node.js-based HTTP servers turn request parameters into arrays if their names are repeated.
|
||||
*/
|
||||
private class TypeTamperableRequestParameter extends Source {
|
||||
TypeTamperableRequestParameter() { this.(HTTP::RequestInputAccess).isUserControlledObject() }
|
||||
TypeTamperableRequestParameter() { this.(Http::RequestInputAccess).isUserControlledObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,8 +48,8 @@ module PolynomialReDoS {
|
||||
* A remote input to a server, seen as a source for polynomial
|
||||
* regular expression denial-of-service vulnerabilities.
|
||||
*/
|
||||
class RequestInputAccessAsSource extends Source instanceof HTTP::RequestInputAccess {
|
||||
override string getKind() { result = HTTP::RequestInputAccess.super.getKind() }
|
||||
class RequestInputAccessAsSource extends Source instanceof Http::RequestInputAccess {
|
||||
override string getKind() { result = Http::RequestInputAccess.super.getKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.3.4
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### New Queries
|
||||
|
||||
@@ -54,6 +54,8 @@ predicate isUniversalRegExp(RegExpTerm term) {
|
||||
or
|
||||
child.(RegExpCharacterClass).isUniversalClass()
|
||||
)
|
||||
or
|
||||
term.(RegExpSequence).getNumChild() = 0
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,6 +118,6 @@ where
|
||||
call instanceof RegExpSearchCall and
|
||||
not term.getAChild*() instanceof RegExpDollar and
|
||||
message =
|
||||
"This regular expression always the matches at index 0 when used $@, as it matches the empty substring."
|
||||
"This regular expression always matches at index 0 when used $@, as it matches the empty substring."
|
||||
)
|
||||
select term, message, call, "here"
|
||||
|
||||
@@ -21,5 +21,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is used in a path.", source.getNode(),
|
||||
"User-provided value"
|
||||
select sink.getNode(), source, sink, "This path depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -18,6 +18,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select source.getNode(), source, sink,
|
||||
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
|
||||
"file system operation"
|
||||
select source.getNode(), source, sink, "$@ depends on $@ which may contain '..'", sink.getNode(),
|
||||
"File system operation", source.getNode(), "unsanitized archive entry"
|
||||
|
||||
@@ -17,5 +17,5 @@ import semmle.javascript.security.dataflow.TemplateObjectInjectionQuery
|
||||
|
||||
from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Template object injection due to $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
select sink.getNode(), source, sink, "Template object depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -28,5 +28,5 @@ where
|
||||
else highlight = sink.getNode()
|
||||
) and
|
||||
sourceNode = source.getNode()
|
||||
select highlight, source, sink, "$@ flows to here and is used in a command.", source.getNode(),
|
||||
sourceNode.getSourceType()
|
||||
select highlight, source, sink, "Command line depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -19,6 +19,6 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode
|
||||
where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode()
|
||||
select sinkNode.getAlertLocation(), source, sink, "$@ based on $@ is later used in $@.",
|
||||
select sinkNode.getAlertLocation(), source, sink, "$@ which depends on $@ is later used in $@.",
|
||||
sinkNode.getAlertLocation(), sinkNode.getSinkType(), source.getNode(), "library input",
|
||||
sinkNode.getCommandExecution(), "shell command"
|
||||
sinkNode.getCommandExecution(), "a shell command"
|
||||
|
||||
@@ -18,6 +18,6 @@ import semmle.javascript.security.dataflow.UnsafeHtmlConstructionQuery
|
||||
|
||||
from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode
|
||||
where cfg.hasFlowPath(source, sink) and sink.getNode() = sinkNode
|
||||
select sinkNode, source, sink, "$@ based on $@ might later cause $@.", sinkNode,
|
||||
select sinkNode, source, sink, "$@ which depends on $@ might later allow $@.", sinkNode,
|
||||
sinkNode.describe(), source.getNode(), "library input", sinkNode.getSink(),
|
||||
sinkNode.getVulnerabilityKind().toLowerCase()
|
||||
|
||||
@@ -68,5 +68,5 @@ where
|
||||
sink.getNode().(StringOps::ConcatenationLeaf).getRoot() = endsInCodeInjectionSink() and
|
||||
remoteFlow() = source.getNode().(DataFlow::InvokeNode).getAnArgument()
|
||||
)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is used to construct code.",
|
||||
source.getNode(), "Improperly sanitized value"
|
||||
select sink.getNode(), source, sink, "Code construction depends on $@.", source.getNode(),
|
||||
"an improperly sanitized value"
|
||||
|
||||
@@ -19,5 +19,5 @@ import semmle.javascript.security.dataflow.UnsafeCodeConstruction::UnsafeCodeCon
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is later $@.", source.getNode(),
|
||||
select sink.getNode(), source, sink, "$@ flows to this location and is later $@.", source.getNode(),
|
||||
"Library input", sink.getNode().(Sink).getCodeSink(), "interpreted as code"
|
||||
|
||||
@@ -17,5 +17,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink, source, sink,
|
||||
"Invocation of method derived from $@ may lead to remote code execution.", source.getNode(),
|
||||
"user-controlled value"
|
||||
"This method is invoked using $@, which may allow remote code execution.", source.getNode(),
|
||||
"a user-controlled value"
|
||||
|
||||
@@ -17,5 +17,5 @@ import semmle.javascript.security.dataflow.LogInjectionQuery
|
||||
|
||||
from LogInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to log entry.", source.getNode(),
|
||||
"User-provided value"
|
||||
select sink.getNode(), source, sink, "Log entry depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -16,5 +16,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is used in a format string.",
|
||||
source.getNode(), "User-provided value"
|
||||
select sink.getNode(), source, sink, "Format string depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -16,5 +16,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows directly to outbound network request",
|
||||
source.getNode(), "File data"
|
||||
select sink.getNode(), source, sink, "Outbound network request depends on $@", source.getNode(),
|
||||
"file data"
|
||||
|
||||
@@ -19,6 +19,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"Sensitive data returned from $@ is sent to another window without origin restriction.",
|
||||
source.getNode(), "here"
|
||||
select sink.getNode(), source, sink, "$@ is sent to another window without origin restriction.",
|
||||
source.getNode(), "Sensitive data"
|
||||
|
||||
@@ -20,5 +20,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"Stack trace information from $@ may be exposed to an external user here.", source.getNode(),
|
||||
"here"
|
||||
"$@ flows to this location and may be exposed to an external user.", source.getNode(),
|
||||
"Stack trace information"
|
||||
|
||||
@@ -20,5 +20,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"Sensitive data returned by $@ is stored in a build artifact here.", source.getNode(),
|
||||
source.getNode().(CleartextLogging::Source).describe()
|
||||
"Sensitive data returned by $@ flows to this location and is stored in a build artifact.",
|
||||
source.getNode(), source.getNode().(CleartextLogging::Source).describe()
|
||||
|
||||
@@ -38,5 +38,5 @@ where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
// ignore logging to the browser console (even though it is not a good practice)
|
||||
not inBrowserEnvironment(sink.getNode().asExpr().getTopLevel())
|
||||
select sink.getNode(), source, sink, "Sensitive data returned by $@ is logged here.",
|
||||
source.getNode(), source.getNode().(Source).describe()
|
||||
select sink.getNode(), source, sink, "$@ is logged here.", source.getNode(),
|
||||
"Sensitive data returned by " + source.getNode().(Source).describe()
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Sensitive data returned by $@ is stored here.",
|
||||
source.getNode(), source.getNode().(Source).describe()
|
||||
select sink.getNode(), source, sink, "$@ is stored here.", source.getNode(),
|
||||
"Sensitive data returned by " + source.getNode().(Source).describe()
|
||||
|
||||
@@ -20,6 +20,5 @@ from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
not source.getNode() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash
|
||||
select sink.getNode(), source, sink,
|
||||
"Sensitive data from $@ is used in a broken or weak cryptographic algorithm.", source.getNode(),
|
||||
source.getNode().(Source).describe()
|
||||
select sink.getNode(), source, sink, "A broken or weak cryptographic algorithm depends on $@.",
|
||||
source.getNode(), "sensitive data from" + source.getNode().(Source).describe()
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"Cryptographically insecure random number is generated at $@ and used here in a security context.",
|
||||
"This security context depends on a cryptographically insecure random number at $@.",
|
||||
source.getNode(), source.getNode().toString()
|
||||
|
||||
@@ -35,7 +35,7 @@ predicate isRouteHandlerUsingCookies(Routing::RouteHandler handler) {
|
||||
* A router handler following after cookie parsing is assumed to depend on
|
||||
* cookies, and thus require CSRF protection.
|
||||
*/
|
||||
predicate hasCookieMiddleware(Routing::Node route, HTTP::CookieMiddlewareInstance cookie) {
|
||||
predicate hasCookieMiddleware(Routing::Node route, Http::CookieMiddlewareInstance cookie) {
|
||||
route.isGuardedBy(cookie)
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ private DataFlow::SourceNode nodeLeadingToCsrfWriteOrCheck(DataFlow::TypeBackTra
|
||||
* Gets a route handler that sets an CSRF related cookie.
|
||||
*/
|
||||
private Routing::RouteHandler getAHandlerSettingCsrfCookie() {
|
||||
exists(HTTP::CookieDefinition setCookie |
|
||||
exists(Http::CookieDefinition setCookie |
|
||||
setCookie.getNameArgument().getStringValue().regexpMatch("(?i).*(csrf|xsrf).*") and
|
||||
result = Routing::getRouteHandler(setCookie.getRouteHandler())
|
||||
)
|
||||
@@ -180,7 +180,7 @@ predicate hasCsrfMiddleware(Routing::RouteHandler handler) {
|
||||
|
||||
from
|
||||
Routing::RouteSetup setup, Routing::Node setupArg, Routing::RouteHandler handler,
|
||||
HTTP::CookieMiddlewareInstance cookie
|
||||
Http::CookieMiddlewareInstance cookie
|
||||
where
|
||||
// Require that the handler uses cookies and has cookie middleware.
|
||||
//
|
||||
|
||||
@@ -18,32 +18,44 @@ import javascript
|
||||
* A call that checks a property of some file.
|
||||
*/
|
||||
class FileCheck extends DataFlow::CallNode {
|
||||
string member;
|
||||
|
||||
FileCheck() {
|
||||
this =
|
||||
NodeJSLib::FS::moduleMember([
|
||||
"open", "openSync", "exists", "existsSync", "stat", "statSync", "lstat", "lstatSync",
|
||||
"fstat", "fstatSync", "access", "accessSync"
|
||||
]).getACall()
|
||||
member =
|
||||
[
|
||||
"open", "openSync", "exists", "existsSync", "stat", "statSync", "lstat", "lstatSync",
|
||||
"fstat", "fstatSync", "access", "accessSync"
|
||||
] and
|
||||
this = NodeJSLib::FS::moduleMember(member).getACall()
|
||||
}
|
||||
|
||||
DataFlow::Node getPathArgument() { result = this.getArgument(0) }
|
||||
|
||||
/** Holds if this call is a simple existence check for a file. */
|
||||
predicate isExistsCheck() { member = ["exists", "existsSync"] }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that modifies or otherwise interacts with a file.
|
||||
*/
|
||||
class FileUse extends DataFlow::CallNode {
|
||||
string member;
|
||||
|
||||
FileUse() {
|
||||
this =
|
||||
NodeJSLib::FS::moduleMember([
|
||||
// these are the six methods that accept file paths and file descriptors
|
||||
"readFile", "readFileSync", "writeFile", "writeFileSync", "appendFile", "appendFileSync",
|
||||
// don't use "open" after e.g. "access"
|
||||
"open", "openSync"
|
||||
]).getACall()
|
||||
member =
|
||||
[
|
||||
// these are the six methods that accept file paths and file descriptors
|
||||
"readFile", "readFileSync", "writeFile", "writeFileSync", "appendFile", "appendFileSync",
|
||||
// don't use "open" after e.g. "access"
|
||||
"open", "openSync"
|
||||
] and
|
||||
this = NodeJSLib::FS::moduleMember(member).getACall()
|
||||
}
|
||||
|
||||
DataFlow::Node getPathArgument() { result = this.getArgument(0) }
|
||||
|
||||
/** Holds if this call reads from a file. */
|
||||
predicate isFileRead() { member = ["readFile", "readFileSync"] }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,5 +113,6 @@ from FileCheck check, FileUse use
|
||||
where
|
||||
checkAndUseOnSame(check, use) and
|
||||
useAfterCheck(check, use) and
|
||||
not (check.isExistsCheck() and use.isFileRead()) and // a read after an exists check is fine
|
||||
not getAFileHandle(DataFlow::TypeTracker::end()).flowsTo(use.getPathArgument())
|
||||
select use, "The file may have changed since it $@.", check, "was checked"
|
||||
|
||||
@@ -20,5 +20,5 @@ from
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
sink.getNode().(Sink).hasReason(link, reason)
|
||||
select sink, source, sink, "Denial of service caused by processing user input from $@ with $@.",
|
||||
source.getNode(), "here", link, reason
|
||||
select sink, source, sink, "Denial of service caused by processing $@ with $@.", source.getNode(),
|
||||
"user input", link, reason
|
||||
|
||||
@@ -18,5 +18,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "A $@ is used as" + sink.getNode().(Sink).getMessage(),
|
||||
source.getNode(), "user-provided value"
|
||||
select sink.getNode(), source, sink, sink.getNode().(Sink).getMessage() + " depends on $@.",
|
||||
source.getNode(), "a user-provided value"
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
import javascript
|
||||
import semmle.javascript.frameworks.HTTP
|
||||
|
||||
from HTTP::ServerDefinition server
|
||||
from Http::ServerDefinition server
|
||||
where not exists(server.getARouteHandler().getAResponseHeader("x-frame-options"))
|
||||
select server, "This server never sets the 'X-Frame-Options' HTTP header."
|
||||
|
||||
@@ -17,4 +17,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Unsafe deserialization of $@.", source.getNode(), "user input"
|
||||
select sink.getNode(), source, sink, "Unsafe deserialization that depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"Hard-coded data from $@ is interpreted as " + sink.getNode().(Sink).getKind() + ".",
|
||||
source.getNode(), "here"
|
||||
"$@ is interpreted as " + sink.getNode().(Sink).getKind() + ".", source.getNode(),
|
||||
"Hard-coded data"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import javascript
|
||||
|
||||
from
|
||||
Routing::RouteSetup setup, Routing::RouteHandler handler, HTTP::RequestInputAccess input,
|
||||
Routing::RouteSetup setup, Routing::RouteHandler handler, Http::RequestInputAccess input,
|
||||
SensitiveNode sensitive
|
||||
where
|
||||
setup.getOwnHttpMethod() = "GET" and
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
select sink.getNode(), source, sink, "Untrusted URL redirection depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -17,5 +17,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
select sink.getNode(), source, sink, "Untrusted URL redirection depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"A $@ is parsed as XML without guarding against external entity expansion.", source.getNode(),
|
||||
"user-provided value"
|
||||
"XML parsing depends on $@ without guarding against external entity expansion.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -17,6 +17,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"Links in this email can be hijacked by poisoning the HTTP host header $@.", source.getNode(),
|
||||
"here"
|
||||
select sink.getNode(), source, sink, "Links in this email can be hijacked by poisoning the $@.",
|
||||
source.getNode(), "HTTP host header"
|
||||
|
||||
@@ -17,5 +17,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is used in an XPath expression.",
|
||||
source.getNode(), "User-provided value"
|
||||
select sink.getNode(), source, sink, "XPath expression depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This regular expression is constructed from a $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
select sink.getNode(), source, sink, "This regular expression depends on $@.", source.getNode(),
|
||||
"a user-provided value"
|
||||
|
||||
@@ -88,7 +88,7 @@ Function reachableFromAsyncCallback() {
|
||||
* The main predicate of this query: used for both result display and path computation.
|
||||
*/
|
||||
predicate main(
|
||||
HTTP::RouteHandler rh, AsyncSentinelCall async, AsyncCallback cb, LikelyExceptionThrower thrower
|
||||
Http::RouteHandler rh, AsyncSentinelCall async, AsyncCallback cb, LikelyExceptionThrower thrower
|
||||
) {
|
||||
async.getAsyncCallee() = cb and
|
||||
rh.getAstNode() = invokesCallbackThatThrowsUncaughtException(async, thrower)
|
||||
@@ -180,7 +180,7 @@ query predicate nodes(AstNode node) {
|
||||
}
|
||||
|
||||
from
|
||||
HTTP::RouteHandler rh, AsyncSentinelCall async, DataFlow::Node callbackArg, AsyncCallback cb,
|
||||
Http::RouteHandler rh, AsyncSentinelCall async, DataFlow::Node callbackArg, AsyncCallback cb,
|
||||
ExprOrStmt crasher
|
||||
where
|
||||
main(rh, async, cb, crasher) and
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"A $@ is parsed as XML without guarding against uncontrolled entity expansion.", source.getNode(),
|
||||
"user-provided value"
|
||||
"XML parsing depends on $@ without guarding against uncontrolled entity expansion.",
|
||||
source.getNode(), "a user-provided value"
|
||||
|
||||
@@ -19,5 +19,5 @@ import DataFlow::PathGraph
|
||||
from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where dataflow.hasFlowPath(source, sink)
|
||||
select sink, source, sink,
|
||||
"Iterating over user-controlled object with a potentially unbounded .length property from $@.",
|
||||
source, "here"
|
||||
"Iteration over a user-controlled object with a potentially unbounded .length property from $@.",
|
||||
source, "a user-provided value"
|
||||
|
||||
@@ -17,4 +17,4 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to file system", source.getNode(), "Untrusted data"
|
||||
select sink.getNode(), source, sink, "$@ flows to file system.", source.getNode(), "Untrusted data"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
|
||||
- The `js/regexp/always-matches` query will no longer report an empty regular expression as always
|
||||
matching, as this is often the intended behavior.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved how the JavaScript parser handles ambiguities between plain JavaScript and dialects such as Flow and E4X that use the same file extension. The parser now prefers plain JavaScript if possible, falling back to dialects only if the source code can not be parsed as plain JavaScript. Previously, there were rare cases where parsing would fail because the parser would erroneously attempt to parse dialect-specific syntax in a regular JavaScript file.
|
||||
1
javascript/ql/src/change-notes/released/0.3.4.md
Normal file
1
javascript/ql/src/change-notes/released/0.3.4.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.3.4
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.3
|
||||
lastReleaseVersion: 0.3.4
|
||||
|
||||
@@ -77,7 +77,7 @@ private module StandardPoIs {
|
||||
UnpromotedRouteSetupPoI() { this = "UnpromotedRouteSetupPoI" }
|
||||
|
||||
override predicate is(Node l0) {
|
||||
l0 instanceof HTTP::RouteSetupCandidate and not l0 instanceof HTTP::RouteSetup
|
||||
l0 instanceof Http::RouteSetupCandidate and not l0 instanceof Http::RouteSetup
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ private module StandardPoIs {
|
||||
UnpromotedRouteHandlerPoI() { this = "UnpromotedRouteHandlerPoI" }
|
||||
|
||||
override predicate is(Node l0) {
|
||||
l0 instanceof HTTP::RouteHandlerCandidate and not l0 instanceof HTTP::RouteHandler
|
||||
l0 instanceof Http::RouteHandlerCandidate and not l0 instanceof Http::RouteHandler
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ private module StandardPoIs {
|
||||
class UnpromotedRouteHandlerWithFlowPoI extends PoI {
|
||||
UnpromotedRouteHandlerWithFlowPoI() { this = "UnpromotedRouteHandlerWithFlowPoI" }
|
||||
|
||||
private DataFlow::SourceNode track(HTTP::RouteHandlerCandidate cand, DataFlow::TypeTracker t) {
|
||||
private DataFlow::SourceNode track(Http::RouteHandlerCandidate cand, DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = cand
|
||||
or
|
||||
@@ -106,8 +106,8 @@ private module StandardPoIs {
|
||||
}
|
||||
|
||||
override predicate is(Node l0, Node l1, string t1) {
|
||||
l0 instanceof HTTP::RouteHandlerCandidate and
|
||||
not l0 instanceof HTTP::RouteHandler and
|
||||
l0 instanceof Http::RouteHandlerCandidate and
|
||||
not l0 instanceof Http::RouteHandler and
|
||||
l1 = track(l0, TypeTracker::end()) and
|
||||
(if l1 = l0 then t1 = "ends here" else t1 = "starts/ends here")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import javascript
|
||||
* Gets a source node to which `cand` may flow inter-procedurally, with `t` tracking
|
||||
* the state of flow.
|
||||
*/
|
||||
DataFlow::SourceNode track(HTTP::RouteHandlerCandidate cand, DataFlow::TypeTracker t) {
|
||||
DataFlow::SourceNode track(Http::RouteHandlerCandidate cand, DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = cand
|
||||
or
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
import javascript
|
||||
import CallGraphQuality
|
||||
|
||||
HTTP::RouteHandler relevantRouteHandler() { not result.getFile() instanceof IgnoredFile }
|
||||
Http::RouteHandler relevantRouteHandler() { not result.getFile() instanceof IgnoredFile }
|
||||
|
||||
select projectRoot(), count(relevantRouteHandler())
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
import javascript
|
||||
import CandidateTracking
|
||||
|
||||
from HTTP::RouteHandlerCandidate rh
|
||||
from Http::RouteHandlerCandidate rh
|
||||
where
|
||||
not rh instanceof HTTP::RouteHandler and
|
||||
not exists(HTTP::RouteSetupCandidate setup |
|
||||
not rh instanceof Http::RouteHandler and
|
||||
not exists(Http::RouteSetupCandidate setup |
|
||||
track(rh, DataFlow::TypeTracker::end()).flowsTo(setup.getARouteHandlerArg())
|
||||
)
|
||||
select rh,
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
import javascript
|
||||
import CandidateTracking
|
||||
|
||||
from HTTP::RouteSetupCandidate setup
|
||||
from Http::RouteSetupCandidate setup
|
||||
where
|
||||
not setup instanceof HTTP::RouteSetup and
|
||||
exists(HTTP::RouteHandlerCandidate rh |
|
||||
not setup instanceof Http::RouteSetup and
|
||||
exists(Http::RouteHandlerCandidate rh |
|
||||
track(rh, DataFlow::TypeTracker::end()).flowsTo(setup.getARouteHandlerArg())
|
||||
)
|
||||
select setup,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user