diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll index cba8fc8fab77..e569fb3dc960 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll @@ -175,7 +175,7 @@ predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) { or n instanceof CryptographicKey and reason instanceof CryptographicKeyReason or - any(CryptographicOperation op).getInput().flow() = n and + any(CryptographicOperation op).getInput() = n and reason instanceof CryptographicOperationFlowReason or exists(DataFlow::CallNode call | n = call.getAnArgument() | diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll index f146f569684d..f0ec79df0cf5 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll @@ -144,7 +144,7 @@ private module AccessPaths { not param = base.getReceiver() | result = param and - name = param.asSource().asExpr().(Parameter).getName() + name = param.asSource().(DataFlow::ParameterNode).getName() or param.asSource().asExpr() instanceof DestructuringPattern and result = param.getMember(name) diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 2f84c558f3a7..3acb5c315f7d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -42,10 +42,10 @@ module SinkEndpointFilter { result = "modeled database access" or // Remove calls to APIs that aren't relevant to NoSQL injection - call.getReceiver().asExpr() instanceof HTTP::RequestExpr and + call.getReceiver() instanceof HTTP::RequestNode and result = "receiver is a HTTP request expression" or - call.getReceiver().asExpr() instanceof HTTP::ResponseExpr and + call.getReceiver() instanceof HTTP::ResponseNode and result = "receiver is a HTTP response expression" ) or @@ -115,7 +115,7 @@ predicate isBaseAdditionalFlowStep( inlbl = TaintedObject::label() and outlbl = TaintedObject::label() and exists(NoSql::Query query, DataFlow::SourceNode queryObj | - queryObj.flowsToExpr(query) and + queryObj.flowsTo(query) and queryObj.flowsTo(trg) and src = queryObj.getAPropertyWrite().getRhs() ) diff --git a/javascript/ql/lib/change-notes/2022-04-04-dataflow-models.md b/javascript/ql/lib/change-notes/2022-04-04-dataflow-models.md new file mode 100644 index 000000000000..4a454f51b202 --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-04-04-dataflow-models.md @@ -0,0 +1,57 @@ +--- +category: breaking +--- +* Many library models have been rewritten to use dataflow nodes instead of the AST. + The types of some classes have been changed, and these changes may break existing code. + Other classes and predicates have been renamed, in these cases the old name is still available as a deprecated feature. + +* The basetype of the following list of classes has changed from an expression to a dataflow node, and thus code using these classes might break. + The fix to these breakages is usually to use `asExpr()` to get an expression from a dataflow node, or to use `.flow()` to get a dataflow node from an expression. + - DOM.qll#WebStorageWrite + - CryptoLibraries.qll#CryptographicOperation + - Express.qll#Express::RequestBodyAccess + - HTTP.qll#HTTP::ResponseBody + - HTTP.qll#HTTP::CookieDefinition + - HTTP.qll#HTTP::ServerDefinition + - HTTP.qll#HTTP::RouteSetup + - NoSQL.qll#NoSql::Query + - SQL.qll#SQL::SqlString + - SQL.qll#SQL::SqlSanitizer + - HTTP.qll#ResponseBody + - HTTP.qll#CookieDefinition + - HTTP.qll#ServerDefinition + - HTTP.qll#RouteSetup + - HTTP.qll#HTTP::RedirectInvocation + - HTTP.qll#RedirectInvocation + - Express.qll#Express::RouterDefinition + - AngularJSCore.qll#LinkFunction + - Connect.qll#Connect::StandardRouteHandler + - CryptoLibraries.qll#CryptographicKeyCredentialsExpr + - AWS.qll#AWS::Credentials + - Azure.qll#Azure::Credentials + - Connect.qll#Connect::Credentials + - DigitalOcean.qll#DigitalOcean::Credentials + - Express.qll#Express::Credentials + - NodeJSLib.qll#NodeJSLib::Credentials + - PkgCloud.qll#PkgCloud::Credentials + - Request.qll#Request::Credentials + - ServiceDefinitions.qll#InjectableFunctionServiceRequest + - SensitiveActions.qll#SensitiveVariableAccess + - SensitiveActions.qll#CleartextPasswordExpr + - Connect.qll#Connect::ServerDefinition + - Restify.qll#Restify::ServerDefinition + - Connect.qll#Connect::RouteSetup + - Express.qll#Express::RouteSetup + - Fastify.qll#Fastify::RouteSetup + - Hapi.qll#Hapi::RouteSetup + - Koa.qll#Koa::RouteSetup + - Restify.qll#Restify::RouteSetup + - NodeJSLib.qll#NodeJSLib::RouteSetup + - Express.qll#Express::StandardRouteHandler + - Express.qll#Express::SetCookie + - Hapi.qll#Hapi::RouteHandler + - HTTP.qll#HTTP::Servers::StandardHeaderDefinition + - HTTP.qll#Servers::StandardHeaderDefinition + - Hapi.qll#Hapi::ServerDefinition + - Koa.qll#Koa::AppDefinition + - SensitiveActions.qll#SensitiveCall \ No newline at end of file diff --git a/javascript/ql/lib/semmle/javascript/Expr.qll b/javascript/ql/lib/semmle/javascript/Expr.qll index 7db74458bdf6..3676077e0241 100644 --- a/javascript/ql/lib/semmle/javascript/Expr.qll +++ b/javascript/ql/lib/semmle/javascript/Expr.qll @@ -167,7 +167,7 @@ class Expr extends @expr, ExprOrStmt, ExprOrType, AST::ValueNode { /** * Holds if this expression may refer to the initial value of parameter `p`. */ - predicate mayReferToParameter(Parameter p) { this.flow().mayReferToParameter(p) } + predicate mayReferToParameter(Parameter p) { DataFlow::parameterNode(p).flowsToExpr(this) } /** * Gets the static type of this expression, as determined by the TypeScript type system. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 7a2640b6f60a..20366a8f2b5c 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -139,9 +139,12 @@ module DataFlow { } /** + * DEPRECATED: Use `DataFlow::ParameterNode::flowsTo()` instead. * Holds if this expression may refer to the initial value of parameter `p`. */ - predicate mayReferToParameter(Parameter p) { parameterNode(p).(SourceNode).flowsTo(this) } + deprecated predicate mayReferToParameter(Parameter p) { + parameterNode(p).(SourceNode).flowsTo(this) + } /** * Holds if this element is at the specified location. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll index 826e5280ace6..1c9a9f661007 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll @@ -472,6 +472,12 @@ class FunctionNode extends DataFlow::ValueNode, DataFlow::SourceNode { /** Gets a parameter of this function. */ ParameterNode getAParameter() { result = this.getParameter(_) } + /** Gets the parameter named `name` of this function, if any. */ + DataFlow::ParameterNode getParameterByName(string name) { + result = this.getAParameter() and + result.getName() = name + } + /** Gets the number of parameters declared on this function. */ int getNumParameter() { result = count(astNode.getAParameter()) } @@ -556,6 +562,14 @@ class ObjectLiteralNode extends DataFlow::ValueNode, DataFlow::SourceNode { DataFlow::FunctionNode getPropertySetter(string name) { result = astNode.getPropertyByName(name).(PropertySetter).getInit().flow() } + + /** Gets the value of a computed property name of this object literal, such as `x` in `{[x]: 1}` */ + DataFlow::Node getAComputedPropertyName() { + exists(Property prop | prop = astNode.getAProperty() | + prop.isComputed() and + result = prop.getNameExpr().flow() + ) + } } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index ec38e760916a..d7f620f64315 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -482,17 +482,13 @@ module TaintTracking { */ private class HeapTaintStep extends SharedTaintStep { override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(Expr e, Expr f | e = succ.asExpr() and f = pred.asExpr() | - exists(Property prop | e.(ObjectExpr).getAProperty() = prop | - prop.isComputed() and f = prop.getNameExpr() - ) - or - // spreading a tainted object into an object literal gives a tainted object - e.(ObjectExpr).getAProperty().(SpreadProperty).getInit().(SpreadElement).getOperand() = f - or - // spreading a tainted value into an array literal gives a tainted array - e.(ArrayExpr).getAnElement().(SpreadElement).getOperand() = f - ) + succ.(DataFlow::ObjectLiteralNode).getAComputedPropertyName() = pred + or + // spreading a tainted object into an object literal gives a tainted object + succ.(DataFlow::ObjectLiteralNode).getASpreadProperty() = pred + or + // spreading a tainted value into an array literal gives a tainted array + succ.(DataFlow::ArrayCreationNode).getASpreadArgument() = pred or // arrays with tainted elements and objects with tainted property names are tainted succ.(DataFlow::ArrayCreationNode).getAnElement() = pred and @@ -546,16 +542,16 @@ module TaintTracking { */ private class ComputedPropWriteTaintStep extends SharedTaintStep { override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(AssignExpr assgn, IndexExpr idx, DataFlow::SourceNode obj | - assgn.getTarget() = idx and - obj.flowsToExpr(idx.getBase()) and - not exists(idx.getPropertyName()) and - pred = DataFlow::valueNode(assgn.getRhs()) and + exists(DataFlow::PropWrite assgn, DataFlow::SourceNode obj | + not exists(assgn.getPropertyName()) and + not assgn.getWriteNode() instanceof Property and // not a write inside an object literal + pred = assgn.getRhs() and + assgn = obj.getAPropertyWrite() and succ = obj | obj instanceof DataFlow::ObjectLiteralNode or - obj.getAPropertyRead("length").flowsToExpr(idx.getPropertyNameExpr()) + obj.getAPropertyRead("length").flowsToExpr(assgn.getPropertyNameExpr()) ) } } @@ -580,8 +576,8 @@ module TaintTracking { override predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node target) { exists(DataFlow::ValueNode succ | target = succ | // string operations that propagate taint - exists(string name | name = succ.getAstNode().(MethodCallExpr).getMethodName() | - pred.asExpr() = succ.getAstNode().(MethodCallExpr).getReceiver() and + exists(string name | name = succ.(DataFlow::MethodCallNode).getMethodName() | + pred = succ.(DataFlow::MethodCallNode).getReceiver() and ( // sorted, interesting, properties of String.prototype name = @@ -600,7 +596,7 @@ module TaintTracking { name = "join" ) or - exists(int i | pred.asExpr() = succ.getAstNode().(MethodCallExpr).getArgument(i) | + exists(int i | pred = succ.(DataFlow::MethodCallNode).getArgument(i) | name = "concat" or name = ["replace", "replaceAll"] and i = 1 @@ -615,10 +611,10 @@ module TaintTracking { ) or // String.fromCharCode and String.fromCodePoint - exists(int i, MethodCallExpr mce | - mce = succ.getAstNode() and - pred.asExpr() = mce.getArgument(i) and - (mce.getMethodName() = "fromCharCode" or mce.getMethodName() = "fromCodePoint") + exists(int i, DataFlow::MethodCallNode mcn | + mcn = succ and + pred = mcn.getArgument(i) and + mcn.getMethodName() = ["fromCharCode", "fromCodePoint"] ) or // `(encode|decode)URI(Component)?` propagate taint @@ -744,11 +740,11 @@ module TaintTracking { * the parameters in `input`. */ predicate isUrlSearchParams(DataFlow::SourceNode params, DataFlow::Node input) { - exists(DataFlow::GlobalVarRefNode urlSearchParams, NewExpr newUrlSearchParams | + exists(DataFlow::GlobalVarRefNode urlSearchParams, DataFlow::NewNode newUrlSearchParams | urlSearchParams.getName() = "URLSearchParams" and - newUrlSearchParams = urlSearchParams.getAnInstantiation().asExpr() and - params.asExpr() = newUrlSearchParams and - input.asExpr() = newUrlSearchParams.getArgument(0) + newUrlSearchParams = urlSearchParams.getAnInstantiation() and + params = newUrlSearchParams and + input = newUrlSearchParams.getArgument(0) ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AWS.qll b/javascript/ql/lib/semmle/javascript/frameworks/AWS.qll index 120f47bb9527..1eac5888b955 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AWS.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AWS.qll @@ -8,19 +8,19 @@ module AWS { /** * Holds if the `i`th argument of `invk` is an object hash for `AWS.Config`. */ - private predicate takesConfigurationObject(InvokeExpr invk, int i) { + private predicate takesConfigurationObject(DataFlow::InvokeNode invk, int i) { exists(DataFlow::ModuleImportNode mod | mod.getPath() = "aws-sdk" | // `AWS.config.update(nd)` - invk = mod.getAPropertyRead("config").getAMemberCall("update").asExpr() and + invk = mod.getAPropertyRead("config").getAMemberCall("update") and i = 0 or exists(DataFlow::SourceNode cfg | cfg = mod.getAConstructorInvocation("Config") | // `new AWS.Config(nd)` - invk = cfg.asExpr() and + invk = cfg and i = 0 or // `var config = new AWS.Config(...); config.update(nd);` - invk = cfg.getAMemberCall("update").asExpr() and + invk = cfg.getAMemberCall("update") and i = 0 ) ) @@ -29,13 +29,13 @@ module AWS { /** * An expression that is used as an AWS config value: `{ accessKeyId: , secretAccessKey: }`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { - exists(string prop, InvokeExpr invk, int i | + exists(string prop, DataFlow::InvokeNode invk, int i | takesConfigurationObject(invk, i) and - invk.hasOptionArgument(i, prop, this) + this = invk.getOptionArgument(i, prop) | prop = "accessKeyId" and kind = "user name" or diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll index f7975a8c1985..e26a71bcdd48 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll @@ -68,7 +68,7 @@ private class TrackStringsInAngularCode extends DataFlow::SourceNode::Range, Dat */ private DataFlow::CallNode angularModuleCall(string name) { result = angular().getAMemberCall("module") and - result.getArgument(0).asExpr().mayHaveStringValue(name) + result.getArgument(0).mayHaveStringValue(name) } /** @@ -105,8 +105,8 @@ class AngularModule extends TAngularModule { /** * Get the array of dependencies from this module's definition. */ - ArrayExpr getDependencyArray() { - this.getADefinition().getArgument(1).getALocalSource().asExpr() = result + DataFlow::ArrayCreationNode getDependencyArray() { + this.getADefinition().getArgument(1).getALocalSource() = result } /** @@ -160,14 +160,10 @@ class ModuleApiCall extends DataFlow::CallNode { string getMethodName() { result = methodName } } -class ModuleApiCallDependencyInjection extends DependencyInjection { - ModuleApiCall call; +class ModuleApiCallDependencyInjection extends DependencyInjection instanceof ModuleApiCall { string methodName; - ModuleApiCallDependencyInjection() { - this = call and - methodName = call.getMethodName() - } + ModuleApiCallDependencyInjection() { methodName = super.getMethodName() } /** * Gets the argument position for this method call that expects an injectable function. @@ -183,7 +179,7 @@ class ModuleApiCallDependencyInjection extends DependencyInjection { } override DataFlow::Node getAnInjectableFunction() { - result = call.getArgument(this.injectableArgPos()) + result = super.getArgument(this.injectableArgPos()) } } @@ -266,10 +262,10 @@ abstract class CustomDirective extends DirectiveInstance { DataFlow::SourceNode getMember(string name) { result.flowsTo(this.getMemberInit(name)) } /** Gets the method `name` of this directive. */ - Function getMethod(string name) { DataFlow::valueNode(result) = this.getMember(name) } + DataFlow::FunctionNode getMethod(string name) { result = this.getMember(name) } /** Gets a link function of this directive. */ - abstract Function getALinkFunction(); + abstract DataFlow::FunctionNode getALinkFunction(); /** Holds if this directive's properties are bound to the controller. */ abstract predicate bindsToController(); @@ -284,7 +280,7 @@ abstract class CustomDirective extends DirectiveInstance { InjectableFunction getController() { result = this.getMember("controller") } /** Gets the template URL of this directive, if any. */ - string getTemplateUrl() { this.getMember("templateUrl").asExpr().mayHaveStringValue(result) } + string getTemplateUrl() { this.getMember("templateUrl").mayHaveStringValue(result) } /** * Gets a template file for this directive, if any. @@ -302,9 +298,7 @@ abstract class CustomDirective extends DirectiveInstance { else result = DirectiveInstance.super.getAScope() } - private string getRestrictionString() { - this.getMember("restrict").asExpr().mayHaveStringValue(result) - } + private string getRestrictionString() { this.getMember("restrict").mayHaveStringValue(result) } private predicate hasTargetType(DirectiveTargetType type) { not exists(this.getRestrictionString()) or @@ -332,10 +326,10 @@ class GeneralDirective extends CustomDirective, MkCustomDirective { /** Gets a node that contributes to the return value of the factory function. */ override DataFlow::SourceNode getAnInstantiation() { - exists(Function factory, InjectableFunction f | + exists(DataFlow::FunctionNode factory, InjectableFunction f | f = definition.getAFactoryFunction() and factory = f.asFunction() and - result.flowsToExpr(factory.getAReturnedExpr()) + result.flowsTo(factory.getAReturn()) ) } @@ -344,7 +338,7 @@ class GeneralDirective extends CustomDirective, MkCustomDirective { } /** Gets the compile function of this directive, if any. */ - Function getCompileFunction() { result = this.getMethod("compile") } + DataFlow::FunctionNode getCompileFunction() { result = this.getMethod("compile") } /** * Gets a pre/post link function of this directive defined on its definition object. @@ -365,9 +359,8 @@ class GeneralDirective extends CustomDirective, MkCustomDirective { result = this.getMember("link").getAPropertySource(kind) or // { compile: function() { ... return link; } } - exists(Expr compileReturn, DataFlow::SourceNode compileReturnSrc | - compileReturn = this.getCompileFunction().getAReturnedExpr() and - compileReturnSrc.flowsToExpr(compileReturn) + exists(DataFlow::SourceNode compileReturnSrc | + compileReturnSrc.flowsTo(this.getCompileFunction().getAReturn()) | // link = function postLink() { ... } kind = "post" and @@ -380,18 +373,20 @@ class GeneralDirective extends CustomDirective, MkCustomDirective { } /** Gets the pre-link function of this directive. */ - Function getPreLinkFunction() { result = this.getLinkFunction("pre").getAstNode() } + DataFlow::FunctionNode getPreLinkFunction() { result = this.getLinkFunction("pre") } /** Gets the post-link function of this directive. */ - Function getPostLinkFunction() { result = this.getLinkFunction("post").getAstNode() } + DataFlow::FunctionNode getPostLinkFunction() { result = this.getLinkFunction("post") } - override Function getALinkFunction() { result = this.getLinkFunction(_).getAstNode() } + override DataFlow::FunctionNode getALinkFunction() { result = this.getLinkFunction(_) } override predicate bindsToController() { - this.getMemberInit("bindToController").asExpr().mayHaveBooleanValue(true) + this.getMemberInit("bindToController").mayHaveBooleanValue(true) } - override predicate hasIsolateScope() { this.getMember("scope").asExpr() instanceof ObjectExpr } + override predicate hasIsolateScope() { + this.getMember("scope") instanceof DataFlow::ObjectLiteralNode + } } /** @@ -412,7 +407,7 @@ class ComponentDirective extends CustomDirective, MkCustomComponent { comp.getConfig().hasPropertyWrite(name, result) } - override Function getALinkFunction() { none() } + override DataFlow::FunctionNode getALinkFunction() { none() } override predicate bindsToController() { none() } @@ -561,13 +556,12 @@ class DirectiveTargetName extends string { * * See https://docs.angularjs.org/api/ng/service/$location for details. */ -private class LocationFlowSource extends RemoteFlowSource { +private class LocationFlowSource extends RemoteFlowSource instanceof DataFlow::MethodCallNode { LocationFlowSource() { - exists(ServiceReference service, MethodCallExpr mce, string m, int n | + exists(ServiceReference service, string m, int n | service.getName() = "$location" and - this.asExpr() = mce and - mce = service.getAMethodCall(m) and - n = mce.getNumArgument() + this = service.getAMethodCall(m) and + n = super.getNumArgument() | m = "search" and n < 2 or @@ -605,7 +599,7 @@ private class JQLiteObject extends JQuery::ObjectSource::Range { JQLiteObject() { this = angular().getAMemberCall("element") or - exists(Parameter param | this = DataFlow::parameterNode(param) | + exists(DataFlow::ParameterNode param | this = param | // element parameters to user-functions invoked by AngularJS param = any(LinkFunction link).getElementParameter() or @@ -613,13 +607,13 @@ private class JQLiteObject extends JQuery::ObjectSource::Range { param = d.getCompileFunction().getParameter(0) or exists(DataFlow::FunctionNode f, int i | - f.flowsToExpr(d.getCompileFunction().getAReturnedExpr()) and i = 1 + f.flowsTo(d.getCompileFunction().getAReturn()) and i = 1 or f = d.getMember("template") and i = 0 or f = d.getMember("templateUrl") and i = 0 | - param = f.getAstNode().(Function).getParameter(i) + param = f.getParameter(i) ) ) ) @@ -631,99 +625,111 @@ private class JQLiteObject extends JQuery::ObjectSource::Range { } /** + * DEPRECATED: Use `AngularJSCallNode` instead. * A call to an AngularJS function. * * Used for exposing behavior that is similar to the behavior of other libraries. */ -abstract class AngularJSCall extends CallExpr { +deprecated class AngularJSCall extends CallExpr { + AngularJSCallNode node; + + AngularJSCall() { this.flow() = node } + + /** Holds if `e` is an argument that this call interprets as HTML. */ + deprecated predicate interpretsArgumentAsHtml(Expr e) { node.interpretsArgumentAsHtml(e.flow()) } + + /** Holds if `e` is an argument that this call stores globally, e.g. in a cookie. */ + deprecated predicate storesArgumentGlobally(Expr e) { node.storesArgumentGlobally(e.flow()) } + + /** Holds if `e` is an argument that this call interprets as code. */ + deprecated predicate interpretsArgumentAsCode(Expr e) { node.interpretsArgumentAsCode(e.flow()) } +} + +/** + * A call to an AngularJS function. + * + * Used for exposing behavior that is similar to the behavior of other libraries. + */ +abstract class AngularJSCallNode extends DataFlow::CallNode { /** * Holds if `e` is an argument that this call interprets as HTML. */ - abstract predicate interpretsArgumentAsHtml(Expr e); + abstract predicate interpretsArgumentAsHtml(DataFlow::Node e); /** * Holds if `e` is an argument that this call stores globally, e.g. in a cookie. */ - abstract predicate storesArgumentGlobally(Expr e); + abstract predicate storesArgumentGlobally(DataFlow::Node e); /** * Holds if `e` is an argument that this call interprets as code. */ - abstract predicate interpretsArgumentAsCode(Expr e); + abstract predicate interpretsArgumentAsCode(DataFlow::Node e); } /** * A call to a method on the AngularJS object itself. */ -private class AngularMethodCall extends AngularJSCall { - MethodCallExpr mce; - - AngularMethodCall() { - mce = angular().getAMemberCall(_).asExpr() and - mce = this - } +private class AngularMethodCall extends AngularJSCallNode { + AngularMethodCall() { this = angular().getAMemberCall(_) } - override predicate interpretsArgumentAsHtml(Expr e) { - mce.getMethodName() = "element" and - e = mce.getArgument(0) + override predicate interpretsArgumentAsHtml(DataFlow::Node e) { + super.getCalleeName() = "element" and + e = super.getArgument(0) } - override predicate storesArgumentGlobally(Expr e) { none() } + override predicate storesArgumentGlobally(DataFlow::Node e) { none() } - override predicate interpretsArgumentAsCode(Expr e) { none() } + override predicate interpretsArgumentAsCode(DataFlow::Node e) { none() } } /** * A call to a builtin service or one of its methods. */ -private class BuiltinServiceCall extends AngularJSCall { - CallExpr call; - +private class BuiltinServiceCall extends AngularJSCallNode { BuiltinServiceCall() { exists(BuiltinServiceReference service | service.getAMethodCall(_) = this or service.getACall() = this - | - call = this ) } - override predicate interpretsArgumentAsHtml(Expr e) { + override predicate interpretsArgumentAsHtml(DataFlow::Node e) { exists(ServiceReference service, string methodName | service.getName() = "$sce" and - call = service.getAMethodCall(methodName) + this = service.getAMethodCall(methodName) | // specialized call (methodName = "trustAsHtml" or methodName = "trustAsCss") and - e = call.getArgument(0) + e = this.getArgument(0) or // generic call with enum argument methodName = "trustAs" and exists(DataFlow::PropRead prn | - prn.asExpr() = call.getArgument(0) and + prn = this.getArgument(0) and (prn = service.getAPropertyAccess("HTML") or prn = service.getAPropertyAccess("CSS")) and - e = call.getArgument(1) + e = this.getArgument(1) ) ) } - override predicate storesArgumentGlobally(Expr e) { + override predicate storesArgumentGlobally(DataFlow::Node e) { exists(ServiceReference service, string serviceName, string methodName | service.getName() = serviceName and - call = service.getAMethodCall(methodName) + this = service.getAMethodCall(methodName) | // AngularJS caches (only available during runtime, so similar to sessionStorage) (serviceName = "$cacheFactory" or serviceName = "$templateCache") and methodName = "put" and - e = call.getArgument(1) + e = this.getArgument(1) or serviceName = "$cookies" and (methodName = "put" or methodName = "putObject") and - e = call.getArgument(1) + e = this.getArgument(1) ) } - override predicate interpretsArgumentAsCode(Expr e) { + override predicate interpretsArgumentAsCode(DataFlow::Node e) { exists(ScopeServiceReference scope, string methodName | methodName = [ @@ -731,22 +737,21 @@ private class BuiltinServiceCall extends AngularJSCall { "$watchGroup" ] | - call = scope.getAMethodCall(methodName) and - e = call.getArgument(0) + this = scope.getAMethodCall(methodName) and + e = this.getArgument(0) ) or exists(ServiceReference service | service.getName() = ["$compile", "$parse", "$interpolate"] | - call = service.getACall() and - e = call.getArgument(0) + this = service.getACall() and + e = this.getArgument(0) ) or - exists(ServiceReference service, CallExpr filterInvocation | + exists(ServiceReference service | // `$filter('orderBy')(collection, expression)` service.getName() = "$filter" and - call = service.getACall() and - call.getArgument(0).mayHaveStringValue("orderBy") and - filterInvocation.getCallee() = call and - e = filterInvocation.getArgument(1) + this = service.getACall() and + this.getArgument(0).mayHaveStringValue("orderBy") and + e = this.getACall().getArgument(1) ) } } @@ -754,33 +759,33 @@ private class BuiltinServiceCall extends AngularJSCall { /** * A link-function used in a custom AngularJS directive. */ -class LinkFunction extends Function { +class LinkFunction extends DataFlow::FunctionNode { LinkFunction() { this = any(GeneralDirective d).getALinkFunction() } /** * Gets the scope parameter of this function. */ - Parameter getScopeParameter() { result = this.getParameter(0) } + DataFlow::ParameterNode getScopeParameter() { result = this.getParameter(0) } /** * Gets the element parameter of this function (contains a jqLite-wrapped DOM element). */ - Parameter getElementParameter() { result = this.getParameter(1) } + DataFlow::ParameterNode getElementParameter() { result = this.getParameter(1) } /** * Gets the attributes parameter of this function. */ - Parameter getAttributesParameter() { result = this.getParameter(2) } + DataFlow::ParameterNode getAttributesParameter() { result = this.getParameter(2) } /** * Gets the controller parameter of this function. */ - Parameter getControllerParameter() { result = this.getParameter(3) } + DataFlow::ParameterNode getControllerParameter() { result = this.getParameter(3) } /** * Gets the transclude-function parameter of this function. */ - Parameter getTranscludeFnParameter() { result = this.getParameter(4) } + DataFlow::ParameterNode getTranscludeFnParameter() { result = this.getParameter(4) } } /** @@ -807,29 +812,29 @@ class AngularScope extends TAngularScope { /** * Gets an access to this scope object. */ - Expr getAnAccess() { + DataFlow::Node getAnAccess() { exists(CustomDirective d | this = d.getAScope() | - exists(Parameter p | + exists(DataFlow::ParameterNode p | p = d.getController().getDependencyParameter("$scope") or p = d.getALinkFunction().getParameter(0) | - result.mayReferToParameter(p) + p.flowsTo(result) ) or exists(DataFlow::ThisNode dis | - dis.flowsToExpr(result) and - dis.getBinder().getAstNode() = d.getController().asFunction() and + dis.flowsTo(result) and + dis.getBinder() = d.getController().asFunction() and d.bindsToController() ) or - d.hasIsolateScope() and result = d.getMember("scope").asExpr() + d.hasIsolateScope() and result = d.getMember("scope") ) or - exists(DirectiveController c, DOM::ElementDefinition elem, Parameter p | + exists(DirectiveController c, DOM::ElementDefinition elem, DataFlow::ParameterNode p | c.boundTo(elem) and this.mayApplyTo(elem) and p = c.getFactoryFunction().getDependencyParameter("$scope") and - result.mayReferToParameter(p) + p.flowsTo(result) ) } @@ -925,9 +930,7 @@ class RouteSetup extends DataFlow::CallNode, DependencyInjection { | result = controllerProperty or - exists(ControllerDefinition def | - controllerProperty.asExpr().mayHaveStringValue(def.getName()) - | + exists(ControllerDefinition def | controllerProperty.mayHaveStringValue(def.getName()) | result = def.getAService() ) ) @@ -1007,7 +1010,7 @@ private class RouteInstantiatedController extends Controller { override predicate boundTo(DOM::ElementDefinition elem) { exists(string url, HTML::HtmlFile template | - setup.getRouteParam("templateUrl").asExpr().mayHaveStringValue(url) and + setup.getRouteParam("templateUrl").mayHaveStringValue(url) and template.getAbsolutePath().regexpMatch(".*\\Q" + url + "\\E") and elem.getFile() = template ) @@ -1015,22 +1018,19 @@ private class RouteInstantiatedController extends Controller { override predicate boundToAs(DOM::ElementDefinition elem, string name) { this.boundTo(elem) and - setup.getRouteParam("controllerAs").asExpr().mayHaveStringValue(name) + setup.getRouteParam("controllerAs").mayHaveStringValue(name) } } /** * Dataflow for the arguments of AngularJS dependency-injected functions. */ -private class DependencyInjectedArgumentInitializer extends DataFlow::AnalyzedNode { +private class DependencyInjectedArgumentInitializer extends DataFlow::AnalyzedNode instanceof DataFlow::ParameterNode { DataFlow::AnalyzedNode service; DependencyInjectedArgumentInitializer() { - exists( - AngularJS::InjectableFunction f, Parameter param, AngularJS::CustomServiceDefinition def - | - this = DataFlow::parameterNode(param) and - def.getServiceReference() = f.getAResolvedDependency(param) and + exists(AngularJS::InjectableFunction f, AngularJS::CustomServiceDefinition def | + def.getServiceReference() = f.getAResolvedDependency(this) and service = def.getAService() ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll index 6f5aaf7d38ff..0db43d3d97a9 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll @@ -41,33 +41,35 @@ abstract class DependencyInjection extends DataFlow::ValueNode { */ abstract class InjectableFunction extends DataFlow::ValueNode { /** Gets the parameter corresponding to dependency `name`. */ - abstract Parameter getDependencyParameter(string name); + abstract DataFlow::ParameterNode getDependencyParameter(string name); /** * Gets the `i`th dependency declaration, which is also named `name`. */ - abstract AstNode getDependencyDeclaration(int i, string name); + abstract DataFlow::Node getDependencyDeclaration(int i, string name); /** - * Gets an ASTNode for the `name` dependency declaration. + * Gets a node for the `name` dependency declaration. */ - AstNode getADependencyDeclaration(string name) { result = getDependencyDeclaration(_, name) } + DataFlow::Node getADependencyDeclaration(string name) { + result = getDependencyDeclaration(_, name) + } /** - * Gets the ASTNode for the `i`th dependency declaration. + * Gets the dataflow node for the `i`th dependency declaration. */ - AstNode getDependencyDeclaration(int i) { result = getDependencyDeclaration(i, _) } + DataFlow::Node getDependencyDeclaration(int i) { result = getDependencyDeclaration(i, _) } /** Gets the function underlying this injectable function. */ - abstract Function asFunction(); + abstract DataFlow::FunctionNode asFunction(); - /** Gets a location where this function is explicitly dependency injected. */ - abstract AstNode getAnExplicitDependencyInjection(); + /** Gets a node where this function is explicitly dependency injected. */ + abstract DataFlow::Node getAnExplicitDependencyInjection(); /** * Gets a service corresponding to the dependency-injected `parameter`. */ - ServiceReference getAResolvedDependency(Parameter parameter) { + ServiceReference getAResolvedDependency(DataFlow::ParameterNode parameter) { exists(string name, InjectableFunctionServiceRequest request | this = request.getAnInjectedFunction() and parameter = getDependencyParameter(name) and @@ -79,7 +81,7 @@ abstract class InjectableFunction extends DataFlow::ValueNode { * Gets a Custom service corresponding to the dependency-injected `parameter`. * (this is a convenience variant of `getAResolvedDependency`) */ - DataFlow::Node getCustomServiceDependency(Parameter parameter) { + DataFlow::Node getCustomServiceDependency(DataFlow::ParameterNode parameter) { exists(CustomServiceDefinition custom | custom.getServiceReference() = getAResolvedDependency(parameter) and result = custom.getAService() @@ -91,100 +93,88 @@ abstract class InjectableFunction extends DataFlow::ValueNode { * An injectable function that does not explicitly list its dependencies, * instead relying on implicit matching by parameter names. */ -private class FunctionWithImplicitDependencyAnnotation extends InjectableFunction { - override Function astNode; - +private class FunctionWithImplicitDependencyAnnotation extends InjectableFunction instanceof DataFlow::FunctionNode { FunctionWithImplicitDependencyAnnotation() { this.(DataFlow::FunctionNode).flowsTo(any(DependencyInjection d).getAnInjectableFunction()) and - not exists(getAPropertyDependencyInjection(astNode)) + not exists(getAPropertyDependencyInjection(this)) } - override Parameter getDependencyParameter(string name) { - result = astNode.getParameterByName(name) + override DataFlow::ParameterNode getDependencyParameter(string name) { + result = super.getParameterByName(name) } - override Parameter getDependencyDeclaration(int i, string name) { + override DataFlow::ParameterNode getDependencyDeclaration(int i, string name) { result.getName() = name and - result = astNode.getParameter(i) + result = super.getParameter(i) } - override Function asFunction() { result = astNode } + override DataFlow::FunctionNode asFunction() { result = this } - override AstNode getAnExplicitDependencyInjection() { none() } + override DataFlow::Node getAnExplicitDependencyInjection() { none() } } -private DataFlow::PropWrite getAPropertyDependencyInjection(Function function) { - exists(DataFlow::FunctionNode ltf | - ltf.getAstNode() = function and - result = ltf.getAPropertyWrite("$inject") - ) +private DataFlow::PropWrite getAPropertyDependencyInjection(DataFlow::FunctionNode function) { + result = function.getAPropertyWrite("$inject") } /** * An injectable function with an `$inject` property that lists its * dependencies. */ -private class FunctionWithInjectProperty extends InjectableFunction { - override Function astNode; +private class FunctionWithInjectProperty extends InjectableFunction instanceof DataFlow::FunctionNode { DataFlow::ArrayCreationNode dependencies; FunctionWithInjectProperty() { ( this.(DataFlow::FunctionNode).flowsTo(any(DependencyInjection d).getAnInjectableFunction()) or - exists(FunctionWithExplicitDependencyAnnotation f | f.asFunction() = astNode) + exists(FunctionWithExplicitDependencyAnnotation f | f.asFunction() = this) ) and exists(DataFlow::PropWrite pwn | - pwn = getAPropertyDependencyInjection(astNode) and + pwn = getAPropertyDependencyInjection(this) and pwn.getRhs().getALocalSource() = dependencies ) } - override Parameter getDependencyParameter(string name) { - exists(int i | exists(getDependencyDeclaration(i, name)) | result = astNode.getParameter(i)) + override DataFlow::ParameterNode getDependencyParameter(string name) { + exists(int i | exists(getDependencyDeclaration(i, name)) | result = super.getParameter(i)) } - override AstNode getDependencyDeclaration(int i, string name) { - exists(DataFlow::ValueNode decl | - decl = dependencies.getElement(i) and - decl.mayHaveStringValue(name) and - result = decl.getAstNode() - ) + override DataFlow::Node getDependencyDeclaration(int i, string name) { + result = dependencies.getElement(i) and + result.mayHaveStringValue(name) } - override Function asFunction() { result = astNode } + override DataFlow::FunctionNode asFunction() { result = this } - override AstNode getAnExplicitDependencyInjection() { - result = getAPropertyDependencyInjection(astNode).getAstNode() + override DataFlow::Node getAnExplicitDependencyInjection() { + result = getAPropertyDependencyInjection(this) } } /** * An injectable function embedded in an array of dependencies. */ -private class FunctionWithExplicitDependencyAnnotation extends InjectableFunction { +private class FunctionWithExplicitDependencyAnnotation extends InjectableFunction instanceof DataFlow::ArrayCreationNode { DataFlow::FunctionNode function; - override ArrayExpr astNode; FunctionWithExplicitDependencyAnnotation() { this.(DataFlow::SourceNode).flowsTo(any(DependencyInjection d).getAnInjectableFunction()) and - function.flowsToExpr(astNode.getElement(astNode.getSize() - 1)) + function.flowsTo(super.getElement(super.getSize() - 1)) } - override Parameter getDependencyParameter(string name) { - exists(int i | astNode.getElement(i).mayHaveStringValue(name) | - result = asFunction().getParameter(i) - ) + override DataFlow::ParameterNode getDependencyParameter(string name) { + exists(int i | super.getElement(i).mayHaveStringValue(name) | result = function.getParameter(i)) } - override AstNode getDependencyDeclaration(int i, string name) { - result = astNode.getElement(i) and - result.(Expr).mayHaveStringValue(name) + override DataFlow::Node getDependencyDeclaration(int i, string name) { + result = super.getElement(i) and + result.mayHaveStringValue(name) } - override Function asFunction() { result = function.getAstNode() } + override DataFlow::FunctionNode asFunction() { result = function } - override AstNode getAnExplicitDependencyInjection() { - result = astNode or + override DataFlow::Node getAnExplicitDependencyInjection() { + result = this or result = function.(InjectableFunction).getAnExplicitDependencyInjection() } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll index 6d421de851ce..a9941c6492dc 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll @@ -27,7 +27,7 @@ private newtype TServiceReference = */ abstract class ServiceReference extends TServiceReference { /** Gets a textual representation of this element. */ - string toString() { result = getName() } + string toString() { result = this.getName() } /** * Gets the name of this reference. @@ -38,26 +38,26 @@ abstract class ServiceReference extends TServiceReference { * Gets a data flow node that may refer to this service. */ DataFlow::SourceNode getAReference() { - result = DataFlow::parameterNode(any(ServiceRequest request).getDependencyParameter(this)) + result = any(ServiceRequestNode request).getDependencyParameter(this) } /** * Gets an access to the referenced service. */ - Expr getAnAccess() { - result.mayReferToParameter(any(ServiceRequest request).getDependencyParameter(this)) + DataFlow::Node getAnAccess() { + any(ServiceRequestNode request).getDependencyParameter(this).flowsTo(result) } /** * Gets a call that invokes the referenced service. */ - CallExpr getACall() { result.getCallee() = getAnAccess() } + DataFlow::CallNode getACall() { result.getCalleeNode() = this.getAnAccess() } /** * Gets a method call that invokes method `methodName` on the referenced service. */ - MethodCallExpr getAMethodCall(string methodName) { - result.getReceiver() = getAnAccess() and + DataFlow::MethodCallNode getAMethodCall(string methodName) { + result.getReceiver() = this.getAnAccess() and result.getMethodName() = methodName } @@ -65,7 +65,7 @@ abstract class ServiceReference extends TServiceReference { * Gets an access to property `propertyName` on the referenced service. */ DataFlow::PropRef getAPropertyAccess(string propertyName) { - result.getBase().asExpr() = getAnAccess() and + result.getBase() = this.getAnAccess() and result.getPropertyName() = propertyName } @@ -93,7 +93,7 @@ class BuiltinServiceReference extends ServiceReference, MkBuiltinServiceReferenc DataFlow::ParameterNode builtinServiceRef(string serviceName) { exists(InjectableFunction f, BuiltinServiceReference service | service.getName() = serviceName and - result = DataFlow::parameterNode(f.getDependencyParameter(serviceName)) + result = f.getDependencyParameter(serviceName) ) } @@ -244,17 +244,17 @@ abstract class RecipeDefinition extends DataFlow::CallNode, CustomServiceDefinit this = moduleRef(_).getAMethodCall(methodName) or this = builtinServiceRef("$provide").getAMethodCall(methodName) ) and - getArgument(0).asExpr().mayHaveStringValue(name) + this.getArgument(0).mayHaveStringValue(name) } override string getName() { result = name } - override DataFlow::SourceNode getAFactoryFunction() { result.flowsTo(getArgument(1)) } + override DataFlow::SourceNode getAFactoryFunction() { result.flowsTo(this.getArgument(1)) } override DataFlow::Node getAnInjectableFunction() { methodName != "value" and methodName != "constant" and - result = getAFactoryFunction() + result = this.getAFactoryFunction() } } @@ -269,7 +269,7 @@ abstract class RecipeDefinition extends DataFlow::CallNode, CustomServiceDefinit */ abstract private class CustomSpecialServiceDefinition extends CustomServiceDefinition, DependencyInjection { - override DataFlow::Node getAnInjectableFunction() { result = getAFactoryFunction() } + override DataFlow::Node getAnInjectableFunction() { result = this.getAFactoryFunction() } } /** @@ -281,7 +281,7 @@ private predicate isCustomServiceDefinitionOnModule( DataFlow::Node factoryFunction ) { mce = moduleRef(_).getAMethodCall(moduleMethodName) and - mce.getArgument(0).asExpr().mayHaveStringValue(serviceName) and + mce.getArgument(0).mayHaveStringValue(serviceName) and factoryFunction = mce.getArgument(1) } @@ -296,7 +296,7 @@ private predicate isCustomServiceDefinitionOnProvider( factoryArgument = mce.getOptionArgument(0, serviceName) or mce.getNumArgument() = 2 and - mce.getArgument(0).asExpr().mayHaveStringValue(serviceName) and + mce.getArgument(0).mayHaveStringValue(serviceName) and factoryArgument = mce.getArgument(1) ) } @@ -338,7 +338,7 @@ class FilterDefinition extends CustomSpecialServiceDefinition { override DataFlow::SourceNode getAService() { exists(InjectableFunction f | f = factoryFunction.getALocalSource() and - result.flowsToExpr(f.asFunction().getAReturnedExpr()) + result.flowsTo(f.asFunction().getAReturn()) ) } @@ -428,7 +428,7 @@ class AnimationDefinition extends CustomSpecialServiceDefinition { override DataFlow::SourceNode getAService() { exists(InjectableFunction f | f = factoryFunction.getALocalSource() and - result.flowsToExpr(f.asFunction().getAReturnedExpr()) + result.flowsTo(f.asFunction().getAReturn()) ) } @@ -446,22 +446,37 @@ BuiltinServiceReference getBuiltinServiceOfKind(string kind) { } /** + * DEPRECATED: Use `ServiceRequestNode` instead. * A request for one or more AngularJS services. */ -abstract class ServiceRequest extends Expr { +deprecated class ServiceRequest extends Expr { + ServiceRequestNode node; + + ServiceRequest() { this.flow() = node } + + /** Gets the parameter of this request into which `service` is injected. */ + deprecated Parameter getDependencyParameter(ServiceReference service) { + result.flow() = node.getDependencyParameter(service) + } +} + +/** + * A request for one or more AngularJS services. + */ +abstract class ServiceRequestNode extends DataFlow::Node { /** * Gets the parameter of this request into which `service` is injected. */ - abstract Parameter getDependencyParameter(ServiceReference service); + abstract DataFlow::ParameterNode getDependencyParameter(ServiceReference service); } /** * The request for a scope service in the form of the link-function of a directive. */ -private class LinkFunctionWithScopeInjection extends ServiceRequest { +private class LinkFunctionWithScopeInjection extends ServiceRequestNode { LinkFunctionWithScopeInjection() { this instanceof LinkFunction } - override Parameter getDependencyParameter(ServiceReference service) { + override DataFlow::ParameterNode getDependencyParameter(ServiceReference service) { service instanceof ScopeServiceReference and result = this.(LinkFunction).getScopeParameter() } @@ -470,10 +485,10 @@ private class LinkFunctionWithScopeInjection extends ServiceRequest { /** * A request for a service, in the form of a dependency-injected function. */ -class InjectableFunctionServiceRequest extends ServiceRequest { +class InjectableFunctionServiceRequest extends ServiceRequestNode { InjectableFunction injectedFunction; - InjectableFunctionServiceRequest() { injectedFunction.getAstNode() = this } + InjectableFunctionServiceRequest() { injectedFunction = this } /** * Gets the function of this request. @@ -483,7 +498,9 @@ class InjectableFunctionServiceRequest extends ServiceRequest { /** * Gets a name of a requested service. */ - string getAServiceName() { exists(getAnInjectedFunction().getADependencyDeclaration(result)) } + string getAServiceName() { + exists(this.getAnInjectedFunction().getADependencyDeclaration(result)) + } /** * Gets a service with the specified name, relative to this request. @@ -494,16 +511,16 @@ class InjectableFunctionServiceRequest extends ServiceRequest { result.isInjectable() } - override Parameter getDependencyParameter(ServiceReference service) { + override DataFlow::ParameterNode getDependencyParameter(ServiceReference service) { service = injectedFunction.getAResolvedDependency(result) } } private DataFlow::SourceNode getFactoryFunctionResult(RecipeDefinition def) { - exists(Function factoryFunction, InjectableFunction f | + exists(DataFlow::FunctionNode factoryFunction, InjectableFunction f | f = def.getAFactoryFunction() and factoryFunction = f.asFunction() and - result.flowsToExpr(factoryFunction.getAReturnedExpr()) + result.flowsTo(factoryFunction.getAReturn()) ) } @@ -561,8 +578,8 @@ class ServiceRecipeDefinition extends RecipeDefinition { */ exists(InjectableFunction f | - f = getAFactoryFunction() and - result.getAstNode() = f.asFunction() + f = this.getAFactoryFunction() and + result = f.asFunction() ) } } @@ -574,7 +591,7 @@ class ServiceRecipeDefinition extends RecipeDefinition { class ValueRecipeDefinition extends RecipeDefinition { ValueRecipeDefinition() { methodName = "value" } - override DataFlow::SourceNode getAService() { result = getAFactoryFunction() } + override DataFlow::SourceNode getAService() { result = this.getAFactoryFunction() } } /** @@ -584,7 +601,7 @@ class ValueRecipeDefinition extends RecipeDefinition { class ConstantRecipeDefinition extends RecipeDefinition { ConstantRecipeDefinition() { methodName = "constant" } - override DataFlow::SourceNode getAService() { result = getAFactoryFunction() } + override DataFlow::SourceNode getAService() { result = this.getAFactoryFunction() } } /** @@ -607,8 +624,8 @@ class ProviderRecipeDefinition extends RecipeDefinition { */ exists(DataFlow::ThisNode thiz, InjectableFunction f | - f = getAFactoryFunction() and - thiz.getBinder().getFunction() = f.asFunction() and + f = this.getAFactoryFunction() and + thiz.getBinder() = f.asFunction() and result = thiz.getAPropertySource("$get") ) } @@ -632,7 +649,9 @@ class ConfigMethodDefinition extends ModuleApiCall { /** * Gets a provided configuration method. */ - InjectableFunction getConfigMethod() { result.(DataFlow::SourceNode).flowsTo(getArgument(0)) } + InjectableFunction getConfigMethod() { + result.(DataFlow::SourceNode).flowsTo(this.getArgument(0)) + } } /** @@ -645,12 +664,12 @@ class RunMethodDefinition extends ModuleApiCall { /** * Gets a provided run method. */ - InjectableFunction getRunMethod() { result.(DataFlow::SourceNode).flowsTo(getArgument(0)) } + InjectableFunction getRunMethod() { result.(DataFlow::SourceNode).flowsTo(this.getArgument(0)) } } /** * The `$scope` or `$rootScope` service. */ class ScopeServiceReference extends BuiltinServiceReference { - ScopeServiceReference() { getName() = "$scope" or getName() = "$rootScope" } + ScopeServiceReference() { this.getName() = "$scope" or this.getName() = "$rootScope" } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Azure.qll b/javascript/ql/lib/semmle/javascript/frameworks/Azure.qll index 5cfd2c8326dd..1527b655eddf 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Azure.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Azure.qll @@ -8,13 +8,14 @@ module Azure { /** * An expression that is used for authentication at Azure`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { - exists(CallExpr mce, string methodName | - (methodName = "loginWithUsernamePassword" or methodName = "loginWithServicePrincipalSecret") and - mce = DataFlow::moduleMember("ms-rest-azure", methodName).getACall().asExpr() + exists(DataFlow::CallNode mce | + mce = + DataFlow::moduleMember("ms-rest-azure", + ["loginWithUsernamePassword", "loginWithServicePrincipalSecret"]).getACall() | this = mce.getArgument(0) and kind = "user name" or diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index 8e56a36b9bf8..e721508ff061 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -270,16 +270,16 @@ module ClientRequest { } /** An expression that is used as a credential in a request. */ - private class AuthorizationHeader extends CredentialsExpr { + private class AuthorizationHeader extends CredentialsNode { AuthorizationHeader() { exists(DataFlow::PropWrite write | write.getPropertyName().regexpMatch("(?i)authorization") | - this = write.getRhs().asExpr() + this = write.getRhs() ) or exists(DataFlow::MethodCallNode call | call.getMethodName() = ["append", "set"] | call.getNumArgument() = 2 and call.getArgument(0).getStringValue().regexpMatch("(?i)authorization") and - this = call.getArgument(1).asExpr() + this = call.getArgument(1) ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll b/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll index 06138746fa61..fe130648cd5f 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll @@ -10,10 +10,10 @@ module Connect { /** * An expression that creates a new Connect server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition, CallExpr { + class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::CallNode { ServerDefinition() { // `app = connect()` - this = DataFlow::moduleImport("connect").getAnInvocation().asExpr() + this = DataFlow::moduleImport("connect").getAnInvocation() } } @@ -30,43 +30,45 @@ module Connect { * * `kind` is one of: "error", "request", "response", "next". */ - abstract Parameter getRouteHandlerParameter(string kind); + abstract DataFlow::ParameterNode getRouteHandlerParameter(string kind); /** * Gets the parameter of the route handler that contains the request object. */ - override Parameter getRequestParameter() { result = getRouteHandlerParameter("request") } + override DataFlow::ParameterNode getRequestParameter() { + result = getRouteHandlerParameter("request") + } /** * Gets the parameter of the route handler that contains the response object. */ - override Parameter getResponseParameter() { result = getRouteHandlerParameter("response") } + override DataFlow::ParameterNode getResponseParameter() { + result = getRouteHandlerParameter("response") + } } /** * A Connect route handler installed by a route setup. */ - class StandardRouteHandler extends RouteHandler { - override Function astNode; - + class StandardRouteHandler extends RouteHandler, DataFlow::FunctionNode { StandardRouteHandler() { this = any(RouteSetup setup).getARouteHandler() } - override Parameter getRouteHandlerParameter(string kind) { - result = getRouteHandlerParameter(astNode, kind) + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { + result = getRouteHandlerParameter(this, kind) } } /** * A call to a Connect method that sets up a route. */ - class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { ServerDefinition server; RouteSetup() { getMethodName() = "use" and ( // app.use(fun) - server.flowsTo(getReceiver()) + server.ref().getAMethodCall() = this or // app.use(...).use(fun) this.getReceiver().(RouteSetup).getServer() = server @@ -79,24 +81,32 @@ module Connect { private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) { t.start() and - result = getARouteHandlerExpr().flow().getALocalSource() + result = getARouteHandlerNode().getALocalSource() or exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t)) } - override Expr getServer() { result = server } + override DataFlow::Node getServer() { result = server } - /** Gets an argument that represents a route handler being registered. */ - Expr getARouteHandlerExpr() { result = getAnArgument() } + /** + * DEPRECATED: Use `getARouteHandlerNode` instead. + * Gets an argument that represents a route handler being registered. + */ + deprecated Expr getARouteHandlerExpr() { result = getARouteHandlerNode().asExpr() } + + /** + * Gets an argument that represents a route handler being registered. + */ + DataFlow::Node getARouteHandlerNode() { result = getAnArgument() } } /** An expression that is passed as `basicAuthConnect(, )`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { - exists(CallExpr call | - call = DataFlow::moduleImport("basic-auth-connect").getAnInvocation().asExpr() and + exists(DataFlow::CallNode call | + call = DataFlow::moduleImport("basic-auth-connect").getAnInvocation() and call.getNumArgument() = 2 | this = call.getArgument(0) and kind = "user name" @@ -108,22 +118,24 @@ module Connect { override string getCredentialsKind() { result = kind } } - class RequestExpr = NodeJSLib::RequestExpr; + deprecated class RequestExpr = NodeJSLib::RequestExpr; + + class RequestNode = NodeJSLib::RequestNode; /** * An access to a user-controlled Connect request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess { - RequestExpr request; + private class RequestInputAccess extends HTTP::RequestInputAccess instanceof DataFlow::MethodCallNode { + RequestNode request; string kind; RequestInputAccess() { request.getRouteHandler() instanceof StandardRouteHandler and - exists(PropAccess cookies | + exists(DataFlow::PropRead cookies | // `req.cookies.get()` kind = "cookie" and cookies.accesses(request, "cookies") and - this.asExpr().(MethodCallExpr).calls(cookies, "get") + super.calls(cookies, "get") ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll index 489fcf550c41..f0ea2f03f683 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll @@ -52,7 +52,7 @@ module ConnectExpressShared { /** * Holds if `function` appears to match the given signature based on parameter naming. */ - private predicate matchesSignature(Function function, RouteHandlerSignature sig) { + private predicate matchesSignature(DataFlow::FunctionNode function, RouteHandlerSignature sig) { function.getNumParameter() = sig.getArity() and function.getParameter(sig.getParameterIndex("request")).getName() = ["req", "request"] and function.getParameter(sig.getParameterIndex("response")).getName() = ["res", "response"] and @@ -71,8 +71,8 @@ module ConnectExpressShared { * so the caller should restrict the function accordingly. */ pragma[inline] - private Parameter getRouteHandlerParameter( - Function routeHandler, RouteHandlerSignature sig, string kind + private DataFlow::ParameterNode getRouteHandlerParameter( + DataFlow::FunctionNode routeHandler, RouteHandlerSignature sig, string kind ) { result = routeHandler.getParameter(sig.getParameterIndex(kind)) } @@ -83,7 +83,9 @@ module ConnectExpressShared { * `kind` is one of: "error", "request", "response", "next". */ pragma[inline] - Parameter getRouteParameterHandlerParameter(Function routeHandler, string kind) { + DataFlow::ParameterNode getRouteParameterHandlerParameter( + DataFlow::FunctionNode routeHandler, string kind + ) { result = getRouteHandlerParameter(routeHandler, RouteHandlerSignature::requestResponseNextParameter(), kind) @@ -95,7 +97,7 @@ module ConnectExpressShared { * `kind` is one of: "error", "request", "response", "next". */ pragma[inline] - Parameter getRouteHandlerParameter(Function routeHandler, string kind) { + DataFlow::ParameterNode getRouteHandlerParameter(DataFlow::FunctionNode routeHandler, string kind) { if routeHandler.getNumParameter() = 4 then // For arity 4 there is ambiguity between (err, req, res, next) and (req, res, next, param) @@ -115,7 +117,7 @@ module ConnectExpressShared { */ class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate { RouteHandlerCandidate() { - matchesSignature(astNode, _) and + matchesSignature(this, _) and not ( // heuristic: not a class method (the server invokes this with a function call) astNode = any(MethodDefinition def).getBody() diff --git a/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll b/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll index 77bfff9f3882..1efc7da5dc49 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll @@ -76,7 +76,7 @@ private predicate canHaveSensitiveCookie(DataFlow::Node node) { HeuristicNames::nameIndicatesSensitiveData([s, getCookieName(s)], _) ) or - node.asExpr() instanceof SensitiveExpr + node instanceof SensitiveNode } /** @@ -271,30 +271,27 @@ private module ExpressCookies { /** * A cookie set using `response.cookie` from `express` module (https://expressjs.com/en/api.html#res.cookie). */ - private class InsecureExpressCookieResponse extends CookieWrites::CookieWrite, - DataFlow::MethodCallNode { - InsecureExpressCookieResponse() { this.asExpr() instanceof Express::SetCookie } - + private class InsecureExpressCookieResponse extends CookieWrites::CookieWrite instanceof Express::SetCookie { override predicate isSecure() { // A cookie is secure if there are cookie options with the `secure` flag set to `true`. // The default is `false`. - exists(DataFlow::Node value | value = this.getOptionArgument(2, CookieWrites::secure()) | + exists(DataFlow::Node value | value = super.getOptionArgument(2, CookieWrites::secure()) | not value.mayHaveBooleanValue(false) // anything but `false` is accepted as being maybe true ) } - override predicate isSensitive() { canHaveSensitiveCookie(this.getArgument(0)) } + override predicate isSensitive() { canHaveSensitiveCookie(super.getArgument(0)) } override predicate isHttpOnly() { // A cookie is httpOnly if there are cookie options with the `httpOnly` flag set to `true`. // The default is `false`. - exists(DataFlow::Node value | value = this.getOptionArgument(2, CookieWrites::httpOnly()) | + exists(DataFlow::Node value | value = super.getOptionArgument(2, CookieWrites::httpOnly()) | not value.mayHaveBooleanValue(false) // anything but `false` is accepted as being maybe true ) } override string getSameSite() { - result = getSameSiteValue(this.getOptionArgument(2, "sameSite")) + result = getSameSiteValue(super.getOptionArgument(2, "sameSite")) } } @@ -372,10 +369,10 @@ private class HttpCookieWrite extends CookieWrites::CookieWrite { HttpCookieWrite() { exists(HTTP::CookieDefinition setCookie | - this.asExpr() = setCookie.getHeaderArgument() and + this = setCookie.getHeaderArgument() and not this instanceof DataFlow::ArrayCreationNode or - this = setCookie.getHeaderArgument().flow().(DataFlow::ArrayCreationNode).getAnElement() + this = setCookie.getHeaderArgument().(DataFlow::ArrayCreationNode).getAnElement() ) and header = [ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll b/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll index 164bc6e8f88a..ad27a0fe8289 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll @@ -6,10 +6,27 @@ import javascript /** + * DEPRECATED: Use `CredentialsNode` instead. * An expression whose value is used to supply credentials such * as a user name, a password, or a key. */ -abstract class CredentialsExpr extends Expr { +deprecated class CredentialsExpr extends Expr { + CredentialsNode node; + + CredentialsExpr() { node.asExpr() = this } + + /** + * Gets a description of the kind of credential this expression is used as, + * such as `"user name"`, `"password"`, `"key"`. + */ + deprecated string getCredentialsKind() { result = node.getCredentialsKind() } +} + +/** + * An expression whose value is used to supply credentials such + * as a user name, a password, or a key. + */ +abstract class CredentialsNode extends DataFlow::Node { /** * Gets a description of the kind of credential this expression is used as, * such as `"user name"`, `"password"`, `"key"`. @@ -17,12 +34,10 @@ abstract class CredentialsExpr extends Expr { abstract string getCredentialsKind(); } -private class CredentialsFromModel extends CredentialsExpr { +private class CredentialsFromModel extends CredentialsNode { string kind; - CredentialsFromModel() { - this = ModelOutput::getASinkNode("credentials[" + kind + "]").asSink().asExpr() - } + CredentialsFromModel() { this = ModelOutput::getASinkNode("credentials[" + kind + "]").asSink() } override string getCredentialsKind() { result = kind } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll b/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll index 9dcd4d9fbb94..9cf4dcfaacea 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/CryptoLibraries.qll @@ -8,11 +8,11 @@ import semmle.javascript.security.CryptoAlgorithms /** * An application of a cryptographic algorithm. */ -abstract class CryptographicOperation extends Expr { +abstract class CryptographicOperation extends DataFlow::Node { /** * Gets the input the algorithm is used on, e.g. the plain text input to be encrypted. */ - abstract Expr getInput(); + abstract DataFlow::Node getInput(); /** * Gets the applied algorithm. @@ -46,11 +46,9 @@ abstract class CryptographicKeyCreation extends DataFlow::Node { } /** - * A key used in a cryptographic algorithm, viewed as a `CredentialsExpr`. + * A key used in a cryptographic algorithm, viewed as a `CredentialsNode`. */ -class CryptographicKeyCredentialsExpr extends CredentialsExpr { - CryptographicKeyCredentialsExpr() { this = any(CryptographicKey k).asExpr() } - +class CryptographicKeyCredentialsExpr extends CredentialsNode instanceof CryptographicKey { override string getCredentialsKind() { result = "key" } } @@ -58,8 +56,8 @@ class CryptographicKeyCredentialsExpr extends CredentialsExpr { * A model of the asmCrypto library. */ private module AsmCrypto { - private class Apply extends CryptographicOperation { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; // non-functional Apply() { @@ -73,17 +71,15 @@ private module AsmCrypto { * ``` */ - exists(DataFlow::CallNode mce | this = mce.asExpr() | - exists(DataFlow::SourceNode asmCrypto, string algorithmName | - asmCrypto = DataFlow::globalVarRef("asmCrypto") and - algorithm.matchesName(algorithmName) and - mce = asmCrypto.getAPropertyRead(algorithmName).getAMemberCall(_) and - input = mce.getAnArgument().asExpr() - ) + exists(DataFlow::SourceNode asmCrypto, string algorithmName | + asmCrypto = DataFlow::globalVarRef("asmCrypto") and + algorithm.matchesName(algorithmName) and + this = asmCrypto.getAPropertyRead(algorithmName).getAMemberCall(_) and + input = this.getAnArgument() ) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -97,9 +93,8 @@ private module BrowserIdCrypto { Key() { this = any(Apply apply).getKey() } } - private class Apply extends CryptographicOperation { + private class Apply extends CryptographicOperation instanceof DataFlow::MethodCallNode { CryptographicAlgorithm algorithm; // non-functional - MethodCallExpr mce; Apply() { /* @@ -118,7 +113,6 @@ private module BrowserIdCrypto { * ``` */ - this = mce and exists( DataFlow::SourceNode mod, DataFlow::Node algorithmNameNode, DataFlow::CallNode keygen, DataFlow::FunctionNode callback @@ -128,15 +122,15 @@ private module BrowserIdCrypto { algorithmNameNode = keygen.getOptionArgument(0, "algorithm") and algorithm.matchesName(algorithmNameNode.getStringValue()) and callback = keygen.getCallback(1) and - this = mod.getAMemberCall("sign").asExpr() + this = mod.getAMemberCall("sign") ) } - override Expr getInput() { result = mce.getArgument(0) } + override DataFlow::Node getInput() { result = super.getArgument(0) } override CryptographicAlgorithm getAlgorithm() { result = algorithm } - DataFlow::Node getKey() { result.asExpr() = mce.getArgument(1) } + DataFlow::Node getKey() { result = super.getArgument(1) } } } @@ -217,14 +211,12 @@ private module NodeJSCrypto { override predicate isSymmetricKey() { none() } } - private class Apply extends CryptographicOperation, MethodCallExpr { + private class Apply extends CryptographicOperation instanceof DataFlow::MethodCallNode { InstantiatedAlgorithm instantiation; - Apply() { - this = instantiation.getAMethodCall(any(string m | m = "update" or m = "write")).asExpr() - } + Apply() { this = instantiation.getAMethodCall(any(string m | m = "update" or m = "write")) } - override Expr getInput() { result = this.getArgument(0) } + override DataFlow::Node getInput() { result = super.getArgument(0) } override CryptographicAlgorithm getAlgorithm() { result = instantiation.getAlgorithm() } } @@ -260,7 +252,7 @@ private module CryptoJS { /** * Matches `CryptoJS.` and `require("crypto-js/")` */ - private DataFlow::SourceNode getAlgorithmExpr(CryptographicAlgorithm algorithm) { + private DataFlow::SourceNode getAlgorithmNode(CryptographicAlgorithm algorithm) { exists(string algorithmName | algorithm.matchesName(algorithmName) | exists(DataFlow::SourceNode mod | mod = DataFlow::moduleImport("crypto-js") | result = mod.getAPropertyRead(algorithmName) or @@ -274,7 +266,9 @@ private module CryptoJS { ) } - private DataFlow::CallNode getEncryptionApplication(Expr input, CryptographicAlgorithm algorithm) { + private DataFlow::CallNode getEncryptionApplication( + DataFlow::Node input, CryptographicAlgorithm algorithm + ) { /* * ``` * var CryptoJS = require("crypto-js"); @@ -288,11 +282,13 @@ private module CryptoJS { * Also matches where `CryptoJS.` has been replaced by `require("crypto-js/")` */ - result = getAlgorithmExpr(algorithm).getAMemberCall("encrypt") and - input = result.getArgument(0).asExpr() + result = getAlgorithmNode(algorithm).getAMemberCall("encrypt") and + input = result.getArgument(0) } - private DataFlow::CallNode getDirectApplication(Expr input, CryptographicAlgorithm algorithm) { + private DataFlow::CallNode getDirectApplication( + DataFlow::Node input, CryptographicAlgorithm algorithm + ) { /* * ``` * var CryptoJS = require("crypto-js"); @@ -307,20 +303,20 @@ private module CryptoJS { * Also matches where `CryptoJS.` has been replaced by `require("crypto-js/")` */ - result = getAlgorithmExpr(algorithm).getACall() and - input = result.getArgument(0).asExpr() + result = getAlgorithmNode(algorithm).getACall() and + input = result.getArgument(0) } private class Apply extends CryptographicOperation { - Expr input; + DataFlow::Node input; CryptographicAlgorithm algorithm; // non-functional Apply() { - this = getEncryptionApplication(input, algorithm).asExpr() or - this = getDirectApplication(input, algorithm).asExpr() + this = getEncryptionApplication(input, algorithm) or + this = getDirectApplication(input, algorithm) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -328,7 +324,7 @@ private module CryptoJS { private class Key extends CryptographicKey { Key() { exists(DataFlow::SourceNode e, CryptographicAlgorithm algorithm | - e = getAlgorithmExpr(algorithm) + e = getAlgorithmNode(algorithm) | exists(string name | name = "encrypt" or @@ -351,7 +347,7 @@ private module CryptoJS { CreateKey() { // var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); this = - getAlgorithmExpr(any(CryptographicAlgorithm algo | algo.getName() = algorithm)).getACall() and + getAlgorithmNode(any(CryptographicAlgorithm algo | algo.getName() = algorithm)).getACall() and optionArg = 2 or // var key = CryptoJS.algo.PBKDF2.create({ keySize: 8 }); @@ -378,8 +374,8 @@ private module CryptoJS { * A model of the TweetNaCl library. */ private module TweetNaCl { - private class Apply extends CryptographicOperation instanceof MethodCallExpr { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; Apply() { @@ -400,12 +396,12 @@ private module TweetNaCl { name = "sign" and algorithm.matchesName("ed25519") | (mod = DataFlow::moduleImport("nacl") or mod = DataFlow::moduleImport("nacl-fast")) and - this = mod.getAMemberCall(name).asExpr() and + this = mod.getAMemberCall(name) and super.getArgument(0) = input ) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -421,7 +417,7 @@ private module HashJs { * - `require("hash.js/lib/hash/")`() * - `require("hash.js/lib/hash/sha/")`() */ - private DataFlow::CallNode getAlgorithmExpr(CryptographicAlgorithm algorithm) { + private DataFlow::CallNode getAlgorithmNode(CryptographicAlgorithm algorithm) { exists(string algorithmName | algorithm.matchesName(algorithmName) | result = DataFlow::moduleMember("hash.js", algorithmName).getACall() or @@ -438,8 +434,8 @@ private module HashJs { ) } - private class Apply extends CryptographicOperation instanceof MethodCallExpr { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; // non-functional Apply() { @@ -456,11 +452,11 @@ private module HashJs { * Also matches where `hash.()` has been replaced by a more specific require a la `require("hash.js/lib/hash/sha/512")` */ - this = getAlgorithmExpr(algorithm).getAMemberCall("update").asExpr() and + this = getAlgorithmNode(algorithm).getAMemberCall("update") and input = super.getArgument(0) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -492,7 +488,7 @@ private module Forge { // `require('forge').cipher.createCipher("3DES-CBC").update("secret", "key");` (createName = "createCipher" or createName = "createDecipher") and this = mod.getAPropertyRead("cipher").getAMemberCall(createName) and - this.getArgument(0).asExpr().mayHaveStringValue(cipherName) and + this.getArgument(0).mayHaveStringValue(cipherName) and cipherName = cipherPrefix + "-" + cipherSuffix and cipherSuffix = ["CBC", "CFB", "CTR", "ECB", "GCM", "OFB"] and algorithmName = cipherPrefix and @@ -531,19 +527,19 @@ private module Forge { override CryptographicAlgorithm getAlgorithm() { result = algorithm } } - private class Apply extends CryptographicOperation instanceof MethodCallExpr { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; // non-functional Apply() { exists(Cipher cipher | - this = cipher.getAMemberCall("update").asExpr() and + this = cipher.getAMemberCall("update") and super.getArgument(0) = input and algorithm = cipher.getAlgorithm() ) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -590,8 +586,8 @@ private module Forge { * A model of the md5 library. */ private module Md5 { - private class Apply extends CryptographicOperation instanceof CallExpr { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; Apply() { @@ -599,12 +595,12 @@ private module Md5 { exists(DataFlow::SourceNode mod | mod = DataFlow::moduleImport("md5") and algorithm.matchesName("MD5") and - this = mod.getACall().asExpr() and + this = mod.getACall() and super.getArgument(0) = input ) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -614,8 +610,8 @@ private module Md5 { * A model of the bcrypt, bcryptjs, bcrypt-nodejs libraries. */ private module Bcrypt { - private class Apply extends CryptographicOperation instanceof MethodCallExpr { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; Apply() { @@ -632,12 +628,12 @@ private module Bcrypt { methodName = "hashSync" ) and mod = DataFlow::moduleImport(moduleName) and - this = mod.getAMemberCall(methodName).asExpr() and + this = mod.getAMemberCall(methodName) and super.getArgument(0) = input ) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } @@ -647,23 +643,23 @@ private module Bcrypt { * A model of the hasha library. */ private module Hasha { - private class Apply extends CryptographicOperation instanceof CallExpr { - Expr input; + private class Apply extends CryptographicOperation instanceof DataFlow::CallNode { + DataFlow::Node input; CryptographicAlgorithm algorithm; Apply() { // `require('hasha')('unicorn', { algorithm: "md5" });` - exists(DataFlow::SourceNode mod, string algorithmName, Expr algorithmNameNode | + exists(DataFlow::SourceNode mod, string algorithmName, DataFlow::Node algorithmNameNode | mod = DataFlow::moduleImport("hasha") and - this = mod.getACall().asExpr() and + this = mod.getACall() and super.getArgument(0) = input and algorithm.matchesName(algorithmName) and - super.hasOptionArgument(1, "algorithm", algorithmNameNode) and + super.getOptionArgument(1, "algorithm") = algorithmNameNode and algorithmNameNode.mayHaveStringValue(algorithmName) ) } - override Expr getInput() { result = input } + override DataFlow::Node getInput() { result = input } override CryptographicAlgorithm getAlgorithm() { result = algorithm } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/DigitalOcean.qll b/javascript/ql/lib/semmle/javascript/frameworks/DigitalOcean.qll index 76077c930236..60d96a937c9c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/DigitalOcean.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/DigitalOcean.qll @@ -8,12 +8,12 @@ module DigitalOcean { /** * An expression that is used for authentication at DigitalOcean: `digitalocean.client()`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { - exists(CallExpr mce | - mce = DataFlow::moduleMember("digitalocean", "client").getACall().asExpr() + exists(DataFlow::CallNode mce | + mce = DataFlow::moduleMember("digitalocean", "client").getACall() | this = mce.getArgument(0) and kind = "token" ) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index 196165307631..86abe01f5d66 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -40,31 +40,27 @@ module Express { ) } - /** - * Holds if `e` may refer to the given `router` object. - */ - private predicate isRouter(Expr e, RouterDefinition router) { router.flowsTo(e) } + /** Holds if `e` may refer to the given `router` object. */ + private predicate isRouter(DataFlow::Node e, RouterDefinition router) { router.ref().flowsTo(e) } /** * Holds if `e` may refer to a router object. */ - private predicate isRouter(Expr e) { + private predicate isRouter(DataFlow::Node e) { isRouter(e, _) or - e.getType().hasUnderlyingType("express", "Router") + e.asExpr().getType().hasUnderlyingType("express", "Router") or // created by `webpack-dev-server` - WebpackDevServer::webpackDevServerApp().flowsToExpr(e) + WebpackDevServer::webpackDevServerApp().flowsTo(e) } /** + * DEPRECATED: Use `RouterDefinition.ref()` or `RouteSetup` instead. * An expression that refers to a route. */ - class RouteExpr extends MethodCallExpr { - RouteExpr() { isRouter(this) } - - /** Gets the router from which this route was created, if it is known. */ - RouterDefinition getRouter() { isRouter(this, result) } + deprecated class RouteExpr extends MethodCallExpr { + RouteExpr() { isRouter(this.flow()) } } /** @@ -83,13 +79,13 @@ module Express { private class RouterRange extends Routing::Router::Range { RouterDefinition def; - RouterRange() { this = def.flow() } + RouterRange() { this = def } override DataFlow::SourceNode getAReference() { result = def.ref() } } private class RoutingTreeSetup extends Routing::RouteSetup::MethodCall { - RoutingTreeSetup() { this.asExpr() instanceof RouteSetup } + RoutingTreeSetup() { this instanceof RouteSetup } override string getRelativePath() { not this.getMethodName() = "param" and // do not treat parameter name as a path @@ -140,7 +136,7 @@ module Express { /** * A call to an Express router method that sets up a route. */ - class RouteSetup extends HTTP::Servers::StandardRouteSetup, MethodCallExpr { + class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode { RouteSetup() { isRouter(this.getReceiver()) and this.getMethodName() = routeSetupMethodName() @@ -156,12 +152,23 @@ module Express { predicate isUseCall() { this.getMethodName() = "use" } /** + * DEPRECATED: Use `getRouteHandlerNode` instead. * Gets the `n`th handler registered by this setup, with 0 being the first. * * This differs from `getARouteHandler` in that the argument expression is * returned, not its dataflow source. */ - Expr getRouteHandlerExpr(int index) { + deprecated Expr getRouteHandlerExpr(int index) { + result = this.getRouteHandlerNode(index).asExpr() + } + + /** + * Gets the `n`th handler registered by this setup, with 0 being the first. + * + * This differs from `getARouteHandler` in that the argument expression is + * returned, not its dataflow source. + */ + DataFlow::Node getRouteHandlerNode(int index) { // The first argument is a URI pattern if it is a string. If it could possibly be // a function, we consider it to be a route handler, otherwise a URI pattern. exists(AnalyzedNode firstArg | firstArg = this.getArgument(0).analyze() | @@ -173,21 +180,39 @@ module Express { ) } - /** Gets an argument that represents a route handler being registered. */ - Expr getARouteHandlerExpr() { result = this.getRouteHandlerExpr(_) } + /** + * DEPRECATED: Use `getARouteHandlerNode` instead. + * Gets an argument that represents a route handler being registered. + */ + deprecated Expr getARouteHandlerExpr() { result = this.getRouteHandlerExpr(_) } + + /** + * Gets an argument that represents a route handler being registered. + */ + DataFlow::Node getARouteHandlerNode() { result = this.getRouteHandlerNode(_) } - /** Gets the last argument representing a route handler being registered. */ - Expr getLastRouteHandlerExpr() { + /** + * DEPRECATED: Use `getLastRouteHandlerExpr` instead. + * Gets the last argument representing a route handler being registered. + */ + deprecated Expr getLastRouteHandlerExpr() { result = max(int i | | this.getRouteHandlerExpr(i) order by i) } + /** + * Gets the last argument representing a route handler being registered. + */ + DataFlow::Node getLastRouteHandlerNode() { + result = max(int i | | this.getRouteHandlerNode(i) order by i) + } + override DataFlow::SourceNode getARouteHandler() { result = this.getARouteHandler(DataFlow::TypeBackTracker::end()) } private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) { t.start() and - result = this.getARouteHandlerExpr().flow().getALocalSource() + result = this.getARouteHandlerNode().getALocalSource() or exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode succ | succ = this.getARouteHandler(t2) @@ -199,7 +224,9 @@ module Express { ) } - override Expr getServer() { result.(Application).getARouteHandler() = this.getARouteHandler() } + override DataFlow::Node getServer() { + result.(Application).getARouteHandler() = this.getARouteHandler() + } /** * Gets the HTTP request type this is registered for, if any. @@ -233,16 +260,16 @@ module Express { /** * A call that sets up a Passport router that includes the request object. */ - private class PassportRouteSetup extends HTTP::Servers::StandardRouteSetup, CallExpr { + private class PassportRouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode { DataFlow::ModuleImportNode importNode; DataFlow::FunctionNode callback; // looks for this pattern: passport.use(new Strategy({passReqToCallback: true}, callback)) PassportRouteSetup() { importNode = DataFlow::moduleImport("passport") and - this = importNode.getAMemberCall("use").asExpr() and + this = importNode.getAMemberCall("use") and exists(DataFlow::NewNode strategy | - strategy.flowsToExpr(this.getArgument(0)) and + strategy.flowsTo(this.getArgument(0)) and strategy.getNumArgument() = 2 and // new Strategy({passReqToCallback: true}, ...) strategy.getOptionArgument(0, "passReqToCallback").mayHaveBooleanValue(true) and @@ -250,7 +277,7 @@ module Express { ) } - override Expr getServer() { result = importNode.asExpr() } + override DataFlow::Node getServer() { result = importNode } override DataFlow::SourceNode getARouteHandler() { result = callback } } @@ -259,15 +286,59 @@ module Express { * The callback given to passport in PassportRouteSetup. */ private class PassportRouteHandler extends RouteHandler, HTTP::Servers::StandardRouteHandler, - DataFlow::ValueNode { - override Function astNode; - + DataFlow::FunctionNode { PassportRouteHandler() { this = any(PassportRouteSetup setup).getARouteHandler() } - override Parameter getRouteHandlerParameter(string kind) { + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { kind = "request" and - result = astNode.getParameter(0) + result = this.getParameter(0) + } + } + + /** + * DEPRECATED: Use `RouteHandlerNode` instead. + * An expression used as an Express route handler, such as `submitHandler` below: + * ``` + * app.post('/submit', submitHandler) + * ``` + * + * Unlike `RouterHandler`, this is the argument passed to a setup, as opposed to + * a function that flows into such an argument. + */ + deprecated class RouteHandlerExpr extends Expr { + RouteHandlerNode node; + + RouteHandlerExpr() { this.flow() = node } + + /** Gets the setup call that registers this route handler. */ + deprecated RouteSetup getSetup() { result = node.getSetup() } + + /** Gets the function body of this handler, if it is defined locally. */ + deprecated RouteHandler getBody() { result = node.getBody() } + + /** Holds if this is not followed by more handlers. */ + deprecated predicate isLastHandler() { node.isLastHandler() } + + /** Gets a route handler that immediately precedes this in the route stack. */ + deprecated Express::RouteHandlerExpr getPreviousMiddleware() { + result = node.getPreviousMiddleware().asExpr() + } + + /** Gets a route handler that may follow immediately after this one in its route stack. */ + deprecated Express::RouteHandlerExpr getNextMiddleware() { + result = node.getNextMiddleware().asExpr() } + + /** + * Gets a route handler that precedes this one (not necessarily immediately), may handle + * same request method, and matches on the same path or a prefix. + */ + deprecated Express::RouteHandlerExpr getAMatchingAncestor() { + result = node.getAMatchingAncestor().asExpr() + } + + /** Gets the router being registered as a sub-router here, if any. */ + deprecated RouterDefinition getAsSubRouter() { result = node.getAsSubRouter() } } /** @@ -279,11 +350,11 @@ module Express { * Unlike `RouterHandler`, this is the argument passed to a setup, as opposed to * a function that flows into such an argument. */ - class RouteHandlerExpr extends Expr { + class RouteHandlerNode extends DataFlow::Node { RouteSetup setup; int index; - RouteHandlerExpr() { this = setup.getRouteHandlerExpr(index) } + RouteHandlerNode() { this = setup.getRouteHandlerNode(index) } /** * Gets the setup call that registers this route handler. @@ -294,7 +365,7 @@ module Express { * Gets the function body of this handler, if it is defined locally. */ RouteHandler getBody() { - exists(DataFlow::SourceNode source | source = this.flow().getALocalSource() | + exists(DataFlow::SourceNode source | source = this.getALocalSource() | result = source or DataFlow::functionOneWayForwardingStep(result.(DataFlow::SourceNode).getALocalUse(), source) @@ -306,7 +377,7 @@ module Express { */ predicate isLastHandler() { not setup.isUseCall() and - not exists(setup.getRouteHandlerExpr(index + 1)) + not exists(setup.getRouteHandlerNode(index + 1)) } /** @@ -331,10 +402,11 @@ module Express { * In this case, the previous from `foo` is `auth` although they do not act on the * same requests. */ - Express::RouteHandlerExpr getPreviousMiddleware() { - index = 0 and result = setup.getRouter().getMiddlewareStackAt(setup.getAPredecessor()) + Express::RouteHandlerNode getPreviousMiddleware() { + index = 0 and + result = setup.getRouter().getMiddlewareStackAt(setup.asExpr().getAPredecessor()) or - index > 0 and result = setup.getRouteHandlerExpr(index - 1) + index > 0 and result = setup.getRouteHandlerNode(index - 1) or // Outside the router's original container, use the flow-insensitive model of its middleware stack. // Its state is not tracked to CFG nodes outside its original container. @@ -348,7 +420,7 @@ module Express { /** * Gets a route handler that may follow immediately after this one in its route stack. */ - Express::RouteHandlerExpr getNextMiddleware() { result.getPreviousMiddleware() = this } + Express::RouteHandlerNode getNextMiddleware() { result.getPreviousMiddleware() = this } /** * Gets a route handler that precedes this one (not necessarily immediately), may handle @@ -361,7 +433,7 @@ module Express { * router installs a route handler `r1` on a path that matches the path of a route handler * `r2` installed on a subrouter, `r1` will not be recognized as an ancestor of `r2`. */ - Express::RouteHandlerExpr getAMatchingAncestor() { + Express::RouteHandlerNode getAMatchingAncestor() { result = this.getPreviousMiddleware+() and exists(RouteSetup resSetup | resSetup = result.getSetup() | // check whether request methods are compatible @@ -378,7 +450,7 @@ module Express { or // if this is a sub-router, any previously installed middleware for the same // request method will necessarily match - exists(RouteHandlerExpr outer | + exists(RouteHandlerNode outer | setup.getRouter() = outer.getAsSubRouter() and outer.getSetup().handlesSameRequestMethodAs(setup) and result = outer.getAMatchingAncestor() @@ -404,46 +476,51 @@ module Express { * * `kind` is one of: "error", "request", "response", "next", or "parameter". */ - abstract Parameter getRouteHandlerParameter(string kind); + abstract DataFlow::ParameterNode getRouteHandlerParameter(string kind); /** * Gets the parameter of the route handler that contains the request object. */ - Parameter getRequestParameter() { result = this.getRouteHandlerParameter("request") } + DataFlow::ParameterNode getRequestParameter() { + result = this.getRouteHandlerParameter("request") + } /** * Gets the parameter of the route handler that contains the response object. */ - Parameter getResponseParameter() { result = this.getRouteHandlerParameter("response") } + DataFlow::ParameterNode getResponseParameter() { + result = this.getRouteHandlerParameter("response") + } /** * Gets a request body access of this handler. */ - Expr getARequestBodyAccess() { result.(PropAccess).accesses(this.getARequestExpr(), "body") } + DataFlow::PropRead getARequestBodyAccess() { result.accesses(this.getARequestNode(), "body") } } /** * An Express route handler installed by a route setup. */ class StandardRouteHandler extends RouteHandler, HTTP::Servers::StandardRouteHandler, - DataFlow::ValueNode { - override Function astNode; + DataFlow::FunctionNode { RouteSetup routeSetup; StandardRouteHandler() { this = routeSetup.getARouteHandler() } - override Parameter getRouteHandlerParameter(string kind) { + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { if routeSetup.isParameterHandler() - then result = getRouteParameterHandlerParameter(astNode, kind) - else result = getRouteHandlerParameter(astNode, kind) + then result = getRouteParameterHandlerParameter(this, kind) + else result = getRouteHandlerParameter(this, kind) } } /** * Holds if `call` is a chainable method call on the response object of `handler`. */ - private predicate isChainableResponseMethodCall(RouteHandler handler, MethodCallExpr call) { - exists(string name | call.calls(handler.getAResponseExpr(), name) | + private predicate isChainableResponseMethodCall( + RouteHandler handler, DataFlow::MethodCallNode call + ) { + exists(string name | call.calls(handler.getAResponseNode(), name) | name = [ "append", "attachment", "location", "send", "sendStatus", "set", "status", "type", "vary", @@ -463,9 +540,9 @@ module Express { RouteHandler rh; ExplicitResponseSource() { - this = DataFlow::parameterNode(rh.getResponseParameter()) + this = rh.getResponseParameter() or - isChainableResponseMethodCall(rh, this.asExpr()) + isChainableResponseMethodCall(rh, this) } /** @@ -493,7 +570,7 @@ module Express { private class ExplicitRequestSource extends RequestSource { RouteHandler rh; - ExplicitRequestSource() { this = DataFlow::parameterNode(rh.getRequestParameter()) } + ExplicitRequestSource() { this = rh.getRequestParameter() } /** * Gets the route handler that handles this request. @@ -511,16 +588,32 @@ module Express { } /** + * DEPRECATED: Use `ResponseNode` instead. * An Express response expression. */ - class ResponseExpr extends NodeJSLib::ResponseExpr { + deprecated class ResponseExpr extends NodeJSLib::ResponseExpr { + ResponseExpr() { this.flow() instanceof ResponseNode } + } + + /** + * An Express response expression. + */ + class ResponseNode extends NodeJSLib::ResponseNode { override ResponseSource src; } /** + * DEPRECATED: Use `RequestNode` instead. * An Express request expression. */ - class RequestExpr extends NodeJSLib::RequestExpr { + deprecated class RequestExpr extends NodeJSLib::RequestExpr { + RequestExpr() { this.flow() instanceof RequestNode } + } + + /** + * An Express request expression. + */ + class RequestNode extends NodeJSLib::RequestNode { override RequestSource src; } @@ -544,7 +637,7 @@ module Express { ParamHandlerInputAccess() { exists(RouteSetup setup | rh = setup.getARouteHandler() | - this = DataFlow::parameterNode(rh.getRouteHandlerParameter("parameter")) + this = rh.getRouteHandlerParameter("parameter") ) } @@ -674,35 +767,35 @@ module Express { /** * Holds if `e` is an HTTP request object. */ - predicate isRequest(Expr e) { any(RouteHandler rh).getARequestExpr() = e } + predicate isRequest(DataFlow::Node e) { any(RouteHandler rh).getARequestNode() = e } /** * Holds if `e` is an HTTP response object. */ - predicate isResponse(Expr e) { any(RouteHandler rh).getAResponseExpr() = e } + predicate isResponse(DataFlow::Node e) { any(RouteHandler rh).getAResponseNode() = e } /** * An access to the HTTP request body. */ - class RequestBodyAccess extends Expr { + class RequestBodyAccess extends DataFlow::Node { RequestBodyAccess() { any(RouteHandler h).getARequestBodyAccess() = this } } abstract private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { - HeaderDefinition() { isResponse(astNode.getReceiver()) } + HeaderDefinition() { isResponse(this.getReceiver()) } - override RouteHandler getRouteHandler() { astNode.getReceiver() = result.getAResponseExpr() } + override RouteHandler getRouteHandler() { this.getReceiver() = result.getAResponseNode() } } /** * An invocation of the `redirect` method of an HTTP response object. */ - private class RedirectInvocation extends HTTP::RedirectInvocation, MethodCallExpr { + private class RedirectInvocation extends HTTP::RedirectInvocation, DataFlow::MethodCallNode { ResponseSource response; - RedirectInvocation() { this = response.ref().getAMethodCall("redirect").asExpr() } + RedirectInvocation() { this = response.ref().getAMethodCall("redirect") } - override Expr getUrlArgument() { result = this.getLastArgument() } + override DataFlow::Node getUrlArgument() { result = this.getLastArgument() } override RouteHandler getRouteHandler() { result = response.getRouteHandler() } } @@ -713,8 +806,8 @@ module Express { */ private class SetOneHeader extends HeaderDefinition { SetOneHeader() { - astNode.getMethodName() = any(string n | n = "set" or n = "header") and - astNode.getNumArgument() = 2 + this.getMethodName() = any(string n | n = "set" or n = "header") and + this.getNumArgument() = 2 } } @@ -735,18 +828,18 @@ module Express { */ private DataFlow::SourceNode getAHeaderSource() { result.flowsTo(this.getArgument(0)) } - override predicate definesExplicitly(string headerName, Expr headerValue) { + override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) { exists(string header | - this.getAHeaderSource().hasPropertyWrite(header, DataFlow::valueNode(headerValue)) and + this.getAHeaderSource().hasPropertyWrite(header, headerValue) and headerName = header.toLowerCase() ) } override RouteHandler getRouteHandler() { result = response.getRouteHandler() } - override Expr getNameExpr() { + override DataFlow::Node getNameNode() { exists(DataFlow::PropWrite write | this.getAHeaderSource().getAPropertyWrite() = write | - result = write.getPropertyNameExpr() + result = write.getPropertyNameExpr().flow() ) } } @@ -755,7 +848,7 @@ module Express { * An invocation of the `append` method on an HTTP response object. */ private class AppendHeader extends HeaderDefinition { - AppendHeader() { astNode.getMethodName() = "append" } + AppendHeader() { this.getMethodName() = "append" } } /** @@ -764,7 +857,7 @@ module Express { private class ResponseSendArgument extends HTTP::ResponseSendArgument { ResponseSource response; - ResponseSendArgument() { this = response.ref().getAMethodCall("send").getArgument(0).asExpr() } + ResponseSendArgument() { this = response.ref().getAMethodCall("send").getArgument(0) } override RouteHandler getRouteHandler() { result = response.getRouteHandler() } } @@ -772,14 +865,14 @@ module Express { /** * An invocation of the `cookie` method on an HTTP response object. */ - class SetCookie extends HTTP::CookieDefinition, MethodCallExpr { + class SetCookie extends HTTP::CookieDefinition, DataFlow::MethodCallNode { ResponseSource response; - SetCookie() { this = response.ref().getAMethodCall("cookie").asExpr() } + SetCookie() { this = response.ref().getAMethodCall("cookie") } - override Expr getNameArgument() { result = this.getArgument(0) } + override DataFlow::Node getNameArgument() { result = this.getArgument(0) } - override Expr getValueArgument() { result = this.getArgument(1) } + override DataFlow::Node getValueArgument() { result = this.getArgument(1) } override RouteHandler getRouteHandler() { result = response.getRouteHandler() } } @@ -792,7 +885,7 @@ module Express { TemplateObjectInput obj; TemplateInput() { - obj.getALocalSource().(DataFlow::ObjectLiteralNode).hasPropertyWrite(_, this.flow()) + obj.getALocalSource().(DataFlow::ObjectLiteralNode).hasPropertyWrite(_, this) } override RouteHandler getRouteHandler() { result = obj.getRouteHandler() } @@ -821,7 +914,7 @@ module Express { * An Express server application. */ private class Application extends HTTP::ServerDefinition { - Application() { this = appCreation().asExpr() } + Application() { this = appCreation() } /** * Gets a route handler of the application, regardless of nesting. @@ -831,15 +924,13 @@ module Express { } } - /** - * An Express router. - */ - class RouterDefinition extends InvokeExpr { - RouterDefinition() { this = routerCreation().asExpr() } + /** An Express router. */ + class RouterDefinition extends DataFlow::Node instanceof DataFlow::InvokeNode { + RouterDefinition() { this = routerCreation() } private DataFlow::SourceNode ref(DataFlow::TypeTracker t) { t.start() and - result = DataFlow::exprNode(this) + result = this or exists(string name | result = this.ref(t.continue()).getAMethodCall(name) | name = "route" or @@ -852,22 +943,17 @@ module Express { /** Gets a data flow node referring to this router. */ DataFlow::SourceNode ref() { result = this.ref(DataFlow::TypeTracker::end()) } - /** - * Holds if `sink` may refer to this router. - */ - predicate flowsTo(Expr sink) { this.ref().flowsToExpr(sink) } - /** * Gets a `RouteSetup` that was used for setting up a route on this router. */ - private RouteSetup getARouteSetup() { this.flowsTo(result.getReceiver()) } + private RouteSetup getARouteSetup() { this.ref().flowsTo(result.getReceiver()) } /** * Gets a sub-router registered on this router. * * Example: `router2` for `router1.use(router2)` or `router1.use("/route2", router2)` */ - RouterDefinition getASubRouter() { result.flowsTo(this.getARouteSetup().getAnArgument()) } + RouterDefinition getASubRouter() { result.ref().flowsTo(this.getARouteSetup().getAnArgument()) } /** * Gets a route handler registered on this router. @@ -875,7 +961,7 @@ module Express { * Example: `fun` for `router1.use(fun)` or `router.use("/route", fun)` */ HTTP::RouteHandler getARouteHandler() { - result.(DataFlow::SourceNode).flowsToExpr(this.getARouteSetup().getAnArgument()) + result.(DataFlow::SourceNode).flowsTo(this.getARouteSetup().getAnArgument()) } /** @@ -893,25 +979,25 @@ module Express { * * If `node` is not in the same container where `router` was defined, the predicate has no result. */ - Express::RouteHandlerExpr getMiddlewareStackAt(ControlFlowNode node) { + Express::RouteHandlerNode getMiddlewareStackAt(ControlFlowNode node) { if - exists(Express::RouteSetup setup | node = setup and setup.getRouter() = this | + exists(Express::RouteSetup setup | node = setup.asExpr() and setup.getRouter() = this | setup.isUseCall() ) - then result = node.(Express::RouteSetup).getLastRouteHandlerExpr() + then result = node.(AST::ValueNode).flow().(Express::RouteSetup).getLastRouteHandlerNode() else result = this.getMiddlewareStackAt(node.getAPredecessor()) } /** * Gets the final middleware registered on this router. */ - Express::RouteHandlerExpr getMiddlewareStack() { + Express::RouteHandlerNode getMiddlewareStack() { result = this.getMiddlewareStackAt(this.getContainer().getExit()) } } /** An expression that is passed as `expressBasicAuth({ users: { : }})`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { @@ -922,9 +1008,9 @@ module Express { usersSrc.flowsTo(call.getOptionArgument(0, "users")) and usersSrc.flowsTo(pwn.getBase()) | - this = pwn.getPropertyNameExpr() and kind = "user name" + this = pwn.getPropertyNameExpr().flow() and kind = "user name" or - this = pwn.getRhs().asExpr() and kind = "password" + this = pwn.getRhs() and kind = "password" ) ) } @@ -937,7 +1023,7 @@ module Express { DataFlow::MethodCallNode { ResponseSendFileAsFileSystemAccess() { exists(string name | name = "sendFile" or name = "sendfile" | - this.calls(any(ResponseExpr res).flow(), name) + this.calls(any(ResponseNode res), name) ) } @@ -963,10 +1049,10 @@ module Express { TrackedRouteHandlerCandidateWithSetup() { this = routeSetup.getARouteHandler() } - override Parameter getRouteHandlerParameter(string kind) { + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { if routeSetup.isParameterHandler() - then result = getRouteParameterHandlerParameter(astNode, kind) - else result = getRouteHandlerParameter(astNode, kind) + then result = getRouteParameterHandlerParameter(this, kind) + else result = getRouteHandlerParameter(this, kind) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll index 000015191f8a..76d1c9825b32 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll @@ -18,9 +18,7 @@ module Fastify { * A standard way to create a Fastify server. */ class StandardServerDefinition extends ServerDefinition { - StandardServerDefinition() { - this = DataFlow::moduleImport("fastify").getAnInvocation().asExpr() - } + StandardServerDefinition() { this = DataFlow::moduleImport("fastify").getAnInvocation() } } /** Gets a data flow node referring to a fastify server. */ @@ -134,12 +132,12 @@ module Fastify { /** * A call to a Fastify method that sets up a route. */ - class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { ServerDefinition server; string methodName; RouteSetup() { - this = server(server.flow()).getAMethodCall(methodName).asExpr() and + this = server(server).getAMethodCall(methodName) and methodName = ["route", "get", "head", "post", "put", "delete", "options", "patch"] } @@ -149,25 +147,30 @@ module Fastify { private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) { t.start() and - result = this.getARouteHandlerExpr().getALocalSource() + result = this.getARouteHandlerNode().getALocalSource() or exists(DataFlow::TypeBackTracker t2 | result = this.getARouteHandler(t2).backtrack(t2, t)) } - override Expr getServer() { result = server } + override DataFlow::SourceNode getServer() { result = server } - /** Gets an argument that represents a route handler being registered. */ - DataFlow::Node getARouteHandlerExpr() { + /** + * DEPRECATED: Use `getARouteHandlerNode` instead. + * Gets an argument that represents a route handler being registered. + */ + deprecated DataFlow::Node getARouteHandlerExpr() { result = this.getARouteHandlerNode() } + + /** Gets an argument that represents a route handler being registered. */ + DataFlow::Node getARouteHandlerNode() { if methodName = "route" - then - result = this.flow().(DataFlow::MethodCallNode).getOptionArgument(0, getNthHandlerName(_)) - else result = this.getLastArgument().flow() + then result = this.getOptionArgument(0, getNthHandlerName(_)) + else result = this.getLastArgument() } } private class ShorthandRoutingTreeSetup extends Routing::RouteSetup::MethodCall { ShorthandRoutingTreeSetup() { - this.asExpr() instanceof RouteSetup and + this instanceof RouteSetup and not this.getMethodName() = "route" } @@ -185,7 +188,7 @@ module Fastify { private class FullRoutingTreeSetup extends Routing::RouteSetup::MethodCall { FullRoutingTreeSetup() { - this.asExpr() instanceof RouteSetup and + this instanceof RouteSetup and this.getMethodName() = "route" } @@ -287,13 +290,7 @@ module Fastify { */ private predicate usesFastifyPlugin(RouteHandler rh, DataFlow::SourceNode plugin) { exists(RouteSetup setup | - plugin - .flowsTo(setup - .getServer() - .flow() - .(DataFlow::SourceNode) - .getAMethodCall("register") - .getArgument(0)) and // only matches the plugins that apply to all routes + plugin.flowsTo(setup.getServer().getAMethodCall("register").getArgument(0)) and // only matches the plugins that apply to all routes rh = setup.getARouteHandler() ) } @@ -303,13 +300,7 @@ module Fastify { */ private predicate usesMiddleware(RouteHandler rh, DataFlow::SourceNode middleware) { exists(RouteSetup setup | - middleware - .flowsTo(setup - .getServer() - .flow() - .(DataFlow::SourceNode) - .getAMethodCall("use") - .getArgument(0)) and // only matches the middlewares that apply to all routes + middleware.flowsTo(setup.getServer().getAMethodCall("use").getArgument(0)) and // only matches the middlewares that apply to all routes rh = setup.getARouteHandler() ) } @@ -340,9 +331,9 @@ module Fastify { RouteHandler rh; ResponseSendArgument() { - this = rh.getAResponseSource().ref().getAMethodCall("send").getArgument(0).asExpr() + this = rh.getAResponseSource().ref().getAMethodCall("send").getArgument(0) or - this = rh.(DataFlow::FunctionNode).getAReturn().asExpr() + this = rh.(DataFlow::FunctionNode).getAReturn() } override RouteHandler getRouteHandler() { result = rh } @@ -351,14 +342,12 @@ module Fastify { /** * An invocation of the `redirect` method of an HTTP response object. */ - private class RedirectInvocation extends HTTP::RedirectInvocation, MethodCallExpr { + private class RedirectInvocation extends HTTP::RedirectInvocation, DataFlow::MethodCallNode { RouteHandler rh; - RedirectInvocation() { - this = rh.getAResponseSource().ref().getAMethodCall("redirect").asExpr() - } + RedirectInvocation() { this = rh.getAResponseSource().ref().getAMethodCall("redirect") } - override Expr getUrlArgument() { result = this.getLastArgument() } + override DataFlow::Node getUrlArgument() { result = this.getLastArgument() } override RouteHandler getRouteHandler() { result = rh } } @@ -394,18 +383,18 @@ module Fastify { */ private DataFlow::SourceNode getAHeaderSource() { result.flowsTo(this.getArgument(0)) } - override predicate definesExplicitly(string headerName, Expr headerValue) { + override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) { exists(string header | - this.getAHeaderSource().hasPropertyWrite(header, headerValue.flow()) and + this.getAHeaderSource().hasPropertyWrite(header, headerValue) and headerName = header.toLowerCase() ) } override RouteHandler getRouteHandler() { result = rh } - override Expr getNameExpr() { + override DataFlow::Node getNameNode() { exists(DataFlow::PropWrite write | this.getAHeaderSource().getAPropertyWrite() = write | - result = write.getPropertyNameExpr() + result = write.getPropertyNameExpr().flow() ) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll b/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll index 3678d5fde578..d22bb782630e 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll @@ -114,13 +114,13 @@ module Firebase { class QueryListenCall extends DataFlow::MethodCallNode { QueryListenCall() { this = query().getAMethodCall() and - (getMethodName() = "on" or getMethodName() = "once") + (this.getMethodName() = "on" or this.getMethodName() = "once") } /** * Gets the argument in which the callback is passed. */ - DataFlow::Node getCallbackNode() { result = getArgument(1) } + DataFlow::Node getCallbackNode() { result = this.getArgument(1) } } /** @@ -183,50 +183,46 @@ module Firebase { class RefBuilderListenCall extends DataFlow::MethodCallNode { RefBuilderListenCall() { this = ref().getAMethodCall() and - getMethodName() = "on" + any(string s) + this.getMethodName() = "on" + any(string s) } /** * Gets the data flow node holding the listener callback. */ - DataFlow::Node getCallbackNode() { result = getArgument(0) } + DataFlow::Node getCallbackNode() { result = this.getArgument(0) } } /** * A call to a Firebase method that sets up a route. */ - private class RouteSetup extends HTTP::Servers::StandardRouteSetup, CallExpr { - RouteSetup() { - this = namespace().getAPropertyRead("https").getAMemberCall("onRequest").asExpr() - } + private class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode { + RouteSetup() { this = namespace().getAPropertyRead("https").getAMemberCall("onRequest") } override DataFlow::SourceNode getARouteHandler() { - result = getARouteHandler(DataFlow::TypeBackTracker::end()) + result = this.getARouteHandler(DataFlow::TypeBackTracker::end()) } private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) { t.start() and - result = getArgument(0).flow().getALocalSource() + result = this.getArgument(0).getALocalSource() or - exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t)) + exists(DataFlow::TypeBackTracker t2 | result = this.getARouteHandler(t2).backtrack(t2, t)) } - override Expr getServer() { none() } + override DataFlow::Node getServer() { none() } } /** * A function used as a route handler. */ private class RouteHandler extends Express::RouteHandler, HTTP::Servers::StandardRouteHandler, - DataFlow::ValueNode { - override Function astNode; - + DataFlow::FunctionNode { RouteHandler() { this = any(RouteSetup setup).getARouteHandler() } - override Parameter getRouteHandlerParameter(string kind) { - kind = "request" and result = astNode.getParameter(0) + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { + kind = "request" and result = this.getParameter(0) or - kind = "response" and result = astNode.getParameter(1) + kind = "response" and result = this.getParameter(1) } } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll b/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll index f82b46506682..626b29423c89 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll @@ -12,9 +12,9 @@ module HTTP { /** * A function invocation that causes a redirect response to be sent. */ - abstract class RedirectInvocation extends InvokeExpr { + abstract class RedirectInvocation extends DataFlow::CallNode { /** Gets the argument specifying the URL to redirect to. */ - abstract Expr getUrlArgument(); + abstract DataFlow::Node getUrlArgument(); /** Gets the route handler this redirect occurs in. */ abstract RouteHandler getRouteHandler(); @@ -56,24 +56,34 @@ module HTTP { * An expression that sets HTTP response headers explicitly. */ abstract class ExplicitHeaderDefinition extends HeaderDefinition { - override string getAHeaderName() { this.definesExplicitly(result, _) } + override string getAHeaderName() { this.definesHeaderValue(result, _) } override predicate defines(string headerName, string headerValue) { - exists(Expr e | - this.definesExplicitly(headerName, e) and + exists(DataFlow::Node e | + this.definesHeaderValue(headerName, e) and headerValue = e.getStringValue() ) } /** + * DEPRECATED: use `definesHeaderValue` instead. * Holds if the header with (lower-case) name `headerName` is set to the value of `headerValue`. */ - abstract predicate definesExplicitly(string headerName, Expr headerValue); + deprecated predicate definesExplicitly(string headerName, Expr headerValue) { + this.definesHeaderValue(headerName, headerValue.flow()) + } + + /** Holds if the header with (lower-case) name `headerName` is set to the value of `headerValue`. */ + abstract predicate definesHeaderValue(string headerName, DataFlow::Node headerValue); /** + * DEPRECATED: Use `getNameNode()` instead. * Returns the expression used to compute the header name. */ - abstract Expr getNameExpr(); + deprecated Expr getNameExpr() { result = this.getNameNode().asExpr() } + + /** Returns the expression used to compute the header name. */ + abstract DataFlow::Node getNameNode(); } /** @@ -107,7 +117,7 @@ module HTTP { /** * An expression whose value is sent as (part of) the body of an HTTP response. */ - abstract class ResponseBody extends Expr { + abstract class ResponseBody extends DataFlow::Node { /** * Gets the route handler that sends this expression. */ @@ -123,21 +133,21 @@ module HTTP { /** * An expression that sets a cookie in an HTTP response. */ - abstract class CookieDefinition extends Expr { + abstract class CookieDefinition extends DataFlow::Node { /** * Gets the argument, if any, specifying the raw cookie header. */ - Expr getHeaderArgument() { none() } + DataFlow::Node getHeaderArgument() { none() } /** * Gets the argument, if any, specifying the cookie name. */ - Expr getNameArgument() { none() } + DataFlow::Node getNameArgument() { none() } /** * Gets the argument, if any, specifying the cookie value. */ - Expr getValueArgument() { none() } + DataFlow::Node getValueArgument() { none() } /** Gets the route handler that sets this cookie. */ abstract RouteHandler getRouteHandler(); @@ -150,12 +160,12 @@ module HTTP { HeaderDefinition header; SetCookieHeader() { - this = header.asExpr() and + this = header and header.getAHeaderName() = "set-cookie" } - override Expr getHeaderArgument() { - header.(ExplicitHeaderDefinition).definesExplicitly("set-cookie", result) + override DataFlow::Node getHeaderArgument() { + header.(ExplicitHeaderDefinition).definesHeaderValue("set-cookie", result) } override RouteHandler getRouteHandler() { result = header.getRouteHandler() } @@ -164,7 +174,7 @@ module HTTP { /** * An expression that creates a new server. */ - abstract class ServerDefinition extends Expr { + abstract class ServerDefinition extends DataFlow::Node { /** * Gets a route handler of the server. */ @@ -198,16 +208,30 @@ module HTTP { final Servers::ResponseSource getAResponseSource() { result.getRouteHandler() = this } /** + * DEPRECATED: Use `getARequestNode()` instead. * Gets an expression that contains a request object handled * by this handler. */ - RequestExpr getARequestExpr() { result.getRouteHandler() = this } + deprecated RequestExpr getARequestExpr() { result.flow() = this.getARequestNode() } + + /** + * Gets an expression that contains a request object handled + * by this handler. + */ + RequestNode getARequestNode() { result.getRouteHandler() = this } + + /** + * DEPRECATED: Use `getAResponseNode()` instead. + * Gets an expression that contains a response object provided + * by this handler. + */ + deprecated ResponseExpr getAResponseExpr() { result.flow() = this.getAResponseNode() } /** * Gets an expression that contains a response object provided * by this handler. */ - ResponseExpr getAResponseExpr() { result.getRouteHandler() = this } + ResponseNode getAResponseNode() { result.getRouteHandler() = this } } /** @@ -232,26 +256,42 @@ module HTTP { /** * An expression that sets up a route on a server. */ - abstract class RouteSetup extends Expr { } + abstract class RouteSetup extends DataFlow::Node { } + + /** A dataflow node that may contain a request object. */ + abstract class RequestNode extends DataFlow::Node { + /** Gets the route handler that handles this request. */ + abstract RouteHandler getRouteHandler(); + } + + /** An dataflow node that may contain a response object. */ + abstract class ResponseNode extends DataFlow::Node { + /** Gets the route handler that handles this request. */ + abstract RouteHandler getRouteHandler(); + } /** + * DEPRECATED: Use `RequestNode` instead. * An expression that may contain a request object. */ - abstract class RequestExpr extends Expr { + deprecated class RequestExpr extends Expr { + RequestExpr() { this.flow() instanceof ResponseNode } + /** * Gets the route handler that handles this request. */ - abstract RouteHandler getRouteHandler(); + RouteHandler getRouteHandler() { result = this.flow().(ResponseNode).getRouteHandler() } } /** + * DEPRECATED: Use `ResponseNode` instead. * An expression that may contain a response object. */ - abstract class ResponseExpr extends Expr { + deprecated class ResponseExpr extends Expr { /** * Gets the route handler that handles this request. */ - abstract RouteHandler getRouteHandler(); + RouteHandler getRouteHandler() { result = this.flow().(ResponseNode).getRouteHandler() } } /** @@ -267,15 +307,19 @@ module HTTP { private DataFlow::SourceNode ref(DataFlow::TypeTracker t) { t.start() and - result = DataFlow::exprNode(this) + result = this.getALocalSource() or exists(DataFlow::TypeTracker t2 | result = this.ref(t2).track(t2, t)) } + /** Gets a data flow node referring to this server. */ + DataFlow::SourceNode ref() { result = this.ref(DataFlow::TypeTracker::end()) } + /** + * DEPRECATED: Use `ref().flowsToExpr()` instead. * Holds if `sink` may refer to this server definition. */ - predicate flowsTo(Expr sink) { this.ref(DataFlow::TypeTracker::end()).flowsToExpr(sink) } + deprecated predicate flowsTo(Expr sink) { this.ref().flowsToExpr(sink) } } /** @@ -290,7 +334,7 @@ module HTTP { /** * Gets the server this route handler is registered on. */ - Expr getServer() { + DataFlow::Node getServer() { exists(StandardRouteSetup setup | setup.getARouteHandler() = this | result = setup.getServer() ) @@ -350,10 +394,10 @@ module HTTP { /** * A request expression arising from a request source. */ - class StandardRequestExpr extends RequestExpr { + class StandardRequestNode extends RequestNode { RequestSource src; - StandardRequestExpr() { src.ref().flowsTo(DataFlow::valueNode(this)) } + StandardRequestNode() { src.ref().flowsTo(this) } override RouteHandler getRouteHandler() { result = src.getRouteHandler() } } @@ -361,26 +405,49 @@ module HTTP { /** * A response expression arising from a response source. */ - class StandardResponseExpr extends ResponseExpr { + class StandardResponseNode extends ResponseNode { ResponseSource src; - StandardResponseExpr() { src.ref().flowsTo(DataFlow::valueNode(this)) } + StandardResponseNode() { src.ref().flowsTo(this) } override RouteHandler getRouteHandler() { result = src.getRouteHandler() } } /** - * A standard header definition. + * A request expression arising from a request source. */ - abstract class StandardHeaderDefinition extends ExplicitHeaderDefinition, DataFlow::ValueNode { - override MethodCallExpr astNode; + deprecated class StandardRequestExpr extends RequestExpr { + RequestSource src; + + StandardRequestExpr() { src.ref().flowsToExpr(this) } - override predicate definesExplicitly(string headerName, Expr headerValue) { - headerName = this.getNameExpr().getStringValue().toLowerCase() and - headerValue = astNode.getArgument(1) + override RouteHandler getRouteHandler() { result = src.getRouteHandler() } + } + + /** + * A response expression arising from a response source. + */ + deprecated class StandardResponseExpr extends ResponseExpr { + ResponseSource src; + + StandardResponseExpr() { src.ref().flowsToExpr(this) } + + override RouteHandler getRouteHandler() { + result = this.flow().(StandardResponseNode).getRouteHandler() + } + } + + /** + * A standard header definition. + */ + abstract class StandardHeaderDefinition extends ExplicitHeaderDefinition, + DataFlow::MethodCallNode { + override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) { + headerName = this.getNameNode().getStringValue().toLowerCase() and + headerValue = this.getArgument(1) } - override Expr getNameExpr() { result = astNode.getArgument(0) } + override DataFlow::Node getNameNode() { result = this.getArgument(0) } } /** @@ -396,7 +463,7 @@ module HTTP { /** * Gets the server on which this route setup sets up routes. */ - abstract Expr getServer(); + abstract DataFlow::Node getServer(); } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index b83b85831c7d..c5700f257287 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -9,39 +9,34 @@ module Hapi { /** * An expression that creates a new Hapi server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition, NewExpr { + class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::NewNode { ServerDefinition() { // `server = new Hapi.Server()` - this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation().asExpr() + this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation() } } /** * A Hapi route handler. */ - class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::ValueNode { - Function function; - - RouteHandler() { - function = astNode and - exists(RouteSetup setup | this = setup.getARouteHandler()) - } + class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + RouteHandler() { exists(RouteSetup setup | this = setup.getARouteHandler()) } /** * Gets the parameter of the route handler that contains the request object. */ - Parameter getRequestParameter() { result = function.getParameter(0) } + DataFlow::ParameterNode getRequestParameter() { result = this.getParameter(0) } /** * Gets the parameter of the route handler that contains the "request toolkit", * usually named `h`. */ - Parameter getRequestToolkitParameter() { result = function.getParameter(1) } + DataFlow::ParameterNode getRequestToolkitParameter() { result = this.getParameter(1) } /** * Gets a source node referring to the request toolkit parameter, usually named `h`. */ - DataFlow::SourceNode getRequestToolkit() { result = getRequestToolkitParameter().flow() } + DataFlow::SourceNode getRequestToolkit() { result = this.getRequestToolkitParameter() } } /** @@ -49,9 +44,9 @@ module Hapi { * of a request object. */ private class ResponseSource extends HTTP::Servers::ResponseSource { - RequestExpr req; + RequestNode req; - ResponseSource() { asExpr().(PropAccess).accesses(req, "response") } + ResponseSource() { this.(DataFlow::PropRead).accesses(req, "response") } /** * Gets the route handler that provides this response. @@ -66,7 +61,7 @@ module Hapi { private class RequestSource extends HTTP::Servers::RequestSource { RouteHandler rh; - RequestSource() { this = DataFlow::parameterNode(rh.getRequestParameter()) } + RequestSource() { this = rh.getRequestParameter() } /** * Gets the route handler that handles this request. @@ -75,16 +70,32 @@ module Hapi { } /** + * DEPRECATED: Use `ResponseNode` instead. * A Hapi response expression. */ - class ResponseExpr extends HTTP::Servers::StandardResponseExpr { + deprecated class ResponseExpr extends HTTP::Servers::StandardResponseExpr { + ResponseExpr() { this.flow() instanceof ResponseNode } + } + + /** + * A Hapi response node. + */ + class ResponseNode extends HTTP::Servers::StandardResponseNode { override ResponseSource src; } /** + * DEPRECATED: Use `RequestNode` instead. * An Hapi request expression. */ - class RequestExpr extends HTTP::Servers::StandardRequestExpr { + deprecated class RequestExpr extends HTTP::Servers::StandardRequestExpr { + RequestExpr() { this.flow() instanceof RequestNode } + } + + /** + * A Hapi request node. + */ + class RequestNode extends HTTP::Servers::StandardRequestNode { override RequestSource src; } @@ -96,38 +107,38 @@ module Hapi { string kind; RequestInputAccess() { - exists(Expr request | request = rh.getARequestExpr() | + exists(DataFlow::Node request | request = rh.getARequestNode() | kind = "body" and ( // `request.rawPayload` - this.asExpr().(PropAccess).accesses(request, "rawPayload") + this.(DataFlow::PropRead).accesses(request, "rawPayload") or - exists(PropAccess payload | + exists(DataFlow::PropRead payload | // `request.payload.name` payload.accesses(request, "payload") and - this.asExpr().(PropAccess).accesses(payload, _) + this.(DataFlow::PropRead).accesses(payload, _) ) ) or kind = "parameter" and - exists(PropAccess query | + exists(DataFlow::PropRead query | // `request.query.name` query.accesses(request, "query") and - this.asExpr().(PropAccess).accesses(query, _) + this.(DataFlow::PropRead).accesses(query, _) ) or - exists(PropAccess url | + exists(DataFlow::PropRead url | // `request.url.path` kind = "url" and url.accesses(request, "url") and - this.asExpr().(PropAccess).accesses(url, "path") + this.(DataFlow::PropRead).accesses(url, "path") ) or - exists(PropAccess state | + exists(DataFlow::PropRead state | // `request.state.` kind = "cookie" and state.accesses(request, "state") and - this.asExpr().(PropAccess).accesses(state, _) + this.(DataFlow::PropRead).accesses(state, _) ) ) or @@ -149,11 +160,11 @@ module Hapi { RouteHandler rh; RequestHeaderAccess() { - exists(Expr request | request = rh.getARequestExpr() | - exists(PropAccess headers | + exists(DataFlow::Node request | request = rh.getARequestNode() | + exists(DataFlow::PropRead headers | // `request.headers.` headers.accesses(request, "headers") and - this.asExpr().(PropAccess).accesses(headers, _) + this.(DataFlow::PropRead).accesses(headers, _) ) ) } @@ -171,11 +182,11 @@ module Hapi { * An HTTP header defined in a Hapi server. */ private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { - ResponseExpr res; + ResponseNode res; HeaderDefinition() { // request.response.header('Cache-Control', 'no-cache') - astNode.calls(res, "header") + this.calls(res, "header") } override RouteHandler getRouteHandler() { result = res.getRouteHandler() } @@ -184,40 +195,40 @@ module Hapi { /** * A call to a Hapi method that sets up a route. */ - class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { ServerDefinition server; - Expr handler; + DataFlow::Node handler; RouteSetup() { - server.flowsTo(getReceiver()) and + server.ref().getAMethodCall() = this and ( // server.route({ handler: fun }) - getMethodName() = "route" and - hasOptionArgument(0, "handler", handler) + this.getMethodName() = "route" and + this.getOptionArgument(0, "handler") = handler or // server.ext('/', fun) - getMethodName() = "ext" and - handler = getArgument(1) + this.getMethodName() = "ext" and + handler = this.getArgument(1) ) } override DataFlow::SourceNode getARouteHandler() { - result = getARouteHandler(DataFlow::TypeBackTracker::end()) + result = this.getARouteHandler(DataFlow::TypeBackTracker::end()) } private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) { t.start() and - result = getRouteHandler().getALocalSource() + result = this.getRouteHandler().getALocalSource() or - exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t)) + exists(DataFlow::TypeBackTracker t2 | result = this.getARouteHandler(t2).backtrack(t2, t)) } pragma[noinline] - private DataFlow::Node getRouteHandler() { result = handler.flow() } + private DataFlow::Node getRouteHandler() { result = handler } - Expr getRouteHandlerExpr() { result = handler } + deprecated Expr getRouteHandlerExpr() { result = handler.asExpr() } - override Expr getServer() { result = server } + override DataFlow::Node getServer() { result = server } } /** @@ -257,9 +268,9 @@ module Hapi { override DataFlow::SourceNode getOutput() { none() } - override DataFlow::Node getTemplateFileNode() { result = getArgument(0) } + override DataFlow::Node getTemplateFileNode() { result = this.getArgument(0) } - override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) } + override DataFlow::Node getTemplateParamsNode() { result = this.getArgument(1) } } /** @@ -268,7 +279,7 @@ module Hapi { private class HandlerReturn extends HTTP::ResponseSendArgument { RouteHandler handler; - HandlerReturn() { this = handler.(DataFlow::FunctionNode).getAReturn().asExpr() } + HandlerReturn() { this = handler.(DataFlow::FunctionNode).getAReturn() } override RouteHandler getRouteHandler() { result = handler } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/HttpProxy.qll b/javascript/ql/lib/semmle/javascript/frameworks/HttpProxy.qll index 24e694ca8d9d..b471dd344314 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/HttpProxy.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/HttpProxy.qll @@ -83,16 +83,12 @@ private module HttpProxy { ) } - override Parameter getRequestParameter() { - exists(int req | routeHandlingEventHandler(event, req, _) | - result = getFunction().getParameter(req) - ) + override DataFlow::ParameterNode getRequestParameter() { + exists(int req | routeHandlingEventHandler(event, req, _) | result = getParameter(req)) } - override Parameter getResponseParameter() { - exists(int res | routeHandlingEventHandler(event, _, res) | - result = getFunction().getParameter(res) - ) + override DataFlow::ParameterNode getResponseParameter() { + exists(int res | routeHandlingEventHandler(event, _, res) | result = getParameter(res)) } } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/JWT.qll b/javascript/ql/lib/semmle/javascript/frameworks/JWT.qll index 485684507707..aa0b157844cd 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/JWT.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/JWT.qll @@ -40,12 +40,10 @@ private module JsonWebToken { } /** - * The private key for a JWT as a `CredentialsExpr`. + * The private key for a JWT as a `CredentialsNode`. */ - private class JwtKey extends CredentialsExpr { - JwtKey() { - this = DataFlow::moduleMember("jsonwebtoken", "sign").getACall().getArgument(1).asExpr() - } + private class JwtKey extends CredentialsNode { + JwtKey() { this = DataFlow::moduleMember("jsonwebtoken", "sign").getACall().getArgument(1) } override string getCredentialsKind() { result = "key" } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Knex.qll b/javascript/ql/lib/semmle/javascript/frameworks/Knex.qll index e768a9feaff6..923df27bd501 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Knex.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Knex.qll @@ -43,7 +43,7 @@ module Knex { /** A SQL string passed to a raw Knex method. */ private class RawKnexSqlString extends SQL::SqlString { - RawKnexSqlString() { this = any(RawKnexCall call).getArgument(0).asExpr() } + RawKnexSqlString() { this = any(RawKnexCall call).getArgument(0) } } /** A call that triggers a SQL query submission by calling then/stream/asCallback. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll b/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll index f9519736b0e4..49104de92633 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll @@ -9,10 +9,10 @@ module Koa { /** * An expression that creates a new Koa application. */ - class AppDefinition extends HTTP::Servers::StandardServerDefinition, InvokeExpr { + class AppDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::InvokeNode { AppDefinition() { // `app = new Koa()` / `app = Koa()` - this = DataFlow::moduleImport("koa").getAnInvocation().asExpr() + this = DataFlow::moduleImport("koa").getAnInvocation() } } @@ -24,10 +24,10 @@ module Koa { HeaderDefinition() { // ctx.set('Cache-Control', 'no-cache'); - astNode.calls(rh.getAResponseOrContextExpr(), "set") + this.calls(rh.getAResponseOrContextNode(), "set") or // ctx.response.header('Cache-Control', 'no-cache') - astNode.calls(rh.getAResponseExpr(), "header") + this.calls(rh.getAResponseNode(), "header") } override RouteHandler getRouteHandler() { result = rh } @@ -40,10 +40,17 @@ module Koa { /** * Gets the parameter of the route handler that contains the context object. */ - Parameter getContextParameter() { - result = this.getAFunctionValue().getFunction().getParameter(0) + DataFlow::ParameterNode getContextParameter() { + result = this.getAFunctionValue().getParameter(0) } + /** + * DEPRECATED: Use `getAContextNode` instead. + * Gets an expression that contains the "context" object of + * a route handler invocation. + */ + deprecated Expr getAContextExpr() { result = this.getAContextNode().asExpr() } + /** * Gets an expression that contains the "context" object of * a route handler invocation. @@ -52,22 +59,38 @@ module Koa { * `this` or `ctx`, given as the first and only argument to the * route handler. */ - Expr getAContextExpr() { result.(ContextExpr).getRouteHandler() = this } + DataFlow::Node getAContextNode() { result.(ContextNode).getRouteHandler() = this } + + /** + * DEPRECATED: Use `getAResponseOrContextNode` instead. + * Gets an expression that contains the context or response + * object of a route handler invocation. + */ + deprecated Expr getAResponseOrContextExpr() { + result = this.getAResponseOrContextNode().asExpr() + } /** * Gets an expression that contains the context or response * object of a route handler invocation. */ - Expr getAResponseOrContextExpr() { - result = this.getAResponseExpr() or result = this.getAContextExpr() + DataFlow::Node getAResponseOrContextNode() { + result = this.getAResponseNode() or result = this.getAContextNode() } /** + * DEPRECATED: Use `getARequestOrContextNode` instead. * Gets an expression that contains the context or request * object of a route handler invocation. */ - Expr getARequestOrContextExpr() { - result = this.getARequestExpr() or result = this.getAContextExpr() + deprecated Expr getARequestOrContextExpr() { result = this.getARequestOrContextNode().asExpr() } + + /** + * Gets an expression that contains the context or request + * object of a route handler invocation. + */ + DataFlow::Node getARequestOrContextNode() { + result = this.getARequestNode() or result = this.getAContextNode() } /** @@ -108,7 +131,7 @@ module Koa { RouteHandler rh; ContextSource() { - this = DataFlow::parameterNode(rh.getContextParameter()) + this = rh.getContextParameter() or this.(DataFlow::ThisNode).getBinder() = rh } @@ -118,8 +141,6 @@ module Koa { */ RouteHandler getRouteHandler() { result = rh } - predicate flowsTo(DataFlow::Node nd) { this.ref().flowsTo(nd) } - private DataFlow::SourceNode ref(DataFlow::TypeTracker t) { t.start() and result = this @@ -206,10 +227,10 @@ 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 { - ContextExpr ctx; + private class RequestSource extends HTTP::Servers::RequestSource instanceof DataFlow::PropRead { + ContextNode ctx; - RequestSource() { this.asExpr().(PropAccess).accesses(ctx, "request") } + RequestSource() { super.accesses(ctx, "request") } /** * Gets the route handler that provides this response. @@ -241,10 +262,10 @@ 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 { - ContextExpr ctx; + private class ResponseSource extends HTTP::Servers::ResponseSource instanceof DataFlow::PropRead { + ContextNode ctx; - ResponseSource() { this.asExpr().(PropAccess).accesses(ctx, "response") } + ResponseSource() { super.accesses(ctx, "response") } /** * Gets the route handler that provides this response. @@ -253,12 +274,25 @@ module Koa { } /** + * DEPRECATED: Use `ContextNode` instead. * An expression that may hold a Koa context object. */ - class ContextExpr extends Expr { + deprecated class ContextExpr extends Expr { + ContextNode node; + + ContextExpr() { node.asExpr() = this } + + /** Gets the route handler that provides this response. */ + deprecated RouteHandler getRouteHandler() { result = node.getRouteHandler() } + } + + /** + * An expression that may hold a Koa context object. + */ + class ContextNode extends DataFlow::Node { ContextSource src; - ContextExpr() { src.flowsTo(DataFlow::valueNode(this)) } + ContextNode() { src.ref().flowsTo(this) } /** * Gets the route handler that provides this response. @@ -267,16 +301,32 @@ module Koa { } /** + * DEPRECATED: Use `RequestNode` instead. * An expression that may hold a Koa request object. */ - class RequestExpr extends HTTP::Servers::StandardRequestExpr { + deprecated class RequestExpr extends HTTP::Servers::StandardRequestExpr { + RequestExpr() { this.flow() instanceof RequestNode } + } + + /** + * An expression that may hold a Koa request object. + */ + class RequestNode extends HTTP::Servers::StandardRequestNode { override RequestSource src; } + /** + * DEPRECATED: Use `ResponseNode` instead. + * An expression that may hold a Koa response object. + */ + deprecated class ResponseExpr extends HTTP::Servers::StandardResponseExpr { + ResponseExpr() { this.flow() instanceof ResponseNode } + } + /** * An expression that may hold a Koa response object. */ - class ResponseExpr extends HTTP::Servers::StandardResponseExpr { + class ResponseNode extends HTTP::Servers::StandardResponseNode { override ResponseSource src; } @@ -294,11 +344,11 @@ module Koa { kind = "parameter" and this = rh.getARequestParameterAccess() or - exists(Expr e | rh.getARequestOrContextExpr() = e | + exists(DataFlow::Node e | rh.getARequestOrContextNode() = e | // `ctx.request.url`, `ctx.request.originalUrl`, or `ctx.request.href` exists(string propName | kind = "url" and - this.asExpr().(PropAccess).accesses(e, propName) + this.(DataFlow::PropRead).accesses(e, propName) | propName = "url" or @@ -309,19 +359,19 @@ module Koa { or // params, when handler is registered by `koa-router` or similar. kind = "parameter" and - this.asExpr().(PropAccess).accesses(e, "params") + this.(DataFlow::PropRead).accesses(e, "params") or // `ctx.request.body` - e instanceof RequestExpr and + e instanceof RequestNode and kind = "body" and - this.asExpr().(PropAccess).accesses(e, "body") + this.(DataFlow::PropRead).accesses(e, "body") or // `ctx.cookies.get()` - exists(PropAccess cookies | - e instanceof ContextExpr and + exists(DataFlow::PropRead cookies | + e instanceof ContextNode and kind = "cookie" and cookies.accesses(e, "cookies") and - this = cookies.flow().(DataFlow::SourceNode).getAMethodCall("get") + this = cookies.getAMethodCall("get") ) or exists(RequestHeaderAccess access | access = this | @@ -340,9 +390,9 @@ module Koa { private DataFlow::Node getAQueryParameterAccess(RouteHandler rh) { // `ctx.query.name` or `ctx.request.query.name` - exists(PropAccess q | - q.accesses(rh.getARequestOrContextExpr(), "query") and - result = q.flow().(DataFlow::SourceNode).getAPropertyRead() + exists(DataFlow::PropRead q | + q.accesses(rh.getARequestOrContextNode(), "query") and + result = q.getAPropertyRead() ) } @@ -353,18 +403,18 @@ module Koa { RouteHandler rh; RequestHeaderAccess() { - exists(Expr e | e = rh.getARequestOrContextExpr() | - exists(string propName, PropAccess headers | + exists(DataFlow::Node e | e = rh.getARequestOrContextNode() | + exists(string propName, DataFlow::PropRead headers | // `ctx.request.header.`, `ctx.request.headers.` headers.accesses(e, propName) and - this = headers.flow().(DataFlow::SourceNode).getAPropertyRead() + this = headers.getAPropertyRead() | propName = "header" or propName = "headers" ) or // `ctx.request.get()` - this.asExpr().(MethodCallExpr).calls(e, "get") + this.(DataFlow::MethodCallNode).calls(e, "get") ) } @@ -385,24 +435,23 @@ module Koa { /** * A call to a Koa method that sets up a route. */ - class RouteSetup extends HTTP::Servers::StandardRouteSetup, MethodCallExpr { + class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode { AppDefinition server; RouteSetup() { // app.use(fun) - server.flowsTo(this.getReceiver()) and - this.getMethodName() = "use" + server.ref().getAMethodCall("use") = this } override DataFlow::SourceNode getARouteHandler() { // `StandardRouteHandler` uses this predicate in it's charpred, so making this predicate return a `RouteHandler` would give an empty recursion. - result.flowsToExpr(this.getArgument(0)) + result.flowsTo(this.getArgument(0)) or // For the route-handlers that does not depend on this predicate in their charpred. - result.(RouteHandler).getARouteHandlerRegistrationObject().flowsToExpr(this.getArgument(0)) + result.(RouteHandler).getARouteHandlerRegistrationObject().flowsTo(this.getArgument(0)) } - override Expr getServer() { result = server } + override DataFlow::Node getServer() { result = server } } /** @@ -412,10 +461,7 @@ module Koa { RouteHandler rh; ResponseSendArgument() { - exists(DataFlow::PropWrite pwn | - pwn.writes(DataFlow::valueNode(rh.getAResponseOrContextExpr()), "body", - DataFlow::valueNode(this)) - ) + exists(DataFlow::PropWrite pwn | pwn.writes(rh.getAResponseOrContextNode(), "body", this)) } override RouteHandler getRouteHandler() { result = rh } @@ -424,12 +470,12 @@ module Koa { /** * An invocation of the `redirect` method of an HTTP response object. */ - private class RedirectInvocation extends HTTP::RedirectInvocation, MethodCallExpr { + private class RedirectInvocation extends HTTP::RedirectInvocation instanceof DataFlow::MethodCallNode { RouteHandler rh; - RedirectInvocation() { this.(MethodCallExpr).calls(rh.getAResponseOrContextExpr(), "redirect") } + RedirectInvocation() { super.calls(rh.getAResponseOrContextNode(), "redirect") } - override Expr getUrlArgument() { result = this.getArgument(0) } + override DataFlow::Node getUrlArgument() { result = this.getArgument(0) } override RouteHandler getRouteHandler() { result = rh } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll b/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll index 1d7604e0b0cb..cc90dc8d7207 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll @@ -10,9 +10,9 @@ private module LiveServer { * An expression that imports the live-server package, seen as a server-definition. */ class ServerDefinition extends HTTP::Servers::StandardServerDefinition { - ServerDefinition() { this = DataFlow::moduleImport("live-server").asExpr() } + ServerDefinition() { this = DataFlow::moduleImport("live-server") } - API::Node getImportNode() { result.asSource().asExpr() = this } + API::Node getImportNode() { result.asSource() = this } } /** @@ -22,26 +22,22 @@ private module LiveServer { class RouteHandler extends Connect::RouteHandler, DataFlow::FunctionNode { RouteHandler() { this = any(RouteSetup setup).getARouteHandler() } - override Parameter getRouteHandlerParameter(string kind) { - result = ConnectExpressShared::getRouteHandlerParameter(astNode, kind) + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { + result = ConnectExpressShared::getRouteHandlerParameter(this, kind) } } /** * The call to `require("live-server").start()`, seen as a route setup. */ - class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends HTTP::Servers::StandardRouteSetup instanceof API::CallNode { ServerDefinition server; - API::CallNode call; - RouteSetup() { - call = server.getImportNode().getMember("start").getACall() and - this = call.asExpr() - } + RouteSetup() { this = server.getImportNode().getMember("start").getACall() } override DataFlow::SourceNode getARouteHandler() { exists(DataFlow::SourceNode middleware | - middleware = call.getParameter(0).getMember("middleware").getAValueReachingSink() + middleware = super.getParameter(0).getMember("middleware").getAValueReachingSink() | result = middleware.getAMemberCall(["push", "unshift"]).getArgument(0).getAFunctionValue() or @@ -49,6 +45,6 @@ private module LiveServer { ) } - override Expr getServer() { result = server } + override DataFlow::Node getServer() { result = server } } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll b/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll index 8f5938f4865a..ba99fc014d17 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll @@ -349,8 +349,8 @@ 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::RequestExpr req, API::Node reqNode | - reqNode.asSource() = req.flow().getALocalSource() and + exists(HTTP::RequestNode req, API::Node reqNode | + reqNode.asSource() = req.getALocalSource() and result = reqNode.getMember(["log", "logger"]) ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll b/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll index bc0cd9a31bdf..7ac9b1349d8b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll @@ -62,11 +62,19 @@ private module Micro { override HTTP::RouteHandler getRouteHandler() { result = h } } - class MicroRequestExpr extends NodeJSLib::RequestExpr { + deprecated class MicroRequestExpr extends NodeJSLib::RequestExpr { override MicroRequestSource src; } - class MicroReseponseExpr extends NodeJSLib::ResponseExpr { + class MicroRequestNode extends NodeJSLib::RequestNode { + override MicroRequestSource src; + } + + deprecated class MicroReseponseExpr extends NodeJSLib::ResponseExpr { + override MicroResponseSource src; + } + + class MicroResponseNode extends NodeJSLib::ResponseNode { override MicroResponseSource src; } @@ -104,7 +112,7 @@ private module Micro { MicroSendArgument() { send = moduleMember("micro", ["send", "sendError"]).getACall() and - this = send.getLastArgument().asExpr() + this = send.getLastArgument() } override HTTP::RouteHandler getRouteHandler() { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll b/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll index 1799f35beb8a..80cba72fd3cb 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll @@ -56,7 +56,7 @@ module NestJS { */ predicate isReturnValueReflected() { getAFunctionDecorator(this) = nestjs().getMember(["Get", "Post"]).getACall() and - not hasRedirectDecorator() and + not this.hasRedirectDecorator() and not getAFunctionDecorator(this) = nestjs().getMember("Render").getACall() } @@ -93,7 +93,7 @@ module NestJS { NestJSRequestInput() { decoratorName = ["Query", "Param", "Headers", "Body", "HostParam", "UploadedFile", "UploadedFiles"] and - decorator = getADecorator() and + decorator = this.getADecorator() and decorator = nestjs().getMember(decoratorName).getACall() } @@ -105,7 +105,7 @@ module NestJS { /** Gets a pipe applied to this parameter, not including global pipes. */ DataFlow::Node getAPipe() { - result = getNestRouteHandler().getAPipe() + result = this.getNestRouteHandler().getAPipe() or result = decorator.getArgument(1) or @@ -132,7 +132,7 @@ module NestJS { hasSanitizingPipe(this, false) or hasSanitizingPipe(this, true) and - isSanitizingType(getParameter().getType().unfold()) + isSanitizingType(this.getParameter().getType().unfold()) } } @@ -240,14 +240,14 @@ module NestJS { ) } - DataFlow::FunctionNode getTransformFunction() { result = getInstanceMethod("transform") } + DataFlow::FunctionNode getTransformFunction() { result = this.getInstanceMethod("transform") } - DataFlow::ParameterNode getInputData() { result = getTransformFunction().getParameter(0) } + DataFlow::ParameterNode getInputData() { result = this.getTransformFunction().getParameter(0) } - DataFlow::Node getOutputData() { result = getTransformFunction().getReturnNode() } + DataFlow::Node getOutputData() { result = this.getTransformFunction().getReturnNode() } NestJSRequestInput getAnAffectedParameter() { - [getAnInstanceReference(), getAClassReference()].flowsTo(result.getAPipe()) + [this.getAnInstanceReference(), this.getAClassReference()].flowsTo(result.getAPipe()) } } @@ -297,16 +297,16 @@ module NestJS { private class NestJSRequestInputAsRequestInputAccess extends NestJSRequestInput, HTTP::RequestInputAccess { NestJSRequestInputAsRequestInputAccess() { - not isSanitizedByPipe() and + not this.isSanitizedByPipe() and not this = any(CustomPipeClass cls).getAnAffectedParameter() } - override HTTP::RouteHandler getRouteHandler() { result = getNestRouteHandler() } + override HTTP::RouteHandler getRouteHandler() { result = this.getNestRouteHandler() } - override string getKind() { result = getInputKind() } + override string getKind() { result = this.getInputKind() } override predicate isUserControlledObject() { - not exists(getAPipe()) and // value is not transformed by a pipe + not exists(this.getAPipe()) and // value is not transformed by a pipe ( decorator.getNumArgument() = 0 or @@ -349,10 +349,10 @@ module NestJS { ReturnValueAsResponseSend() { handler.isReturnValueReflected() and - this = handler.getAReturn().asExpr() and + this = handler.getAReturn() and // Only returned strings are sinks not exists(Type type | - type = getType() and + type = this.asExpr().getType() and not isStringType(type.unfold()) ) } @@ -389,15 +389,15 @@ module NestJS { CustomParameterDecorator() { this = nestjs().getMember("createParamDecorator").getACall() } /** Gets the `context` parameter. */ - API::Node getExecutionContext() { result = getParameter(0).getParameter(1) } + API::Node getExecutionContext() { result = this.getParameter(0).getParameter(1) } /** Gets a parameter with this decorator applied. */ DataFlow::ParameterNode getADecoratedParameter() { - result.getADecorator() = getReturn().getReturn().getAValueReachableFromSource() + result.getADecorator() = this.getReturn().getReturn().getAValueReachableFromSource() } /** Gets a value returned by the decorator's callback, which becomes the value of the decorated parameter. */ - DataFlow::Node getResult() { result = getParameter(0).getReturn().asSink() } + DataFlow::Node getResult() { result = this.getParameter(0).getReturn().asSink() } } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Next.qll b/javascript/ql/lib/semmle/javascript/frameworks/Next.qll index 091aa8ba1af6..495543eb1b36 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Next.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Next.qll @@ -35,11 +35,10 @@ module NextJS { */ Module getAModuleWithFallbackPaths() { result = getAPagesModule() and - exists(DataFlow::FunctionNode staticPaths, Expr fallback | + exists(DataFlow::FunctionNode staticPaths, DataFlow::Node fallback | staticPaths = result.getAnExportedValue("getStaticPaths").getAFunctionValue() and - fallback = - staticPaths.getAReturn().getALocalSource().getAPropertyWrite("fallback").getRhs().asExpr() and - not fallback.(BooleanLiteral).getValue() = "false" + fallback = staticPaths.getAReturn().getALocalSource().getAPropertyWrite("fallback").getRhs() and + not fallback.mayHaveBooleanValue(false) ) } @@ -230,10 +229,10 @@ module NextJS { ) } - override Parameter getRouteHandlerParameter(string kind) { - kind = "request" and result = this.getFunction().getParameter(0) + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { + kind = "request" and result = this.getParameter(0) or - kind = "response" and result = this.getFunction().getParameter(1) + kind = "response" and result = this.getParameter(1) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll index 5985735a1067..7f49e0cd2293 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll @@ -6,8 +6,8 @@ import javascript /** Provides classes for modeling NoSql query sinks. */ module NoSql { - /** An expression that is interpreted as a NoSql query. */ - abstract class Query extends Expr { + /** An expression that is interpreted as a NoSQL query. */ + abstract class Query extends DataFlow::Node { /** Gets an expression that is interpreted as a code operator in this query. */ DataFlow::Node getACodeOperator() { none() } } @@ -84,7 +84,7 @@ private module MongoDB { class Query extends NoSql::Query { QueryCall qc; - Query() { this = qc.getAQueryArgument().asExpr() } + Query() { this = qc.getAQueryArgument() } override DataFlow::Node getACodeOperator() { result = qc.getACodeOperator() } } @@ -496,13 +496,11 @@ private module Mongoose { /** * An expression passed to `mongoose.createConnection` to supply credentials. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { - exists(string prop | - this = createConnection().getParameter(3).getMember(prop).asSink().asExpr() - | + exists(string prop | this = createConnection().getParameter(3).getMember(prop).asSink() | prop = "user" and kind = "user name" or prop = "pass" and kind = "password" @@ -518,7 +516,7 @@ private module Mongoose { class MongoDBQueryPart extends NoSql::Query { MongooseFunction f; - MongoDBQueryPart() { this = f.getQueryArgument().asSink().asExpr() } + MongoDBQueryPart() { this = f.getQueryArgument().asSink() } override DataFlow::Node getACodeOperator() { result = getADollarWhereProperty(f.getQueryArgument()) @@ -625,7 +623,7 @@ private module Minimongo { class Query extends NoSql::Query { QueryCall qc; - Query() { this = qc.getAQueryArgument().asExpr() } + Query() { this = qc.getAQueryArgument() } override DataFlow::Node getACodeOperator() { result = qc.getACodeOperator() } } @@ -685,7 +683,7 @@ private module MarsDB { class Query extends NoSql::Query { QueryCall qc; - Query() { this = qc.getAQueryArgument().asExpr() } + Query() { this = qc.getAQueryArgument() } override DataFlow::Node getACodeOperator() { result = qc.getACodeOperator() } } @@ -770,7 +768,7 @@ private module Redis { RedisKeyArgument() { exists(string method, int argIndex | QuerySignatures::argumentIsAmbiguousKey(method, argIndex) and - this = redis().getMember(method).getParameter(argIndex).asSink().asExpr() + this = redis().getMember(method).getParameter(argIndex).asSink() ) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 5bd92e3ec5c6..0c5fdbd6a15c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -49,7 +49,7 @@ module NodeJSLib { /** * Holds if `call` is an invocation of `http.createServer` or `https.createServer`. */ - predicate isCreateServer(CallExpr call) { + predicate isCreateServer(DataFlow::CallNode call) { exists(string pkg, string fn | pkg = "http" and fn = "createServer" or @@ -60,17 +60,39 @@ module NodeJSLib { or pkg = "http2" and fn = "createSecureServer" | - call = DataFlow::moduleMember(pkg, fn).getAnInvocation().asExpr() + call = DataFlow::moduleMember(pkg, fn).getAnInvocation() ) } /** + * DEPRECATED: Use `ResponseNode` instead. * A Node.js HTTP response. * * A server library that provides an (enhanced) NodesJS HTTP response * object should implement a library specific subclass of this class. */ - abstract class ResponseExpr extends HTTP::Servers::StandardResponseExpr { } + deprecated class ResponseExpr extends HTTP::Servers::StandardResponseExpr { + ResponseExpr() { this.flow() instanceof ResponseNode } + } + + /** + * A Node.js HTTP response. + * + * 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 { } + + /** + * DEPRECATED: Use `RequestNode` instead. + * A Node.js HTTP request. + * + * A server library that provides an (enhanced) NodesJS HTTP request + * object should implement a library specific subclass of this class. + */ + deprecated class RequestExpr extends HTTP::Servers::StandardRequestExpr { + RequestExpr() { this.flow() instanceof RequestNode } + } /** * A Node.js HTTP request. @@ -78,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 RequestExpr extends HTTP::Servers::StandardRequestExpr { } + abstract class RequestNode extends HTTP::Servers::StandardRequestNode { } /** * A function used as an Node.js server route handler. @@ -91,12 +113,12 @@ module NodeJSLib { /** * Gets the parameter of the route handler that contains the request object. */ - Parameter getRequestParameter() { result = this.getFunction().getParameter(0) } + DataFlow::ParameterNode getRequestParameter() { result = this.getParameter(0) } /** * Gets the parameter of the route handler that contains the response object. */ - Parameter getResponseParameter() { result = this.getFunction().getParameter(1) } + DataFlow::ParameterNode getResponseParameter() { result = this.getParameter(1) } } /** @@ -118,7 +140,7 @@ module NodeJSLib { private class StandardResponseSource extends ResponseSource { RouteHandler rh; - StandardResponseSource() { this = DataFlow::parameterNode(rh.getResponseParameter()) } + StandardResponseSource() { this = rh.getResponseParameter() } /** * Gets the route handler that provides this response. @@ -138,7 +160,7 @@ module NodeJSLib { private class StandardRequestSource extends RequestSource { RouteHandler rh; - StandardRequestSource() { this = DataFlow::parameterNode(rh.getRequestParameter()) } + StandardRequestSource() { this = rh.getRequestParameter() } /** * Gets the route handler that handles this request. @@ -147,36 +169,52 @@ module NodeJSLib { } /** + * DEPRECATED: Use `BuiltinRouteHandlerResponseNode` instead. * A builtin Node.js HTTP response. */ - private class BuiltinRouteHandlerResponseExpr extends ResponseExpr { + deprecated private class BuiltinRouteHandlerResponseExpr extends ResponseExpr { BuiltinRouteHandlerResponseExpr() { src instanceof ResponseSource } } /** + * A builtin Node.js HTTP response. + */ + private class BuiltinRouteHandlerResponseNode extends ResponseNode { + BuiltinRouteHandlerResponseNode() { src instanceof ResponseSource } + } + + /** + * DEPRECATED: Use `BuiltinRouteHandlerRequestNode` instead. * A builtin Node.js HTTP request. */ - private class BuiltinRouteHandlerRequestExpr extends RequestExpr { + deprecated private class BuiltinRouteHandlerRequestExpr extends RequestExpr { BuiltinRouteHandlerRequestExpr() { src instanceof RequestSource } } + /** + * A builtin Node.js HTTP request. + */ + private class BuiltinRouteHandlerRequestNode extends RequestNode { + BuiltinRouteHandlerRequestNode() { src instanceof RequestSource } + } + /** * An access to a user-controlled Node.js request input. */ private class RequestInputAccess extends HTTP::RequestInputAccess { - RequestExpr request; + RequestNode request; string kind; RequestInputAccess() { // `req.url` / `req.body` kind = ["url", "body"] and - this.asExpr().(PropAccess).accesses(request, kind) + this.(DataFlow::PropRead).accesses(request, kind) or - exists(PropAccess headers | + exists(DataFlow::PropRead headers | // `req.headers.cookie` kind = "cookie" and headers.accesses(request, "headers") and - this.asExpr().(PropAccess).accesses(headers, "cookie") + this.(DataFlow::PropRead).accesses(headers, "cookie") ) or exists(RequestHeaderAccess access | this = access | @@ -194,14 +232,14 @@ module NodeJSLib { * An access to an HTTP header (other than "Cookie") on an incoming Node.js request object. */ private class RequestHeaderAccess extends HTTP::RequestHeaderAccess { - RequestExpr request; + RequestNode request; RequestHeaderAccess() { - exists(PropAccess headers, string name | + exists(DataFlow::PropRead headers, string name | // `req.headers.` name != "cookie" and headers.accesses(request, "headers") and - this.asExpr().(PropAccess).accesses(headers, name) + this.(DataFlow::PropRead).accesses(headers, name) ) } @@ -213,19 +251,19 @@ module NodeJSLib { override string getKind() { result = "header" } - RequestExpr getRequest() { result = request } + RequestNode getRequest() { result = request } } - class RouteSetup extends CallExpr, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::CallNode, HTTP::Servers::StandardRouteSetup { ServerDefinition server; - Expr handler; + DataFlow::Node handler; RouteSetup() { - server.flowsTo(this) and + server.ref() = this and handler = this.getLastArgument() or - server.flowsTo(this.getReceiver()) and - this.(MethodCallExpr).getMethodName().regexpMatch("on(ce)?") and + server.ref().getAMethodCall() = this and + this.getCalleeName().regexpMatch("on(ce)?") and this.getArgument(0).getStringValue() = "request" and handler = this.getArgument(1) } @@ -236,7 +274,7 @@ module NodeJSLib { private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) { t.start() and - result = handler.flow().getALocalSource() + result = handler.getALocalSource() or exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode succ | succ = this.getARouteHandler(t2) @@ -248,18 +286,24 @@ module NodeJSLib { ) } - override Expr getServer() { result = server } + override DataFlow::Node getServer() { result = server } + + /** + * DEPRECATED: Use `getRouteHandlerNode` instead. + * Gets the expression for the handler registered by this setup. + */ + deprecated Expr getRouteHandlerExpr() { result = handler.asExpr() } /** * Gets the expression for the handler registered by this setup. */ - Expr getRouteHandlerExpr() { result = handler } + DataFlow::Node getRouteHandlerNode() { result = handler } } abstract private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { - ResponseExpr r; + ResponseNode r; - HeaderDefinition() { astNode.getReceiver() = r } + HeaderDefinition() { this.getReceiver() = r } override HTTP::RouteHandler getRouteHandler() { result = r.getRouteHandler() } } @@ -268,7 +312,7 @@ module NodeJSLib { * A call to the `setHeader` method of an HTTP response. */ private class SetHeader extends HeaderDefinition { - SetHeader() { astNode.getMethodName() = "setHeader" } + SetHeader() { this.getMethodName() = "setHeader" } } /** @@ -276,15 +320,15 @@ module NodeJSLib { */ private class WriteHead extends HeaderDefinition { WriteHead() { - astNode.getMethodName() = "writeHead" and - astNode.getNumArgument() >= 1 + this.getMethodName() = "writeHead" and + this.getNumArgument() >= 1 } - override predicate definesExplicitly(string headerName, Expr headerValue) { - astNode.getNumArgument() > 1 and + override predicate definesHeaderValue(string headerName, DataFlow::Node headerValue) { + this.getNumArgument() > 1 and exists(DataFlow::SourceNode headers, string header | - headers.flowsToExpr(astNode.getLastArgument()) and - headers.hasPropertyWrite(header, DataFlow::valueNode(headerValue)) and + headers.flowsTo(this.getLastArgument()) and + headers.hasPropertyWrite(header, headerValue) and headerName = header.toLowerCase() ) } @@ -363,9 +407,9 @@ module NodeJSLib { HTTP::RouteHandler rh; ResponseSendArgument() { - exists(MethodCallExpr mce, string m | m = "write" or m = "end" | - mce.calls(any(ResponseExpr e | e.getRouteHandler() = rh), m) and - this = mce.getArgument(0) and + exists(DataFlow::MethodCallNode mcn, string m | m = "write" or m = "end" | + mcn.calls(any(ResponseNode e | e.getRouteHandler() = rh), m) and + this = mcn.getArgument(0) and // don't mistake callback functions as data not this.analyze().getAValue() instanceof AbstractFunction ) @@ -382,11 +426,10 @@ module NodeJSLib { } /** An expression that is passed as `http.request({ auth: }, ...)`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { Credentials() { exists(string http | http = "http" or http = "https" | - this = - DataFlow::moduleMember(http, "request").getACall().getOptionArgument(0, "auth").asExpr() + this = DataFlow::moduleMember(http, "request").getACall().getOptionArgument(0, "auth") ) } @@ -994,11 +1037,9 @@ module NodeJSLib { /** * A data flow node that is the username passed to the login callback provided by an HTTP or HTTPS request made by a Node.js process, for example `username` in `http.request(url).on('login', (res, cb) => {cb(username, password)})`. */ - private class ClientRequestLoginUsername extends CredentialsExpr { + private class ClientRequestLoginUsername extends CredentialsNode { ClientRequestLoginUsername() { - exists(ClientRequestLoginCallback callback | - this = callback.getACall().getArgument(0).asExpr() - ) + exists(ClientRequestLoginCallback callback | this = callback.getACall().getArgument(0)) } override string getCredentialsKind() { result = "Node.js http(s) client login username" } @@ -1007,11 +1048,9 @@ module NodeJSLib { /** * A data flow node that is the password passed to the login callback provided by an HTTP or HTTPS request made by a Node.js process, for example `password` in `http.request(url).on('login', (res, cb) => {cb(username, password)})`. */ - private class ClientRequestLoginPassword extends CredentialsExpr { + private class ClientRequestLoginPassword extends CredentialsNode { ClientRequestLoginPassword() { - exists(ClientRequestLoginCallback callback | - this = callback.getACall().getArgument(1).asExpr() - ) + exists(ClientRequestLoginCallback callback | this = callback.getACall().getArgument(1)) } override string getCredentialsKind() { result = "Node.js http(s) client login password" } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/PkgCloud.qll b/javascript/ql/lib/semmle/javascript/frameworks/PkgCloud.qll index ef1e5b9bdbb4..9255b31fb659 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/PkgCloud.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/PkgCloud.qll @@ -31,13 +31,13 @@ module PkgCloud { /** * An expression that is used for authentication through pkgcloud. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { exists(string propertyName, DataFlow::InvokeNode invk, int i | takesConfigurationObject(invk, i) and - this = invk.getOptionArgument(0, propertyName).asExpr() + this = invk.getOptionArgument(0, propertyName) | /* * Catch-all support for the following providers: diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Request.qll b/javascript/ql/lib/semmle/javascript/frameworks/Request.qll index bd9fa71864fe..392a84c51a43 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Request.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Request.qll @@ -6,7 +6,7 @@ import javascript module Request { /** A credentials expression that is used for authentication. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { @@ -20,9 +20,9 @@ module Request { action = mod.getAMemberCall(any(HTTP::RequestMethodName n).toLowerCase()) ) | - exists(MethodCallExpr auth, int argIndex | + exists(DataFlow::MethodCallNode auth, int argIndex | // request.get(url).auth('username', 'password', _, 'token'); - auth = action.getAMemberCall("auth").asExpr() and + auth = action.getAMemberCall("auth") and this = auth.getArgument(argIndex) | argIndex = 0 and kind = "user name" @@ -35,7 +35,7 @@ module Request { exists(DataFlow::ObjectLiteralNode auth, string propertyName | // request.get(url, { auth: {user: 'username', pass: 'password', bearer: 'token'}}) auth.flowsTo(action.getOptionArgument(1, "auth")) and - auth.hasPropertyWrite(propertyName, DataFlow::valueNode(this)) + auth.hasPropertyWrite(propertyName, this) | (propertyName = "user" or propertyName = "username") and kind = "user name" diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll index f83f2930f51f..492416171dac 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll @@ -9,10 +9,10 @@ module Restify { /** * An expression that creates a new Restify server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition, CallExpr { + class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::CallNode { ServerDefinition() { // `server = restify.createServer()` - this = DataFlow::moduleMember("restify", "createServer").getACall().asExpr() + this = DataFlow::moduleMember("restify", "createServer").getACall() } } @@ -69,38 +69,54 @@ module Restify { } /** + * DEPRECATED: Use `ResponseNode` instead. * A Node.js HTTP response provided by Restify. */ - class ResponseExpr extends NodeJSLib::ResponseExpr { + deprecated class ResponseExpr extends NodeJSLib::ResponseExpr { ResponseExpr() { src instanceof ResponseSource } } /** + * A Node.js HTTP response provided by Restify. + */ + class ResponseNode extends NodeJSLib::ResponseNode { + ResponseNode() { src instanceof ResponseSource } + } + + /** + * DEPRECATED: Use `RequestNode` instead. * A Node.js HTTP request provided by Restify. */ - class RequestExpr extends NodeJSLib::RequestExpr { + deprecated class RequestExpr extends NodeJSLib::RequestExpr { RequestExpr() { src instanceof RequestSource } } + /** + * A Node.js HTTP request provided by Restify. + */ + class RequestNode extends NodeJSLib::RequestNode { + RequestNode() { src instanceof RequestSource } + } + /** * An access to a user-controlled Restify request input. */ private class RequestInputAccess extends HTTP::RequestInputAccess { - RequestExpr request; + RequestNode request; string kind; RequestInputAccess() { - exists(MethodCallExpr query | + exists(DataFlow::MethodCallNode query | // `request.getQuery().` kind = "parameter" and query.calls(request, "getQuery") and - this.asExpr().(PropAccess).accesses(query, _) + this.(DataFlow::PropRead).accesses(query, _) ) or exists(string methodName | // `request.href()` or `request.getPath()` kind = "url" and - this.asExpr().(MethodCallExpr).calls(request, methodName) + this.(DataFlow::MethodCallNode).calls(request, methodName) | methodName = "href" or methodName = "getPath" @@ -108,13 +124,12 @@ module Restify { or // `request.getContentType()`, `request.userAgent()`, `request.trailer(...)`, `request.header(...)` kind = "header" and - this.asExpr() - .(MethodCallExpr) + this.(DataFlow::MethodCallNode) .calls(request, ["getContentType", "userAgent", "trailer", "header"]) or // `req.cookies kind = "cookie" and - this.asExpr().(PropAccess).accesses(request, "cookies") + this.(DataFlow::PropRead).accesses(request, "cookies") } override RouteHandler getRouteHandler() { result = request.getRouteHandler() } @@ -128,28 +143,27 @@ module Restify { private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { HeaderDefinition() { // response.header('Cache-Control', 'no-cache') - astNode.getReceiver() instanceof ResponseExpr and - astNode.getMethodName() = "header" + this.getReceiver() instanceof ResponseNode and + this.getMethodName() = "header" } - override RouteHandler getRouteHandler() { astNode.getReceiver() = result.getAResponseExpr() } + override RouteHandler getRouteHandler() { this.getReceiver() = result.getAResponseNode() } } /** * A call to a Restify method that sets up a route. */ - class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { ServerDefinition server; RouteSetup() { // server.get('/', fun) // server.head('/', fun) - server.flowsTo(getReceiver()) and - getMethodName() = any(HTTP::RequestMethodName m).toLowerCase() + server.ref().getAMethodCall(any(HTTP::RequestMethodName m).toLowerCase()) = this } - override DataFlow::SourceNode getARouteHandler() { result.flowsToExpr(getArgument(1)) } + override DataFlow::SourceNode getARouteHandler() { result.flowsTo(this.getArgument(1)) } - override Expr getServer() { result = server } + override DataFlow::Node getServer() { result = server } } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll index edd92614a2c3..a1499d09ea2c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/SQL.qll @@ -5,26 +5,26 @@ import javascript module SQL { - /** A string-valued expression that is interpreted as a SQL command. */ - abstract class SqlString extends Expr { } + /** A string-valued dataflow node that is interpreted as a SQL command. */ + abstract class SqlString extends DataFlow::Node { } private class SqlStringFromModel extends SqlString { - SqlStringFromModel() { this = ModelOutput::getASinkNode("sql-injection").asSink().asExpr() } + SqlStringFromModel() { this = ModelOutput::getASinkNode("sql-injection").asSink() } } /** - * An expression that sanitizes a string to make it safe to embed into + * An dataflow node that sanitizes a string to make it safe to embed into * a SQL command. */ - abstract class SqlSanitizer extends Expr { - Expr input; - Expr output; + abstract class SqlSanitizer extends DataFlow::Node { + DataFlow::Node input; + DataFlow::Node output; /** Gets the input expression being sanitized. */ - Expr getInput() { result = input } + DataFlow::Node getInput() { result = input } /** Gets the output expression containing the sanitized value. */ - Expr getOutput() { result = output } + DataFlow::Node getOutput() { result = output } } } @@ -90,26 +90,26 @@ private module MySql { /** An expression that is passed to the `query` method and hence interpreted as SQL. */ class QueryString extends SQL::SqlString { - QueryString() { this = any(QueryCall qc).getAQueryArgument().asExpr() } + QueryString() { this = any(QueryCall qc).getAQueryArgument() } } /** A call to the `escape` or `escapeId` method that performs SQL sanitization. */ - class EscapingSanitizer extends SQL::SqlSanitizer, MethodCallExpr { + class EscapingSanitizer extends SQL::SqlSanitizer instanceof API::CallNode { EscapingSanitizer() { - this = [mysql(), pool(), connection()].getMember(["escape", "escapeId"]).getACall().asExpr() and + this = [mysql(), pool(), connection()].getMember(["escape", "escapeId"]).getACall() and input = this.getArgument(0) and output = this } } /** An expression that is passed as user name or password to `mysql.createConnection`. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { exists(API::Node callee, string prop | callee in [createConnection(), createPool()] and - this = callee.getParameter(0).getMember(prop).asSink().asExpr() and + this = callee.getParameter(0).getMember(prop).asSink() and ( prop = "user" and kind = "user name" or @@ -198,21 +198,21 @@ private module Postgres { /** An expression that is passed to the `query` method and hence interpreted as SQL. */ class QueryString extends SQL::SqlString { QueryString() { - this = any(QueryCall qc).getAQueryArgument().asExpr() + this = any(QueryCall qc).getAQueryArgument() or - this = API::moduleImport("pg-cursor").getParameter(0).asSink().asExpr() + this = API::moduleImport("pg-cursor").getParameter(0).asSink() } } /** An expression that is passed as user name or password when creating a client or a pool. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { exists(string prop | - this = [newClient(), newPool()].getParameter(0).getMember(prop).asSink().asExpr() + this = [newClient(), newPool()].getParameter(0).getMember(prop).asSink() or - this = pgPromise().getParameter(0).getMember(prop).asSink().asExpr() + this = pgPromise().getParameter(0).getMember(prop).asSink() | prop = "user" and kind = "user name" or @@ -349,7 +349,7 @@ private module Postgres { /** An expression that is interpreted as SQL by `pg-promise`. */ class PgPromiseQueryString extends SQL::SqlString { - PgPromiseQueryString() { this = any(PgPromiseQueryCall qc).getAQueryArgument().asExpr() } + PgPromiseQueryString() { this = any(PgPromiseQueryCall qc).getAQueryArgument() } } } @@ -398,7 +398,7 @@ private module Sqlite { /** An expression that is passed to the `query` method and hence interpreted as SQL. */ class QueryString extends SQL::SqlString { - QueryString() { this = any(QueryCall qc).getAQueryArgument().asExpr() } + QueryString() { this = any(QueryCall qc).getAQueryArgument() } } } @@ -470,7 +470,7 @@ private module MsSql { class QueryString extends SQL::SqlString { QueryString() { exists(DatabaseAccess dba | dba instanceof QueryTemplateExpr or dba instanceof QueryCall | - this = dba.getAQueryArgument().asExpr() + this = dba.getAQueryArgument() ) } } @@ -478,14 +478,14 @@ private module MsSql { /** An element of a query template, which is automatically sanitized. */ class QueryTemplateSanitizer extends SQL::SqlSanitizer { QueryTemplateSanitizer() { - this = any(QueryTemplateExpr qte).getAQueryArgument().asExpr() and + this = any(QueryTemplateExpr qte).getAQueryArgument() and input = this and output = this } } /** An expression that is passed as user name or password when creating a client or a pool. */ - class Credentials extends CredentialsExpr { + class Credentials extends CredentialsNode { string kind; Credentials() { @@ -495,7 +495,7 @@ private module MsSql { or callee = mssql().getMember("ConnectionPool") ) and - this = callee.getParameter(0).getMember(prop).asSink().asExpr() and + this = callee.getParameter(0).getMember(prop).asSink() and ( prop = "user" and kind = "user name" or diff --git a/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll b/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll index 3b9c3b1bb79f..1d873a3f2a97 100644 --- a/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll +++ b/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll @@ -29,8 +29,8 @@ private class PromotedExpressCandidate extends Express::RouteHandler, HTTP::Servers::StandardRouteHandler { PromotedExpressCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate } - override Parameter getRouteHandlerParameter(string kind) { - result = ConnectExpressShared::getRouteHandlerParameter(getAstNode(), kind) + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { + result = ConnectExpressShared::getRouteHandlerParameter(this, kind) } } @@ -41,7 +41,7 @@ private class PromotedConnectCandidate extends Connect::RouteHandler, HTTP::Servers::StandardRouteHandler { PromotedConnectCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate } - override Parameter getRouteHandlerParameter(string kind) { - result = ConnectExpressShared::getRouteHandlerParameter(getAstNode(), kind) + override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { + result = ConnectExpressShared::getRouteHandlerParameter(this, kind) } } diff --git a/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll b/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll index dfa1ef10a805..504ebad9e35f 100644 --- a/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll +++ b/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll @@ -13,9 +13,25 @@ import javascript import semmle.javascript.security.internal.SensitiveDataHeuristics private import HeuristicNames +/** + * DEPRECATED: Use `SensitiveNode` instead. + * An expression that might contain sensitive data. + */ +deprecated class SensitiveExpr extends Expr { + SensitiveNode node; + + SensitiveExpr() { node.asExpr() = this } + + /** Gets a human-readable description of this expression for use in alert messages. */ + deprecated string describe() { result = node.describe() } + + /** Gets a classification of the kind of sensitive data this expression might contain. */ + deprecated SensitiveDataClassification getClassification() { result = node.getClassification() } +} + /** An expression that might contain sensitive data. */ cached -abstract class SensitiveExpr extends Expr { +abstract class SensitiveNode extends DataFlow::Node { /** Gets a human-readable description of this expression for use in alert messages. */ cached abstract string describe(); @@ -26,33 +42,33 @@ abstract class SensitiveExpr extends Expr { } /** A function call that might produce sensitive data. */ -class SensitiveCall extends SensitiveExpr, InvokeExpr { +class SensitiveCall extends SensitiveNode instanceof DataFlow::InvokeNode { SensitiveDataClassification classification; SensitiveCall() { - classification = this.getCalleeName().(SensitiveDataFunctionName).getClassification() + classification = super.getCalleeName().(SensitiveDataFunctionName).getClassification() or // This is particularly to pick up methods with an argument like "password", which // may indicate a lookup. - exists(string s | this.getAnArgument().mayHaveStringValue(s) | + exists(string s | super.getAnArgument().mayHaveStringValue(s) | nameIndicatesSensitiveData(s, classification) ) } - override string describe() { result = "a call to " + this.getCalleeName() } + override string describe() { result = "a call to " + super.getCalleeName() } override SensitiveDataClassification getClassification() { result = classification } } /** An access to a variable or property that might contain sensitive data. */ -abstract class SensitiveVariableAccess extends SensitiveExpr { +abstract class SensitiveVariableAccess extends SensitiveNode { string name; SensitiveVariableAccess() { - this.(VarAccess).getName() = name + this.asExpr().(VarAccess).getName() = name or exists(DataFlow::PropRead pr | - this = pr.asExpr() and + this = pr and pr.getPropertyName() = name ) } @@ -173,10 +189,8 @@ class ProtectCall extends DataFlow::CallNode { } /** An expression that might contain a clear-text password. */ -class CleartextPasswordExpr extends SensitiveExpr { - CleartextPasswordExpr() { - this.(SensitiveExpr).getClassification() = SensitiveDataClassification::password() - } +class CleartextPasswordExpr extends SensitiveNode { + CleartextPasswordExpr() { this.getClassification() = SensitiveDataClassification::password() } override string describe() { none() } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmCustomizations.qll index 58858d798865..832f811f67b9 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/BrokenCryptoAlgorithmCustomizations.qll @@ -30,10 +30,8 @@ module BrokenCryptoAlgorithm { * A sensitive expression, viewed as a data flow source for sensitive information * in broken or weak cryptographic algorithms. */ - class SensitiveExprSource extends Source, DataFlow::ValueNode { - override SensitiveExpr astNode; - - override string describe() { result = astNode.describe() } + class SensitiveExprSource extends Source instanceof SensitiveNode { + override string describe() { result = SensitiveNode.super.describe() } } /** @@ -43,7 +41,7 @@ module BrokenCryptoAlgorithm { WeakCryptographicOperationSink() { exists(CryptographicOperation application | application.getAlgorithm().isWeak() and - this.asExpr() = application.getInput() + this = application.getInput() ) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll index e719d02d1009..ef2090b3dead 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll @@ -30,15 +30,13 @@ module CleartextStorage { * A sensitive expression, viewed as a data flow source for cleartext storage * of sensitive information. */ - class SensitiveExprSource extends Source, DataFlow::ValueNode { - override SensitiveExpr astNode; - + class SensitiveExprSource extends Source instanceof SensitiveNode { SensitiveExprSource() { // storing user names or account names in plaintext isn't usually a problem - astNode.getClassification() != SensitiveDataClassification::id() + super.getClassification() != SensitiveDataClassification::id() } - override string describe() { result = astNode.describe() } + override string describe() { result = SensitiveNode.super.describe() } } /** A call to any function whose name suggests that it encodes or encrypts its arguments. */ @@ -52,8 +50,8 @@ module CleartextStorage { class CookieStorageSink extends Sink { CookieStorageSink() { exists(HTTP::CookieDefinition cookieDef | - this.asExpr() = cookieDef.getValueArgument() or - this.asExpr() = cookieDef.getHeaderArgument() + this = cookieDef.getValueArgument() or + this = cookieDef.getHeaderArgument() ) } } @@ -61,16 +59,12 @@ module CleartextStorage { /** * An expression set as a value of localStorage or sessionStorage. */ - class WebStorageSink extends Sink { - WebStorageSink() { this.asExpr() instanceof WebStorageWrite } - } + class WebStorageSink extends Sink instanceof WebStorageWrite { } /** * An expression stored by AngularJS. */ class AngularJSStorageSink extends Sink { - AngularJSStorageSink() { - any(AngularJS::AngularJSCall call).storesArgumentGlobally(this.asExpr()) - } + AngularJSStorageSink() { any(AngularJS::AngularJSCallNode call).storesArgumentGlobally(this) } } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index 6549f40ebdd2..4c6ad8b0ee9e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -57,23 +57,23 @@ module ClientSideUrlRedirect { * when `base` is the current URL. */ predicate untrustedUrlSubstring(DataFlow::Node base, DataFlow::Node substring) { - exists(MethodCallExpr mce, string methodName | - mce = substring.asExpr() and mce.calls(base.asExpr(), methodName) + exists(DataFlow::MethodCallNode mcn, string methodName | + mcn = substring and mcn.calls(base, methodName) | methodName = "split" and // exclude all splits where only the prefix is accessed, which is safe for url-redirects. - not exists(PropAccess pacc | mce = pacc.getBase() | pacc.getPropertyName() = "0") + not exists(DataFlow::PropRead pacc | mcn = pacc.getBase() | pacc.getPropertyName() = "0") or methodName = StringOps::substringMethodName() and // exclude `location.href.substring(0, ...)` and similar, which can // never refer to the query string - not mce.getArgument(0).(NumberLiteral).getIntValue() = 0 + not mcn.getArgument(0).getIntValue() = 0 ) or - exists(MethodCallExpr mce | - substring.asExpr() = mce and - mce = any(DataFlow::RegExpCreationNode re).getAMethodCall("exec").asExpr() and - base.asExpr() = mce.getArgument(0) + exists(DataFlow::MethodCallNode mcn | + substring = mcn and + mcn = any(DataFlow::RegExpCreationNode re).getAMethodCall("exec") and + base = mcn.getArgument(0) ) } @@ -104,7 +104,9 @@ module ClientSideUrlRedirect { xss = true or // An assignment to `location` - exists(Assignment assgn | isLocation(assgn.getTarget()) and astNode = assgn.getRhs()) and + exists(Assignment assgn | + isLocationNode(assgn.getTarget().flow()) and astNode = assgn.getRhs() + ) and xss = true or // An assignment to `location.href`, `location.protocol` or `location.hostname` @@ -119,7 +121,7 @@ module ClientSideUrlRedirect { // A redirection using the AngularJS `$location` service exists(AngularJS::ServiceReference service | service.getName() = "$location" and - this.asExpr() = service.getAMethodCall("url").getArgument(0) + this = service.getAMethodCall("url").getArgument(0) ) and xss = false } @@ -177,7 +179,7 @@ module ClientSideUrlRedirect { ) or // e.g. node.setAttribute("href", sink) - any(DomMethodCallExpr call).interpretsArgumentsAsUrl(this.asExpr()) + any(DomMethodCallNode call).interpretsArgumentsAsUrl(this) } override predicate isXssSink() { any() } @@ -189,9 +191,9 @@ module ClientSideUrlRedirect { */ class AttributeWriteUrlSink extends ScriptUrlSink, DataFlow::ValueNode { AttributeWriteUrlSink() { - exists(DomPropWriteNode pw | + exists(DomPropertyWrite pw | pw.interpretsValueAsJavaScriptUrl() and - this = DataFlow::valueNode(pw.getRhs()) + this = pw.getRhs() ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index 9e72cc9ee820..fd76028a6f32 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -37,7 +37,7 @@ module CodeInjection { */ class AngularJSExpressionSink extends Sink, DataFlow::ValueNode { AngularJSExpressionSink() { - any(AngularJS::AngularJSCall call).interpretsArgumentAsCode(this.asExpr()) + any(AngularJS::AngularJSCallNode call).interpretsArgumentAsCode(this) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll index 867494fc0a36..24c9a707bd08 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll @@ -46,12 +46,12 @@ module CorsMisconfigurationForCredentials { CorsOriginHeaderWithAssociatedCredentialHeader() { exists( HTTP::RouteHandler routeHandler, HTTP::ExplicitHeaderDefinition origin, - Expr credentialsValue + DataFlow::Node credentialsValue | routeHandler.getAResponseHeader(_) = origin and routeHandler.getAResponseHeader(_) = credentials and - origin.definesExplicitly("access-control-allow-origin", this.asExpr()) and - credentials.definesExplicitly("access-control-allow-credentials", credentialsValue) + origin.definesHeaderValue("access-control-allow-origin", this) and + credentials.definesHeaderValue("access-control-allow-credentials", credentialsValue) | credentialsValue.mayHaveBooleanValue(true) or credentialsValue.mayHaveStringValue("true") diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll index 3b370bb6938a..21fb6f785aff 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll @@ -21,14 +21,28 @@ class DomGlobalVariable extends GlobalVariable { /** DEPRECATED: Alias for DomGlobalVariable */ deprecated class DOMGlobalVariable = DomGlobalVariable; -/** Holds if `e` could hold a value that comes from the DOM. */ -predicate isDomValue(Expr e) { DOM::domValueRef().flowsToExpr(e) } +/** + * DEPRECATED: Use `isDomNode` instead. + * Holds if `e` could hold a value that comes from the DOM. + */ +deprecated predicate isDomValue(Expr e) { isDomNode(e.flow()) } + +/** + * Holds if `e` could hold a value that comes from the DOM. + */ +predicate isDomNode(DataFlow::Node e) { DOM::domValueRef().flowsTo(e) } + +/** + * DEPRECATED: Use `isLocationNode` instead. + * Holds if `e` could refer to the `location` property of a DOM node. + */ +deprecated predicate isLocation(Expr e) { isLocationNode(e.flow()) } /** Holds if `e` could refer to the `location` property of a DOM node. */ -predicate isLocation(Expr e) { - e = DOM::domValueRef().getAPropertyReference("location").asExpr() +predicate isLocationNode(DataFlow::Node e) { + e = DOM::domValueRef().getAPropertyReference("location") or - e.accessesGlobal("location") + e = DataFlow::globalVarRef("location") } /** @@ -52,16 +66,53 @@ deprecated predicate isDocumentUrl(Expr e) { e.flow() = DOM::locationSource() } /** DEPRECATED: Alias for isDocumentUrl */ deprecated predicate isDocumentURL = isDocumentUrl/1; +/** + * DEPRECATED. In most cases, a sanitizer based on this predicate can be removed, as + * taint tracking no longer step through the properties of the location object by default. + * + * Holds if `pacc` accesses a part of `document.location` that is + * not considered user-controlled, that is, anything except + * `href`, `hash` and `search`. + */ +deprecated predicate isSafeLocationProperty(PropAccess pacc) { + exists(string prop | pacc = DOM::locationRef().getAPropertyRead(prop).asExpr() | + prop != "href" and prop != "hash" and prop != "search" + ) +} + +/** + * DEPRECATED: Use `DomMethodCallNode` instead. + * A call to a DOM method. + */ +deprecated class DomMethodCallExpr extends MethodCallExpr { + DomMethodCallNode node; + + DomMethodCallExpr() { this.flow() = node } + + /** Holds if `arg` is an argument that is interpreted as HTML. */ + deprecated predicate interpretsArgumentsAsHtml(Expr arg) { + node.interpretsArgumentsAsHtml(arg.flow()) + } + + /** Holds if `arg` is an argument that is used as an URL. */ + deprecated predicate interpretsArgumentsAsURL(Expr arg) { + node.interpretsArgumentsAsURL(arg.flow()) + } + + /** DEPRECATED: Alias for interpretsArgumentsAsHtml */ + deprecated predicate interpretsArgumentsAsHTML(Expr arg) { this.interpretsArgumentsAsHtml(arg) } +} + /** * A call to a DOM method. */ -class DomMethodCallExpr extends MethodCallExpr { - DomMethodCallExpr() { isDomValue(this.getReceiver()) } +class DomMethodCallNode extends DataFlow::MethodCallNode { + DomMethodCallNode() { isDomNode(this.getReceiver()) } /** * Holds if `arg` is an argument that is interpreted as HTML. */ - predicate interpretsArgumentsAsHtml(Expr arg) { + predicate interpretsArgumentsAsHtml(DataFlow::Node arg) { exists(int argPos, string name | arg = this.getArgument(argPos) and name = this.getMethodName() @@ -86,7 +137,7 @@ class DomMethodCallExpr extends MethodCallExpr { /** * Holds if `arg` is an argument that is used as an URL. */ - predicate interpretsArgumentsAsUrl(Expr arg) { + predicate interpretsArgumentsAsUrl(DataFlow::Node arg) { exists(int argPos, string name | arg = this.getArgument(argPos) and name = this.getMethodName() @@ -104,56 +155,84 @@ class DomMethodCallExpr extends MethodCallExpr { } /** DEPRECATED: Alias for interpretsArgumentsAsUrl */ - deprecated predicate interpretsArgumentsAsURL(Expr arg) { this.interpretsArgumentsAsUrl(arg) } + deprecated predicate interpretsArgumentsAsURL(DataFlow::Node arg) { + this.interpretsArgumentsAsUrl(arg) + } /** DEPRECATED: Alias for interpretsArgumentsAsHtml */ - deprecated predicate interpretsArgumentsAsHTML(Expr arg) { this.interpretsArgumentsAsHtml(arg) } + deprecated predicate interpretsArgumentsAsHTML(DataFlow::Node arg) { + this.interpretsArgumentsAsHtml(arg) + } } /** + * DEPRECATED: Use `DomPropertyWrite` instead. * An assignment to a property of a DOM object. */ -class DomPropWriteNode extends Assignment { - PropAccess lhs; +deprecated class DomPropWriteNode extends Assignment { + DomPropertyWrite node; - DomPropWriteNode() { - lhs = this.getLhs() and - isDomValue(lhs.getBase()) - } + DomPropWriteNode() { this.flow() = node } /** * Holds if the assigned value is interpreted as HTML. */ - predicate interpretsValueAsHtml() { - lhs.getPropertyName() = "innerHTML" or - lhs.getPropertyName() = "outerHTML" - } + predicate interpretsValueAsHtml() { node.interpretsValueAsHtml() } /** DEPRECATED: Alias for interpretsValueAsHtml */ deprecated predicate interpretsValueAsHTML() { this.interpretsValueAsHtml() } + /** + * Holds if the assigned value is interpreted as JavaScript via javascript: protocol. + */ + predicate interpretsValueAsJavaScriptUrl() { node.interpretsValueAsJavaScriptUrl() } +} + +/** + * An assignment to a property of a DOM object. + */ +class DomPropertyWrite extends DataFlow::Node instanceof DataFlow::PropWrite { + DomPropertyWrite() { isDomNode(super.getBase()) } + + /** + * Holds if the assigned value is interpreted as HTML. + */ + predicate interpretsValueAsHtml() { + super.getPropertyName() = "innerHTML" or + super.getPropertyName() = "outerHTML" + } + /** * Holds if the assigned value is interpreted as JavaScript via javascript: protocol. */ predicate interpretsValueAsJavaScriptUrl() { - lhs.getPropertyName() = DOM::getAPropertyNameInterpretedAsJavaScriptUrl() + super.getPropertyName() = DOM::getAPropertyNameInterpretedAsJavaScriptUrl() + } + + /** + * Gets the data flow node corresponding to the value being written. + */ + DataFlow::Node getRhs() { + result = super.getRhs() + or + result = super.getWriteNode().(AssignAddExpr).getRhs().flow() } } /** * A value written to web storage, like `localStorage` or `sessionStorage`. */ -class WebStorageWrite extends Expr { +class WebStorageWrite extends DataFlow::Node { WebStorageWrite() { exists(DataFlow::SourceNode webStorage | webStorage = DataFlow::globalVarRef("localStorage") or webStorage = DataFlow::globalVarRef("sessionStorage") | // an assignment to `window.localStorage[someProp]` - this = webStorage.getAPropertyWrite().getRhs().asExpr() + this = webStorage.getAPropertyWrite().getRhs() or // an invocation of `window.localStorage.setItem` - this = webStorage.getAMethodCall("setItem").getArgument(1).asExpr() + this = webStorage.getAMethodCall("setItem").getArgument(1) ) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll index b23f52d7c228..18230c920377 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssCustomizations.qll @@ -31,7 +31,7 @@ module DomBasedXss { ) or // call to an Angular method that interprets its argument as HTML - any(AngularJS::AngularJSCall call).interpretsArgumentAsHtml(this.asExpr()) + any(AngularJS::AngularJSCallNode call).interpretsArgumentAsHtml(this) or // call to a WinJS function that interprets its argument as HTML exists(DataFlow::MethodCallNode mcn, string m | @@ -130,12 +130,12 @@ module DomBasedXss { class DomSink extends Sink { DomSink() { // Call to a DOM function that inserts its argument into the DOM - any(DomMethodCallExpr call).interpretsArgumentsAsHtml(this.asExpr()) + any(DomMethodCallNode call).interpretsArgumentsAsHtml(this) or // Assignment to a dangerous DOM property - exists(DomPropWriteNode pw | + exists(DomPropertyWrite pw | pw.interpretsValueAsHtml() and - this = DataFlow::valueNode(pw.getRhs()) + this = pw.getRhs() ) or // `html` or `source.html` properties of React Native `WebView` @@ -159,7 +159,7 @@ module DomBasedXss { ) or exists(DataFlow::MethodCallNode ccf | - isDomValue(ccf.getReceiver().asExpr()) and + isDomNode(ccf.getReceiver()) and ccf.getMethodName() = "createContextualFragment" and this = ccf.getArgument(0) ) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll index fb663a755ed4..785677488e4e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll @@ -165,7 +165,7 @@ module ExternalApiUsedWithUntrustedData { not param = base.getReceiver() | result = param and - name = param.asSource().asExpr().(Parameter).getName() + name = param.asSource().(DataFlow::ParameterNode).getName() or param.asSource().asExpr() instanceof DestructuringPattern and result = param.getMember(name) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsCustomizations.qll index 6ad3b1a8853c..5e43e34aa8a0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedCredentialsCustomizations.qll @@ -33,12 +33,10 @@ module HardcodedCredentials { } /** - * A subclass of `Sink` that includes every `CredentialsExpr` + * A subclass of `Sink` that includes every `CredentialsNode` * as a credentials sink. */ - class DefaultCredentialsSink extends Sink, DataFlow::ValueNode { - override CredentialsExpr astNode; - - override string getKind() { result = astNode.getCredentialsKind() } + class DefaultCredentialsSink extends Sink instanceof CredentialsNode { + override string getKind() { result = super.getCredentialsKind() } } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashCustomizations.qll index 6ffcb7fa527a..1697d55fe0b1 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsufficientPasswordHashCustomizations.qll @@ -30,14 +30,12 @@ module InsufficientPasswordHash { * A potential clear-text password, considered as a source for password hashing * with insufficient computational effort. */ - class CleartextPasswordSource extends Source, DataFlow::ValueNode { - override SensitiveExpr astNode; - + class CleartextPasswordSource extends Source instanceof SensitiveNode { CleartextPasswordSource() { - astNode.getClassification() = SensitiveDataClassification::password() + super.getClassification() = SensitiveDataClassification::password() } - override string describe() { result = astNode.describe() } + override string describe() { result = SensitiveNode.super.describe() } } /** @@ -49,7 +47,7 @@ module InsufficientPasswordHash { application.getAlgorithm().isWeak() or not application.getAlgorithm() instanceof PasswordHashingAlgorithm | - this.asExpr() = application.getInput() + this = application.getInput() ) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/MissingRateLimiting.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/MissingRateLimiting.qll index b4acd922498c..7d3958d83d8d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/MissingRateLimiting.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/MissingRateLimiting.qll @@ -199,7 +199,7 @@ class RateLimiterFlexibleRateLimiter extends DataFlow::FunctionNode { rateLimiterClassName.matches("RateLimiter%") and rateLimiterClass = API::moduleImport("rate-limiter-flexible").getMember(rateLimiterClassName) and rateLimiterConsume = rateLimiterClass.getInstance().getMember("consume") and - request.getParameter() = getRouteHandlerParameter(this.getFunction(), "request") and + request = getRouteHandlerParameter(this, "request") and request.getAPropertyRead().flowsTo(rateLimiterConsume.getAParameter().asSink()) ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionCustomizations.qll index 7d4c59394403..50dd7fc00536 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionCustomizations.qll @@ -36,7 +36,5 @@ module NosqlInjection { } /** An expression interpreted as a NoSql query, viewed as a sink. */ - class NosqlQuerySink extends Sink, DataFlow::ValueNode { - override NoSql::Query astNode; - } + class NosqlQuerySink extends Sink instanceof NoSql::Query { } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll index ada9c57ad64c..be9b3bdee0a0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/NosqlInjectionQuery.qll @@ -45,7 +45,7 @@ class Configuration extends TaintTracking::Configuration { inlbl = TaintedObject::label() and outlbl = TaintedObject::label() and exists(NoSql::Query query, DataFlow::SourceNode queryObj | - queryObj.flowsToExpr(query) and + queryObj.flowsTo(query) and queryObj.flowsTo(trg) and src = queryObj.getAPropertyWrite().getRhs() ) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarCustomizations.qll index 3f8b7c7f846e..b35d564bcaf2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PostMessageStarCustomizations.qll @@ -41,9 +41,7 @@ module PostMessageStar { * A sensitive expression, viewed as a data flow source for cross-window communication * with unrestricted origin. */ - class SensitiveExprSource extends Source, DataFlow::ValueNode { - override SensitiveExpr astNode; - } + class SensitiveExprSource extends Source instanceof SensitiveNode { } /** A call to any function whose name suggests that it encodes or encrypts its arguments. */ class ProtectSanitizer extends Sanitizer { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll index 73188869256d..2969d118c60f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll @@ -24,10 +24,8 @@ 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, DataFlow::ValueNode { - override HTTP::ResponseSendArgument astNode; - - HttpResponseSink() { not exists(getANonHtmlHeaderDefinition(astNode)) } + class HttpResponseSink extends Sink instanceof HTTP::ResponseSendArgument { + HttpResponseSink() { not exists(getANonHtmlHeaderDefinition(this)) } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll index 8281a958142b..d060f91b371e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll @@ -57,11 +57,11 @@ module RemotePropertyInjection { * header names as properties. This case is already handled by * `PropertyWriteSink`. */ - class HeaderNameSink extends Sink, DataFlow::ValueNode { + class HeaderNameSink extends Sink { HeaderNameSink() { exists(HTTP::ExplicitHeaderDefinition hd | not hd instanceof Express::SetMultipleHeaders and - astNode = hd.getNameExpr() + this = hd.getNameNode() ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll index e8511ee1f5a2..db62f29c8ddf 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll @@ -33,17 +33,17 @@ module ServerSideUrlRedirect { /** * An HTTP redirect, considered as a sink for `Configuration`. */ - class RedirectSink extends Sink, DataFlow::ValueNode { - RedirectSink() { astNode = any(HTTP::RedirectInvocation redir).getUrlArgument() } + class RedirectSink extends Sink { + RedirectSink() { this = any(HTTP::RedirectInvocation redir).getUrlArgument() } } /** * A definition of the HTTP "Location" header, considered as a sink for * `Configuration`. */ - class LocationHeaderSink extends Sink, DataFlow::ValueNode { + class LocationHeaderSink extends Sink { LocationHeaderSink() { - any(HTTP::ExplicitHeaderDefinition def).definesExplicitly("location", astNode) + any(HTTP::ExplicitHeaderDefinition def).definesHeaderValue("location", this) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionCustomizations.qll index 42ffe2ea3c3b..dd6f5d79ac8a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionCustomizations.qll @@ -28,13 +28,11 @@ module SqlInjection { } /** An SQL expression passed to an API call that executes SQL. */ - class SqlInjectionExprSink extends Sink, DataFlow::ValueNode { - override SQL::SqlString astNode; - } + class SqlInjectionExprSink extends Sink instanceof SQL::SqlString { } /** An expression that sanitizes a value for the purposes of string based query injection. */ - class SanitizerExpr extends Sanitizer, DataFlow::ValueNode { - SanitizerExpr() { astNode = any(SQL::SqlSanitizer ss).getOutput() } + class SanitizerExpr extends Sanitizer { + SanitizerExpr() { this = any(SQL::SqlSanitizer ss).getOutput() } } /** An GraphQL expression passed to an API call that executes GraphQL. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll index 235926795ba4..1ee969205fdc 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll @@ -32,7 +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, DataFlow::ValueNode { - override HTTP::ResponseBody astNode; - } + class DefaultSink extends Sink instanceof HTTP::ResponseBody { } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index 03b1211326a5..c463b1d3ecbd 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -647,12 +647,12 @@ module TaintedPath { /** * A path argument to the Express `res.render` method. */ - class ExpressRenderSink extends Sink, DataFlow::ValueNode { + class ExpressRenderSink extends Sink { ExpressRenderSink() { - exists(MethodCallExpr mce | + exists(DataFlow::MethodCallNode mce | Express::isResponse(mce.getReceiver()) and mce.getMethodName() = "render" and - astNode = mce.getArgument(0) + this = mce.getArgument(0) ) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionCustomizations.qll index 06008a0266de..6191c3898731 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TemplateObjectInjectionCustomizations.qll @@ -76,8 +76,8 @@ module TemplateObjectInjection { predicate usesVulnerableTemplateEngine(Express::RouterDefinition router) { // option 1: `app.set("view engine", "theEngine")`. // Express will load the engine automatically. - exists(MethodCallExpr call | - router.flowsTo(call.getReceiver()) and + exists(DataFlow::MethodCallNode call | + router.ref().getAMethodCall() = call and call.getMethodName() = "set" and call.getArgument(0).getStringValue() = "view engine" and call.getArgument(1).getStringValue() = getAVulnerableTemplateEngine() @@ -91,11 +91,11 @@ module TemplateObjectInjection { DataFlow::MethodCallNode viewEngineCall | // `app.engine("name", engine) - router.flowsTo(registerCall.getReceiver().asExpr()) and + router.ref().getAMethodCall() = registerCall and registerCall.getMethodName() = ["engine", "register"] and engine = registerCall.getArgument(1).getALocalSource() and // app.set("view engine", "name") - router.flowsTo(viewEngineCall.getReceiver().asExpr()) and + router.ref().getAMethodCall() = viewEngineCall and viewEngineCall.getMethodName() = "set" and viewEngineCall.getArgument(0).getStringValue() = "view engine" and // The name set by the `app.engine("name")` call matches `app.set("view engine", "name")`. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombCustomizations.qll index 1d159b057ad0..7d9755ca7a51 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XmlBombCustomizations.qll @@ -31,8 +31,8 @@ module XmlBomb { /** * An access to `document.location`, considered as a flow source for XML bomb vulnerabilities. */ - class LocationAsSource extends Source, DataFlow::ValueNode { - LocationAsSource() { isLocation(astNode) } + class LocationAsSource extends Source { + LocationAsSource() { isLocationNode(this) } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XxeCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XxeCustomizations.qll index 4e7bb5e730c9..0b54c3bf301f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XxeCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XxeCustomizations.qll @@ -31,8 +31,8 @@ module Xxe { /** * An access to `document.location`, considered as a flow source for XXE vulnerabilities. */ - class LocationAsSource extends Source, DataFlow::ValueNode { - LocationAsSource() { isLocation(astNode) } + class LocationAsSource extends Source { + LocationAsSource() { isLocationNode(this) } } /** diff --git a/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql b/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql index 36a907842752..d1d411ad4470 100644 --- a/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql +++ b/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql @@ -42,17 +42,19 @@ predicate isABuiltinEventName(string name) { * Holds if user code emits or broadcasts an event named `name`. */ predicate isAUserDefinedEventName(string name) { - exists(string methodName, MethodCallExpr mce | methodName = "$emit" or methodName = "$broadcast" | - mce.getArgument(0).mayHaveStringValue(name) and + exists(string methodName, DataFlow::MethodCallNode mcn | + methodName = "$emit" or methodName = "$broadcast" + | + mcn.getArgument(0).mayHaveStringValue(name) and ( // dataflow based scope resolution - mce = any(AngularJS::ScopeServiceReference scope).getAMethodCall(methodName) + mcn = any(AngularJS::ScopeServiceReference scope).getAMethodCall(methodName) or // heuristic scope resolution: assume parameters like `$scope` or `$rootScope` are AngularJS scope objects - exists(SimpleParameter param | + exists(DataFlow::ParameterNode param | param.getName() = any(AngularJS::ScopeServiceReference scope).getName() and - mce.getReceiver().mayReferToParameter(param) and - mce.getMethodName() = methodName + param.getAMethodCall() = mcn and + mcn.getMethodName() = methodName ) or // a call in an AngularJS expression @@ -64,7 +66,7 @@ predicate isAUserDefinedEventName(string name) { ) } -from AngularJS::ScopeServiceReference scope, MethodCallExpr mce, string eventName +from AngularJS::ScopeServiceReference scope, DataFlow::MethodCallNode mce, string eventName where mce = scope.getAMethodCall("$on") and mce.getArgument(0).mayHaveStringValue(eventName) and diff --git a/javascript/ql/src/AngularJS/DependencyMismatch.ql b/javascript/ql/src/AngularJS/DependencyMismatch.ql index bbdb042bf19d..83f9b1cb73ac 100644 --- a/javascript/ql/src/AngularJS/DependencyMismatch.ql +++ b/javascript/ql/src/AngularJS/DependencyMismatch.ql @@ -14,7 +14,7 @@ import javascript -from AngularJS::InjectableFunction f, SimpleParameter p, string msg +from AngularJS::InjectableFunction f, DataFlow::ParameterNode p, string msg where p = f.asFunction().getAParameter() and ( diff --git a/javascript/ql/src/AngularJS/DisablingSce.ql b/javascript/ql/src/AngularJS/DisablingSce.ql index 7ec1b5405b21..4f164d9c55b1 100644 --- a/javascript/ql/src/AngularJS/DisablingSce.ql +++ b/javascript/ql/src/AngularJS/DisablingSce.ql @@ -14,7 +14,7 @@ import javascript -from MethodCallExpr mce, AngularJS::BuiltinServiceReference service +from DataFlow::MethodCallNode mce, AngularJS::BuiltinServiceReference service where service.getName() = "$sceProvider" and mce = service.getAMethodCall("enabled") and diff --git a/javascript/ql/src/AngularJS/DoubleCompilation.ql b/javascript/ql/src/AngularJS/DoubleCompilation.ql index 95f088d20ce2..968e493c45da 100644 --- a/javascript/ql/src/AngularJS/DoubleCompilation.ql +++ b/javascript/ql/src/AngularJS/DoubleCompilation.ql @@ -15,7 +15,7 @@ import javascript -from AngularJS::ServiceReference compile, SimpleParameter elem, CallExpr c +from AngularJS::ServiceReference compile, DataFlow::ParameterNode elem, DataFlow::CallNode c where compile.getName() = "$compile" and elem = @@ -24,7 +24,7 @@ where .(AngularJS::LinkFunction) .getElementParameter() and c = compile.getACall() and - c.getArgument(0).mayReferToParameter(elem) and + elem.flowsTo(c.getArgument(0)) and // don't flag $compile calls that specify a `maxPriority` c.getNumArgument() < 3 select c, "This call to $compile may cause double compilation of '" + elem + "'." diff --git a/javascript/ql/src/AngularJS/DuplicateDependency.ql b/javascript/ql/src/AngularJS/DuplicateDependency.ql index e0f0c4954cb8..53ed240aa542 100644 --- a/javascript/ql/src/AngularJS/DuplicateDependency.ql +++ b/javascript/ql/src/AngularJS/DuplicateDependency.ql @@ -12,16 +12,17 @@ import javascript import semmle.javascript.RestrictedLocations -predicate isRepeatedDependency(AngularJS::InjectableFunction f, string name, AstNode location) { +predicate isRepeatedDependency(AngularJS::InjectableFunction f, string name, DataFlow::Node node) { exists(int i, int j | i < j and exists(f.getDependencyDeclaration(i, name)) and - location = f.getDependencyDeclaration(j, name) + node = f.getDependencyDeclaration(j, name) ) } -from AngularJS::InjectableFunction f, AstNode node, string name +from AngularJS::InjectableFunction f, DataFlow::Node node, string name where isRepeatedDependency(f, name, node) and not count(f.asFunction().getParameterByName(name)) > 1 // avoid duplicating reports from js/duplicate-parameter-name -select f.asFunction().(FirstLineOf), "This function has a duplicate dependency '$@'.", node, name +select f.asFunction().getFunction().(FirstLineOf), "This function has a duplicate dependency '$@'.", + node, name diff --git a/javascript/ql/src/AngularJS/InsecureUrlWhitelist.ql b/javascript/ql/src/AngularJS/InsecureUrlWhitelist.ql index ac4c4772f11d..54f900a1b36b 100644 --- a/javascript/ql/src/AngularJS/InsecureUrlWhitelist.ql +++ b/javascript/ql/src/AngularJS/InsecureUrlWhitelist.ql @@ -23,7 +23,7 @@ predicate isResourceUrlWhitelist( ) { exists(AngularJS::ServiceReference service | service.getName() = "$sceDelegateProvider" and - setupCall.asExpr() = service.getAMethodCall("resourceUrlWhitelist") and + setupCall = service.getAMethodCall("resourceUrlWhitelist") and list.flowsTo(setupCall.getArgument(0)) ) } diff --git a/javascript/ql/src/AngularJS/RepeatedInjection.ql b/javascript/ql/src/AngularJS/RepeatedInjection.ql index 3f2e535fdd0d..27fb0dc2f621 100644 --- a/javascript/ql/src/AngularJS/RepeatedInjection.ql +++ b/javascript/ql/src/AngularJS/RepeatedInjection.ql @@ -12,9 +12,9 @@ import javascript import semmle.javascript.RestrictedLocations -from AngularJS::InjectableFunction f, AstNode explicitInjection +from AngularJS::InjectableFunction f, DataFlow::Node explicitInjection where count(f.getAnExplicitDependencyInjection()) > 1 and explicitInjection = f.getAnExplicitDependencyInjection() -select f.asFunction().(FirstLineOf), "This function has $@ defined in multiple places.", - explicitInjection, "dependency injections" +select f.asFunction().getFunction().(FirstLineOf), + "This function has $@ defined in multiple places.", explicitInjection, "dependency injections" diff --git a/javascript/ql/src/AngularJS/UnusedAngularDependency.ql b/javascript/ql/src/AngularJS/UnusedAngularDependency.ql index 4eb22c336953..4c5530d1a68a 100644 --- a/javascript/ql/src/AngularJS/UnusedAngularDependency.ql +++ b/javascript/ql/src/AngularJS/UnusedAngularDependency.ql @@ -13,9 +13,9 @@ import javascript import Declarations.UnusedParameter import semmle.javascript.RestrictedLocations -predicate isUnusedParameter(Function f, string msg, Parameter parameter) { +predicate isUnusedParameter(DataFlow::FunctionNode f, string msg, Parameter parameter) { exists(Variable pv | - isUnused(f, parameter, pv, _) and + isUnused(f.getFunction(), parameter, pv, _) and not isAnAccidentallyUnusedParameter(parameter) and // avoid double alerts msg = "Unused dependency " + pv.getName() + "." ) diff --git a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql index 73a20ce22494..fc402857e651 100644 --- a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql +++ b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql @@ -135,7 +135,7 @@ DataFlow::CallNode servesAPrivateFolder(string description) { */ Express::RouteSetup getAnExposingExpressSetup(string path) { result.isUseCall() and - result.getArgument([0 .. 1]) = servesAPrivateFolder(path).getEnclosingExpr() + result.getArgument([0 .. 1]) = servesAPrivateFolder(path) } /** @@ -149,7 +149,7 @@ DataFlow::CallNode getAnExposingServeSetup(string path) { from DataFlow::Node node, string path where - node = getAnExposingExpressSetup(path).flow() + node = getAnExposingExpressSetup(path) or node = getAnExposingServeSetup(path) select node, "Serves " + path + ", which can contain private information." diff --git a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql index 99e5f937f5bb..3cdd8bb3f31c 100644 --- a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql +++ b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql @@ -19,7 +19,7 @@ import DataFlow::PathGraph from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) and - not source.getNode().asExpr() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash + 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() diff --git a/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql b/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql index ace28997ccc2..89aeb49b6f41 100644 --- a/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql +++ b/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql @@ -15,13 +15,13 @@ import javascript from Routing::RouteSetup setup, Routing::RouteHandler handler, HTTP::RequestInputAccess input, - SensitiveExpr sensitive + SensitiveNode sensitive where setup.getOwnHttpMethod() = "GET" and setup.getAChild+() = handler and input.getRouteHandler() = handler.getFunction() and input.getKind() = "parameter" and - input.(DataFlow::SourceNode).flowsToExpr(sensitive) and + input.(DataFlow::SourceNode).flowsTo(sensitive) and not sensitive.getClassification() = SensitiveDataClassification::id() select input, "$@ for GET requests uses query parameter as sensitive data.", handler, "Route handler" diff --git a/javascript/ql/src/experimental/poi/PoI.qll b/javascript/ql/src/experimental/poi/PoI.qll index c51909c5c9ec..68143be6bdd5 100644 --- a/javascript/ql/src/experimental/poi/PoI.qll +++ b/javascript/ql/src/experimental/poi/PoI.qll @@ -77,7 +77,7 @@ private module StandardPoIs { UnpromotedRouteSetupPoI() { this = "UnpromotedRouteSetupPoI" } override predicate is(Node l0) { - l0 instanceof HTTP::RouteSetupCandidate and not l0.asExpr() instanceof HTTP::RouteSetup + l0 instanceof HTTP::RouteSetupCandidate and not l0 instanceof HTTP::RouteSetup } } diff --git a/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql b/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql index 361e2d8a6194..428f6b4e4b07 100644 --- a/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql +++ b/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql @@ -13,7 +13,7 @@ import CandidateTracking from HTTP::RouteSetupCandidate setup where - not setup.asExpr() instanceof HTTP::RouteSetup and + not setup instanceof HTTP::RouteSetup and exists(HTTP::RouteHandlerCandidate rh | track(rh, DataFlow::TypeTracker::end()).flowsTo(setup.getARouteHandlerArg()) ) diff --git a/javascript/ql/test/experimental/PoI/TestCustomPoIs.ql b/javascript/ql/test/experimental/PoI/TestCustomPoIs.ql index 5e73f8a4f874..1a4f9b686f01 100644 --- a/javascript/ql/test/experimental/PoI/TestCustomPoIs.ql +++ b/javascript/ql/test/experimental/PoI/TestCustomPoIs.ql @@ -16,7 +16,7 @@ class RouteHandlerAndSetupPoI extends ActivePoI { RouteHandlerAndSetupPoI() { this = "RouteHandlerAndSetupPoI" } override predicate is(Node l0, Node l1, string t1) { - l1.asExpr().(Express::RouteSetup).getARouteHandler() = l0 and t1 = "setup" + l1.(Express::RouteSetup).getARouteHandler() = l0 and t1 = "setup" } } @@ -24,9 +24,9 @@ class RouteSetupAndRouterAndRouteHandlerPoI extends ActivePoI { RouteSetupAndRouterAndRouteHandlerPoI() { this = "RouteSetupAndRouterAndRouteHandlerPoI" } override predicate is(Node l0, Node l1, string t1, Node l2, string t2) { - l0.asExpr().(Express::RouteSetup).getRouter().flow() = l1 and + l0.(Express::RouteSetup).getRouter() = l1 and t1 = "router" and - l0.asExpr().(Express::RouteSetup).getARouteHandler() = l2 and + l0.(Express::RouteSetup).getARouteHandler() = l2 and t2 = "routehandler" } } diff --git a/javascript/ql/test/library-tests/SensitiveActions/tests.ql b/javascript/ql/test/library-tests/SensitiveActions/tests.ql index 7adfe2121d3e..e1cd2cbd095b 100644 --- a/javascript/ql/test/library-tests/SensitiveActions/tests.ql +++ b/javascript/ql/test/library-tests/SensitiveActions/tests.ql @@ -20,4 +20,4 @@ query predicate processTermination(NodeJSLib::ProcessTermination term) { any() } query predicate sensitiveAction(SensitiveAction ac) { any() } -query predicate sensitiveExpr(SensitiveExpr e) { any() } +query predicate sensitiveExpr(SensitiveNode e) { any() } diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-dataflow/ScopeMethodCalls.ql b/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-dataflow/ScopeMethodCalls.ql index 612439f0be04..53a27ecdf829 100644 --- a/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-dataflow/ScopeMethodCalls.ql +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-dataflow/ScopeMethodCalls.ql @@ -1,5 +1,5 @@ import javascript -from AngularJS::ScopeServiceReference s, MethodCallExpr mce +from AngularJS::ScopeServiceReference s, DataFlow::MethodCallNode mce where mce = s.getAMethodCall(_) select mce diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-resolution/DependencyResolution_full.ql b/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-resolution/DependencyResolution_full.ql index eb12430a4563..be1f2c1aceff 100644 --- a/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-resolution/DependencyResolution_full.ql +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/dependency-resolution/DependencyResolution_full.ql @@ -1,6 +1,6 @@ import javascript private import AngularJS -from InjectableFunction f, SimpleParameter p, DataFlow::Node nd +from InjectableFunction f, DataFlow::ParameterNode p, DataFlow::Node nd where nd = f.getCustomServiceDependency(p) select p.getName(), nd diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/scopes/ScopeAccess.expected b/javascript/ql/test/library-tests/frameworks/AngularJS/scopes/ScopeAccess.expected index d7a6e49b6cd4..1560c2076bc1 100644 --- a/javascript/ql/test/library-tests/frameworks/AngularJS/scopes/ScopeAccess.expected +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/scopes/ScopeAccess.expected @@ -1,92 +1,137 @@ | isolate scope for directive1 | scope-access.js:4:41:4:45 | scope | +| isolate scope for directive1 | scope-access.js:4:41:4:45 | scope | | isolate scope for directive1 | scope-access.js:5:17:5:21 | scope | | isolate scope for directive1 | scope-access.js:7:20:7:21 | {} | | isolate scope for directive2 | scope-access.js:12:34:12:39 | $scope | +| isolate scope for directive2 | scope-access.js:12:34:12:39 | $scope | | isolate scope for directive2 | scope-access.js:13:17:13:22 | $scope | | isolate scope for directive2 | scope-access.js:15:20:15:21 | {} | | isolate scope for directive3 | scope-access.js:20:39:20:44 | $scope | +| isolate scope for directive3 | scope-access.js:20:39:20:44 | $scope | | isolate scope for directive3 | scope-access.js:21:17:21:22 | $scope | | isolate scope for directive3 | scope-access.js:23:20:23:21 | {} | | isolate scope for directive4 | scope-access.js:28:45:28:45 | a | +| isolate scope for directive4 | scope-access.js:28:45:28:45 | a | | isolate scope for directive4 | scope-access.js:29:17:29:17 | a | | isolate scope for directive4 | scope-access.js:31:20:31:21 | {} | +| isolate scope for directive5 | scope-access.js:36:25:36:24 | this | | isolate scope for directive5 | scope-access.js:37:17:37:20 | this | | isolate scope for directive5 | scope-access.js:39:20:39:21 | {} | +| isolate scope for directive6 | scope-access.js:45:25:45:24 | this | +| isolate scope for directive6 | scope-access.js:46:18:46:26 | return of anonymous function | | isolate scope for directive6 | scope-access.js:46:23:46:26 | this | | isolate scope for directive6 | scope-access.js:48:20:48:21 | {} | | isolate scope for myCustomer | dev-guide-5.js:11:12:13:5 | { // Sc ... y\\n } | | isolate scope for myCustomer | dev-guide-6.js:11:12:13:5 | { // Sc ... y\\n } | | scope for ... | scope-access.js:54:34:54:39 | $scope | +| scope for ... | scope-access.js:54:34:54:39 | $scope | | scope for ... | scope-access.js:55:17:55:22 | $scope | | scope for
... | dev-guide-1.js:4:49:4:54 | $scope | +| scope for
... | dev-guide-1.js:4:49:4:54 | $scope | +| scope for
... | dev-guide-1.js:4:49:4:54 | $scope | | scope for
... | dev-guide-1.js:5:3:5:8 | $scope | | scope for
... | dev-guide-1.js:7:3:7:8 | $scope | +| scope for
... | dev-guide-1.js:7:21:7:20 | $scope | | scope for
... | dev-guide-1.js:8:5:8:10 | $scope | | scope for
... | dev-guide-1.js:8:34:8:39 | $scope | | scope for
... | dev-guide-2.js:4:66:4:71 | $scope | +| scope for
... | dev-guide-2.js:4:66:4:71 | $scope | | scope for
... | dev-guide-2.js:5:3:5:8 | $scope | | scope for
... | dev-guide-2.js:8:51:8:56 | $scope | +| scope for
... | dev-guide-2.js:8:51:8:56 | $scope | | scope for
... | dev-guide-2.js:9:3:9:8 | $scope | | scope for
... | dev-guide-3.js:4:52:4:57 | $scope | +| scope for
... | dev-guide-3.js:4:52:4:57 | $scope | +| scope for
... | dev-guide-3.js:4:52:4:57 | $scope | | scope for
... | dev-guide-3.js:5:3:5:8 | $scope | | scope for
... | dev-guide-3.js:6:3:6:8 | $scope | +| scope for
... | dev-guide-3.js:6:25:6:24 | $scope | | scope for
... | dev-guide-3.js:7:5:7:10 | $scope | | scope for
... | dev-guide-4.js:4:52:4:57 | $scope | +| scope for
... | dev-guide-4.js:4:52:4:57 | $scope | | scope for
... | dev-guide-4.js:5:3:5:8 | $scope | | scope for
... | dev-guide-4.js:10:51:10:56 | $scope | +| scope for
... | dev-guide-4.js:10:51:10:56 | $scope | | scope for
... | dev-guide-4.js:11:3:11:8 | $scope | | scope for
... | dev-guide-5.js:4:47:4:52 | $scope | | scope for
... | dev-guide-5.js:4:47:4:52 | $scope | +| scope for
... | dev-guide-5.js:4:47:4:52 | $scope | +| scope for
... | dev-guide-5.js:4:47:4:52 | $scope | | scope for
... | dev-guide-5.js:5:3:5:8 | $scope | | scope for
... | dev-guide-5.js:5:3:5:8 | $scope | | scope for
... | dev-guide-5.js:6:3:6:8 | $scope | | scope for
... | dev-guide-5.js:6:3:6:8 | $scope | | scope for
... | dev-guide-6.js:4:47:4:52 | $scope | | scope for
... | dev-guide-6.js:4:47:4:52 | $scope | +| scope for
... | dev-guide-6.js:4:47:4:52 | $scope | +| scope for
... | dev-guide-6.js:4:47:4:52 | $scope | | scope for
... | dev-guide-6.js:5:3:5:8 | $scope | | scope for
... | dev-guide-6.js:5:3:5:8 | $scope | | scope for
... | dev-guide-6.js:6:3:6:8 | $scope | | scope for
... | dev-guide-6.js:6:3:6:8 | $scope | | scope for ... | scope-access.js:59:52:59:57 | $scope | +| scope for ... | scope-access.js:59:52:59:57 | $scope | | scope for ... | scope-access.js:60:9:60:14 | $scope | | scope for
  • ... | dev-guide-3.js:4:52:4:57 | $scope | | scope for
  • ... | dev-guide-3.js:4:52:4:57 | $scope | +| scope for
  • ... | dev-guide-3.js:4:52:4:57 | $scope | +| scope for
  • ... | dev-guide-3.js:4:52:4:57 | $scope | +| scope for
  • ... | dev-guide-3.js:4:52:4:57 | $scope | +| scope for
  • ... | dev-guide-3.js:4:52:4:57 | $scope | | scope for
  • ... | dev-guide-3.js:5:3:5:8 | $scope | | scope for
  • ... | dev-guide-3.js:5:3:5:8 | $scope | | scope for
  • ... | dev-guide-3.js:6:3:6:8 | $scope | | scope for
  • ... | dev-guide-3.js:6:3:6:8 | $scope | +| scope for
  • ... | dev-guide-3.js:6:25:6:24 | $scope | +| scope for
  • ... | dev-guide-3.js:6:25:6:24 | $scope | | scope for
  • ... | dev-guide-3.js:7:5:7:10 | $scope | | scope for
  • ... | dev-guide-3.js:7:5:7:10 | $scope | | scope in dev-guide-1.html | dev-guide-1.js:4:49:4:54 | $scope | +| scope in dev-guide-1.html | dev-guide-1.js:4:49:4:54 | $scope | +| scope in dev-guide-1.html | dev-guide-1.js:4:49:4:54 | $scope | | scope in dev-guide-1.html | dev-guide-1.js:5:3:5:8 | $scope | | scope in dev-guide-1.html | dev-guide-1.js:7:3:7:8 | $scope | +| scope in dev-guide-1.html | dev-guide-1.js:7:21:7:20 | $scope | | scope in dev-guide-1.html | dev-guide-1.js:8:5:8:10 | $scope | | scope in dev-guide-1.html | dev-guide-1.js:8:34:8:39 | $scope | | scope in dev-guide-2.html | dev-guide-2.js:4:66:4:71 | $scope | +| scope in dev-guide-2.html | dev-guide-2.js:4:66:4:71 | $scope | | scope in dev-guide-2.html | dev-guide-2.js:5:3:5:8 | $scope | | scope in dev-guide-2.html | dev-guide-2.js:8:51:8:56 | $scope | +| scope in dev-guide-2.html | dev-guide-2.js:8:51:8:56 | $scope | | scope in dev-guide-2.html | dev-guide-2.js:9:3:9:8 | $scope | | scope in dev-guide-3.html | dev-guide-3.js:4:52:4:57 | $scope | +| scope in dev-guide-3.html | dev-guide-3.js:4:52:4:57 | $scope | +| scope in dev-guide-3.html | dev-guide-3.js:4:52:4:57 | $scope | | scope in dev-guide-3.html | dev-guide-3.js:5:3:5:8 | $scope | | scope in dev-guide-3.html | dev-guide-3.js:6:3:6:8 | $scope | +| scope in dev-guide-3.html | dev-guide-3.js:6:25:6:24 | $scope | | scope in dev-guide-3.html | dev-guide-3.js:7:5:7:10 | $scope | | scope in dev-guide-4.html | dev-guide-4.js:4:52:4:57 | $scope | +| scope in dev-guide-4.html | dev-guide-4.js:4:52:4:57 | $scope | | scope in dev-guide-4.html | dev-guide-4.js:5:3:5:8 | $scope | | scope in dev-guide-4.html | dev-guide-4.js:10:51:10:56 | $scope | +| scope in dev-guide-4.html | dev-guide-4.js:10:51:10:56 | $scope | | scope in dev-guide-4.html | dev-guide-4.js:11:3:11:8 | $scope | | scope in dev-guide-5.html | dev-guide-5.js:4:47:4:52 | $scope | +| scope in dev-guide-5.html | dev-guide-5.js:4:47:4:52 | $scope | | scope in dev-guide-5.html | dev-guide-5.js:5:3:5:8 | $scope | | scope in dev-guide-5.html | dev-guide-5.js:6:3:6:8 | $scope | | scope in dev-guide-5.html | dev-guide-6.js:4:47:4:52 | $scope | +| scope in dev-guide-5.html | dev-guide-6.js:4:47:4:52 | $scope | | scope in dev-guide-5.html | dev-guide-6.js:5:3:5:8 | $scope | | scope in dev-guide-5.html | dev-guide-6.js:6:3:6:8 | $scope | | scope in dev-guide-6.html | dev-guide-5.js:4:47:4:52 | $scope | +| scope in dev-guide-6.html | dev-guide-5.js:4:47:4:52 | $scope | | scope in dev-guide-6.html | dev-guide-5.js:5:3:5:8 | $scope | | scope in dev-guide-6.html | dev-guide-5.js:6:3:6:8 | $scope | | scope in dev-guide-6.html | dev-guide-6.js:4:47:4:52 | $scope | +| scope in dev-guide-6.html | dev-guide-6.js:4:47:4:52 | $scope | | scope in dev-guide-6.html | dev-guide-6.js:5:3:5:8 | $scope | | scope in dev-guide-6.html | dev-guide-6.js:6:3:6:8 | $scope | | scope in scope-access.html | scope-access.js:54:34:54:39 | $scope | +| scope in scope-access.html | scope-access.js:54:34:54:39 | $scope | | scope in scope-access.html | scope-access.js:55:17:55:22 | $scope | | scope in scope-access.html | scope-access.js:59:52:59:57 | $scope | +| scope in scope-access.html | scope-access.js:59:52:59:57 | $scope | | scope in scope-access.html | scope-access.js:60:9:60:14 | $scope | diff --git a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll index a1db639b0218..2a7da38aee24 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll @@ -1,5 +1,7 @@ import javascript -query predicate test_HeaderDefinition_getNameExpr(HTTP::ExplicitHeaderDefinition hd, Expr res) { - hd.getRouteHandler() instanceof Express::RouteHandler and res = hd.getNameExpr() +query predicate test_HeaderDefinition_getNameExpr( + HTTP::ExplicitHeaderDefinition hd, DataFlow::Node res +) { + hd.getRouteHandler() instanceof Express::RouteHandler and res = hd.getNameNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll index b2e780fa3a58..87c0bf32b0fe 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll @@ -1,9 +1,9 @@ import javascript -query predicate test_RequestExpr(Express::RequestExpr e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Express::RequestNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } -query predicate test_RequestExprStandalone(Express::RequestExpr e) { +query predicate test_RequestExprStandalone(Express::RequestNode e) { not exists(e.getRouteHandler()) } diff --git a/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll index 25356cfd48cb..ad96e9435113 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Express::ResponseExpr e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Express::ResponseNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteExpr.qll deleted file mode 100644 index bc8010494fd3..000000000000 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteExpr.qll +++ /dev/null @@ -1,5 +0,0 @@ -import javascript - -query predicate test_RouteExpr(Express::RouteExpr e, Express::RouterDefinition res) { - res = e.getRouter() -} diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler.qll index 4873bcf2d997..5a737738b626 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler.qll @@ -1,5 +1,7 @@ import javascript -query predicate test_RouteHandler(Express::RouteHandler rh, Parameter res0, Parameter res1) { +query predicate test_RouteHandler( + Express::RouteHandler rh, DataFlow::ParameterNode res0, DataFlow::ParameterNode res1 +) { res0 = rh.getRequestParameter() and res1 = rh.getResponseParameter() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr.qll index a6c008294dd0..4d3190d34fee 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandlerExpr( - Express::RouteHandlerExpr rhe, Express::RouteSetup res0, boolean isLast + Express::RouteHandlerNode rhe, Express::RouteSetup res0, boolean isLast ) { (if rhe.isLastHandler() then isLast = true else isLast = false) and res0 = rhe.getSetup() diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAMatchingAncestor.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAMatchingAncestor.qll index b42d063bbfae..4cf5088b28d6 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAMatchingAncestor.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAMatchingAncestor.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandlerExpr_getAMatchingAncestor( - Express::RouteHandlerExpr expr, Express::RouteHandlerExpr res + Express::RouteHandlerNode expr, Express::RouteHandlerNode res ) { res = expr.getAMatchingAncestor() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAsSubRouter.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAsSubRouter.qll index 3bb2799d7fbf..10fa029b1782 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAsSubRouter.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getAsSubRouter.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandlerExpr_getAsSubRouter( - Express::RouteHandlerExpr expr, Express::RouterDefinition res + Express::RouteHandlerNode expr, Express::RouterDefinition res ) { res = expr.getAsSubRouter() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getBody.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getBody.qll index 962ef8aab5b4..7a58c892ef50 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getBody.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getBody.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandlerExpr_getBody( - Express::RouteHandlerExpr rhe, Express::RouteHandler res + Express::RouteHandlerNode rhe, Express::RouteHandler res ) { res = rhe.getBody() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getNextMiddleware.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getNextMiddleware.qll index 93d7457b2f1e..ac513215c40f 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getNextMiddleware.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getNextMiddleware.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandlerExpr_getNextMiddleware( - Express::RouteHandlerExpr expr, Express::RouteHandlerExpr res + Express::RouteHandlerNode expr, Express::RouteHandlerNode res ) { res = expr.getNextMiddleware() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getPreviousMiddleware.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getPreviousMiddleware.qll index a202198b2050..ebe1982a7bf1 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getPreviousMiddleware.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr_getPreviousMiddleware.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandlerExpr_getPreviousMiddleware( - Express::RouteHandlerExpr expr, Express::RouteHandlerExpr res + Express::RouteHandlerNode expr, Express::RouteHandlerNode res ) { res = expr.getPreviousMiddleware() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestBodyAccess.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestBodyAccess.qll index 805200c7f8d3..80800ecd7552 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestBodyAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestBodyAccess.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getARequestBodyAccess(Express::RouteHandler rh, Expr res) { +query predicate test_RouteHandler_getARequestBodyAccess(Express::RouteHandler rh, DataFlow::Node res) { res = rh.getARequestBodyAccess() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll index 77cbf26c64cb..652b0a1bbde8 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getARequestExpr(Express::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(Express::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll index 499f53fc7df4..6f9fece338d6 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getAResponseExpr(Express::RouteHandler rh, HTTP::ResponseExpr res) { - res = rh.getAResponseExpr() +query predicate test_RouteHandler_getAResponseExpr(Express::RouteHandler rh, HTTP::ResponseNode res) { + res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup.qll index d291a319a79f..26aff886cfa5 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup.qll @@ -1,6 +1,6 @@ import javascript -query predicate test_RouteSetup(Express::RouteSetup rs, Expr res0, boolean isUseCall) { +query predicate test_RouteSetup(Express::RouteSetup rs, DataFlow::Node res0, boolean isUseCall) { (if rs.isUseCall() then isUseCall = true else isUseCall = false) and res0 = rs.getServer() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getARouteHandlerExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getARouteHandlerExpr.qll index 605747a2581b..97673b157735 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getARouteHandlerExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getARouteHandlerExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteSetup_getARouteHandlerExpr(Express::RouteSetup r, Expr res) { - res = r.getARouteHandlerExpr() +query predicate test_RouteSetup_getARouteHandlerExpr(Express::RouteSetup r, DataFlow::Node res) { + res = r.getARouteHandlerNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getLastRouteHandlerExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getLastRouteHandlerExpr.qll index fd21c22a11e1..0c3336c4a75b 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getLastRouteHandlerExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getLastRouteHandlerExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteSetup_getLastRouteHandlerExpr(Express::RouteSetup r, Expr res) { - res = r.getLastRouteHandlerExpr() +query predicate test_RouteSetup_getLastRouteHandlerExpr(Express::RouteSetup r, DataFlow::Node res) { + res = r.getLastRouteHandlerNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRouteHandlerExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRouteHandlerExpr.qll index db5dccb8d005..680ef07b2ee9 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRouteHandlerExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRouteHandlerExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteSetup_getRouteHandlerExpr(Express::RouteSetup r, int i, Expr res) { - res = r.getRouteHandlerExpr(i) +query predicate test_RouteSetup_getRouteHandlerExpr(Express::RouteSetup r, int i, DataFlow::Node res) { + res = r.getRouteHandlerNode(i) } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getServer.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getServer.qll index fdb650230003..1b6e30803ac4 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getServer.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getServer.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteSetup_getServer(Express::RouteSetup rs, Expr res) { res = rs.getServer() } +query predicate test_RouteSetup_getServer(Express::RouteSetup rs, DataFlow::Node res) { + res = rs.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_handlesSameRequestMethodAs.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_handlesSameRequestMethodAs.qll index a39f945f3cab..13f37d703841 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_handlesSameRequestMethodAs.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_handlesSameRequestMethodAs.qll @@ -4,7 +4,7 @@ query predicate test_RouteSetup_handlesSameRequestMethodAs( Express::RouteSetup rs, Express::RouteSetup rs2 ) { rs.handlesSameRequestMethodAs(rs2) and - rs.getLocation().getStartLine() < rs2.getLocation().getStartLine() and - rs.getLocation().getFile().getBaseName() = "csurf-example.js" and - rs2.getLocation().getFile().getBaseName() = "csurf-example.js" + rs.asExpr().getLocation().getStartLine() < rs2.asExpr().getLocation().getStartLine() and + rs.asExpr().getLocation().getFile().getBaseName() = "csurf-example.js" and + rs2.asExpr().getLocation().getFile().getBaseName() = "csurf-example.js" } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStack.qll b/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStack.qll index ba7f8a435760..93a0d53b3ac6 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStack.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStack.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouterDefinition_getMiddlewareStack( - Express::RouterDefinition r, Express::RouteHandlerExpr res + Express::RouterDefinition r, Express::RouteHandlerNode res ) { res = r.getMiddlewareStack() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStackAt.qll b/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStackAt.qll index 36b9447abf0e..7de8ccc7114e 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStackAt.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getMiddlewareStackAt.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouterDefinition_getMiddlewareStackAt( - Express::RouterDefinition r, ControlFlowNode nd, Express::RouteHandlerExpr res + Express::RouterDefinition r, ControlFlowNode nd, Express::RouteHandlerNode res ) { res = r.getMiddlewareStackAt(nd) } diff --git a/javascript/ql/test/library-tests/frameworks/Express/StandardRouteHandler.qll b/javascript/ql/test/library-tests/frameworks/Express/StandardRouteHandler.qll index 7d5a60cfab29..2ffc514a6d05 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/StandardRouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/StandardRouteHandler.qll @@ -1,7 +1,8 @@ import javascript query predicate test_StandardRouteHandler( - Express::StandardRouteHandler rh, Expr res0, SimpleParameter res1, SimpleParameter res2 + Express::StandardRouteHandler rh, DataFlow::Node res0, DataFlow::ParameterNode res1, + DataFlow::ParameterNode res2 ) { res0 = rh.getServer() and res1 = rh.getRequestParameter() and res2 = rh.getResponseParameter() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/isRequest.qll b/javascript/ql/test/library-tests/frameworks/Express/isRequest.qll index 90c641e5be1f..9aa8ef4c9fa6 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/isRequest.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/isRequest.qll @@ -1,3 +1,3 @@ import javascript -query predicate test_isRequest(Expr nd) { Express::isRequest(nd) } +query predicate test_isRequest(DataFlow::Node nd) { Express::isRequest(nd) } diff --git a/javascript/ql/test/library-tests/frameworks/Express/isResponse.qll b/javascript/ql/test/library-tests/frameworks/Express/isResponse.qll index edc219adb67b..0ebf42be544b 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/isResponse.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/isResponse.qll @@ -1,3 +1,3 @@ import javascript -query predicate test_isResponse(Expr nd) { Express::isResponse(nd) } +query predicate test_isResponse(DataFlow::Node nd) { Express::isResponse(nd) } diff --git a/javascript/ql/test/library-tests/frameworks/Express/tests.expected b/javascript/ql/test/library-tests/frameworks/Express/tests.expected index 898a778ce1bb..cce9e29c9467 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Express/tests.expected @@ -769,50 +769,72 @@ test_RouterDefinition_getMiddlewareStackAt | src/subrouter.js:2:11:2:19 | express() | src/subrouter.js:13:1:13:0 | exit node of | src/subrouter.js:5:14:5:28 | makeSubRouter() | test_isRequest | src/advanced-routehandler-registration.js:6:7:6:9 | req | +| src/advanced-routehandler-registration.js:6:7:6:9 | req | | src/advanced-routehandler-registration.js:6:32:6:34 | req | | src/advanced-routehandler-registration.js:7:7:7:9 | req | +| src/advanced-routehandler-registration.js:7:7:7:9 | req | | src/advanced-routehandler-registration.js:7:32:7:34 | req | | src/advanced-routehandler-registration.js:15:7:15:9 | req | +| src/advanced-routehandler-registration.js:15:7:15:9 | req | | src/advanced-routehandler-registration.js:15:32:15:34 | req | | src/advanced-routehandler-registration.js:16:7:16:9 | req | +| src/advanced-routehandler-registration.js:16:7:16:9 | req | | src/advanced-routehandler-registration.js:16:32:16:34 | req | | src/advanced-routehandler-registration.js:24:7:24:9 | req | +| src/advanced-routehandler-registration.js:24:7:24:9 | req | | src/advanced-routehandler-registration.js:24:32:24:34 | req | | src/advanced-routehandler-registration.js:25:7:25:9 | req | +| src/advanced-routehandler-registration.js:25:7:25:9 | req | | src/advanced-routehandler-registration.js:25:32:25:34 | req | | src/advanced-routehandler-registration.js:46:20:46:22 | req | +| src/advanced-routehandler-registration.js:46:20:46:22 | req | | src/advanced-routehandler-registration.js:47:27:47:29 | req | | src/advanced-routehandler-registration.js:51:10:51:12 | req | +| src/advanced-routehandler-registration.js:51:10:51:12 | req | | src/advanced-routehandler-registration.js:51:40:51:42 | req | | src/advanced-routehandler-registration.js:59:20:59:22 | req | +| src/advanced-routehandler-registration.js:59:20:59:22 | req | | src/advanced-routehandler-registration.js:60:18:60:20 | req | | src/advanced-routehandler-registration.js:64:10:64:12 | req | +| src/advanced-routehandler-registration.js:64:10:64:12 | req | | src/advanced-routehandler-registration.js:64:45:64:47 | req | | src/advanced-routehandler-registration.js:68:13:68:15 | req | +| src/advanced-routehandler-registration.js:68:13:68:15 | req | | src/advanced-routehandler-registration.js:68:38:68:40 | req | | src/advanced-routehandler-registration.js:69:20:69:22 | req | +| src/advanced-routehandler-registration.js:69:20:69:22 | req | | src/advanced-routehandler-registration.js:70:18:70:20 | req | | src/advanced-routehandler-registration.js:73:10:73:12 | req | +| src/advanced-routehandler-registration.js:73:10:73:12 | req | | src/advanced-routehandler-registration.js:73:47:73:49 | req | | src/advanced-routehandler-registration.js:81:20:81:22 | req | +| src/advanced-routehandler-registration.js:81:20:81:22 | req | | src/advanced-routehandler-registration.js:82:27:82:29 | req | | src/advanced-routehandler-registration.js:92:10:92:12 | req | +| src/advanced-routehandler-registration.js:92:10:92:12 | req | | src/advanced-routehandler-registration.js:92:40:92:42 | req | | src/advanced-routehandler-registration.js:100:20:100:22 | req | +| src/advanced-routehandler-registration.js:100:20:100:22 | req | | src/advanced-routehandler-registration.js:101:31:101:33 | req | | src/advanced-routehandler-registration.js:111:10:111:12 | req | +| src/advanced-routehandler-registration.js:111:10:111:12 | req | | src/advanced-routehandler-registration.js:111:40:111:42 | req | | src/advanced-routehandler-registration.js:123:21:123:23 | req | +| src/advanced-routehandler-registration.js:123:21:123:23 | req | | src/advanced-routehandler-registration.js:123:46:123:48 | req | | src/advanced-routehandler-registration.js:124:21:124:23 | req | +| src/advanced-routehandler-registration.js:124:21:124:23 | req | | src/advanced-routehandler-registration.js:124:46:124:48 | req | | src/advanced-routehandler-registration.js:146:29:146:31 | req | | src/advanced-routehandler-registration.js:156:22:156:24 | req | +| src/advanced-routehandler-registration.js:156:22:156:24 | req | | src/advanced-routehandler-registration.js:156:47:156:49 | req | | src/advanced-routehandler-registration.js:157:28:157:30 | req | +| src/advanced-routehandler-registration.js:157:28:157:30 | req | | src/advanced-routehandler-registration.js:157:53:157:55 | req | | src/controllers/handler-in-bulk-require.js:1:45:1:47 | req | | src/csurf-example.js:20:28:20:30 | req | +| src/csurf-example.js:20:28:20:30 | req | | src/csurf-example.js:22:35:22:37 | req | | src/csurf-example.js:25:32:25:34 | req | | src/csurf-example.js:32:40:32:42 | req | @@ -820,22 +842,28 @@ test_isRequest | src/csurf-example.js:40:37:40:39 | req | | src/exportedHandler.js:1:44:1:46 | req | | src/express2.js:3:34:3:36 | req | +| src/express2.js:3:34:3:36 | req | | src/express2.js:3:46:3:48 | req | | src/express2.js:4:41:4:47 | request | +| src/express2.js:4:41:4:47 | request | | src/express2.js:4:60:4:66 | request | | src/express3.js:4:32:4:34 | req | +| src/express3.js:4:32:4:34 | req | | src/express3.js:5:14:5:16 | req | | src/express3.js:5:35:5:37 | req | | src/express3.js:10:22:10:24 | req | | src/express4.js:4:32:4:34 | req | +| src/express4.js:4:32:4:34 | req | | src/express4.js:5:27:5:29 | req | | src/express4.js:6:18:6:20 | req | | src/express4.js:7:18:7:20 | req | | src/express.js:4:32:4:34 | req | +| src/express.js:4:32:4:34 | req | | src/express.js:5:16:5:18 | req | | src/express.js:6:26:6:28 | req | | src/express.js:16:28:16:30 | req | | src/express.js:22:39:22:41 | req | +| src/express.js:22:39:22:41 | req | | src/express.js:23:3:23:5 | req | | src/express.js:24:3:24:5 | req | | src/express.js:25:3:25:5 | req | @@ -847,43 +875,55 @@ test_isRequest | src/express.js:37:22:37:24 | req | | src/express.js:42:13:42:15 | req | | src/express.js:46:31:46:33 | req | +| src/express.js:46:31:46:33 | req | | src/express.js:47:3:47:5 | req | | src/express.js:48:3:48:5 | req | | src/express.js:49:3:49:5 | req | | src/express.js:50:3:50:5 | req | | src/inheritedFromNode.js:4:24:4:26 | req | +| src/inheritedFromNode.js:4:24:4:26 | req | | src/inheritedFromNode.js:7:2:7:4 | req | | src/middleware-flow.js:5:20:5:22 | req | +| src/middleware-flow.js:5:20:5:22 | req | | src/middleware-flow.js:6:5:6:7 | req | | src/middleware-flow.js:7:5:7:7 | req | | src/middleware-flow.js:8:5:8:7 | req | | src/middleware-flow.js:17:25:17:27 | req | +| src/middleware-flow.js:17:25:17:27 | req | | src/middleware-flow.js:18:9:18:11 | req | | src/middleware-flow.js:19:9:19:11 | req | | src/middleware-flow.js:20:9:20:11 | req | | src/middleware-flow.js:23:18:23:20 | req | +| src/middleware-flow.js:23:18:23:20 | req | | src/middleware-flow.js:23:33:23:35 | req | | src/middleware-flow.js:24:18:24:20 | req | +| src/middleware-flow.js:24:18:24:20 | req | | src/middleware-flow.js:24:33:24:35 | req | | src/middleware-flow.js:39:24:39:26 | req | +| src/middleware-flow.js:39:24:39:26 | req | | src/middleware-flow.js:40:5:40:7 | req | | src/middleware-flow.js:41:5:41:7 | req | | src/middleware-flow.js:42:5:42:7 | req | | src/params.js:4:19:4:21 | req | +| src/params.js:4:19:4:21 | req | | src/params.js:5:17:5:19 | req | | src/params.js:6:17:6:19 | req | | src/params.js:14:33:14:35 | req | | src/passport.js:27:13:27:15 | req | +| src/passport.js:27:13:27:15 | req | | src/passport.js:28:2:28:4 | req | | src/responseExprs.js:4:32:4:34 | req | | src/responseExprs.js:7:32:7:34 | req | | src/responseExprs.js:10:39:10:41 | req | | src/responseExprs.js:13:32:13:34 | req | | src/responseExprs.js:16:39:16:41 | req | +| src/responseExprs.js:16:39:16:41 | req | | src/responseExprs.js:17:5:17:7 | req | | src/route-collection.js:2:7:2:9 | req | +| src/route-collection.js:2:7:2:9 | req | | src/route-collection.js:2:32:2:34 | req | | src/route-collection.js:3:7:3:9 | req | +| src/route-collection.js:3:7:3:9 | req | | src/route-collection.js:3:32:3:34 | req | | src/route.js:5:21:5:23 | req | test_RouteSetup_getRouter @@ -1067,37 +1107,52 @@ test_ResponseExpr | src/advanced-routehandler-registration.js:24:12:24:14 | res | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:25:12:25:14 | res | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:46:25:46:27 | res | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:46:25:46:27 | res | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:46:25:46:27 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:46:25:46:27 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:47:32:47:34 | res | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:47:32:47:34 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:51:15:51:17 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | +| src/advanced-routehandler-registration.js:51:15:51:17 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:51:45:51:47 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:59:25:59:27 | res | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:59:25:59:27 | res | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:59:25:59:27 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:59:25:59:27 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:60:23:60:25 | res | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:60:23:60:25 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:64:15:64:17 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | +| src/advanced-routehandler-registration.js:64:15:64:17 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:64:50:64:52 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:68:18:68:20 | res | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:68:18:68:20 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:68:18:68:20 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:69:25:69:27 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:69:25:69:27 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:69:25:69:27 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:69:25:69:27 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:70:23:70:25 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:70:23:70:25 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:73:15:73:17 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | +| src/advanced-routehandler-registration.js:73:15:73:17 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:73:52:73:54 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:81:25:81:27 | res | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:81:25:81:27 | res | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:81:25:81:27 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:81:25:81:27 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:82:32:82:34 | res | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:82:32:82:34 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:92:15:92:17 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | +| src/advanced-routehandler-registration.js:92:15:92:17 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:92:45:92:47 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:100:25:100:27 | res | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:100:25:100:27 | res | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:100:25:100:27 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:100:25:100:27 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:101:36:101:38 | res | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:101:36:101:38 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:111:15:111:17 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | +| src/advanced-routehandler-registration.js:111:15:111:17 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:111:45:111:47 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:123:26:123:28 | res | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:124:26:124:28 | res | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | @@ -1106,32 +1161,40 @@ test_ResponseExpr | src/advanced-routehandler-registration.js:157:33:157:35 | res | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | | src/controllers/handler-in-bulk-require.js:1:50:1:52 | res | src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined | | src/csurf-example.js:20:33:20:35 | res | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | +| src/csurf-example.js:20:33:20:35 | res | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | | src/csurf-example.js:22:3:22:5 | res | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | | src/csurf-example.js:25:37:25:39 | res | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | +| src/csurf-example.js:25:37:25:39 | res | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | | src/csurf-example.js:26:3:26:5 | res | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | | src/csurf-example.js:26:3:26:43 | res.sen ... here') | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | | src/csurf-example.js:32:45:32:47 | res | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | +| src/csurf-example.js:32:45:32:47 | res | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | | src/csurf-example.js:33:5:33:7 | res | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | | src/csurf-example.js:33:5:33:35 | res.sen ... here') | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | | src/csurf-example.js:39:41:39:43 | res | src/csurf-example.js:39:26:39:47 | functio ... res) {} | | src/csurf-example.js:40:42:40:44 | res | src/csurf-example.js:40:27:40:48 | functio ... res) {} | | src/exportedHandler.js:1:49:1:51 | res | src/exportedHandler.js:1:19:1:55 | functio ... res) {} | | src/express2.js:3:39:3:41 | res | src/express2.js:3:25:3:55 | functio ... , res } | +| src/express2.js:3:39:3:41 | res | src/express2.js:3:25:3:55 | functio ... , res } | | src/express2.js:3:46:3:53 | req, res | src/express2.js:3:25:3:55 | functio ... , res } | | src/express2.js:3:51:3:53 | res | src/express2.js:3:25:3:55 | functio ... , res } | | src/express2.js:4:50:4:55 | result | src/express2.js:4:32:4:76 | functio ... esult } | +| src/express2.js:4:50:4:55 | result | src/express2.js:4:32:4:76 | functio ... esult } | | src/express2.js:4:60:4:74 | request, result | src/express2.js:4:32:4:76 | functio ... esult } | | src/express2.js:4:69:4:74 | result | src/express2.js:4:32:4:76 | functio ... esult } | | src/express3.js:4:37:4:39 | res | src/express3.js:4:23:7:1 | functio ... al");\\n} | +| src/express3.js:4:37:4:39 | res | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:5:3:5:5 | res | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:5:3:5:51 | res.hea ... "val")) | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:6:3:6:5 | res | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:6:3:6:17 | res.send("val") | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:10:27:10:29 | res | src/express3.js:10:12:10:32 | functio ... res){} | | src/express4.js:4:37:4:39 | res | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | +| src/express4.js:4:37:4:39 | res | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express4.js:8:3:8:5 | res | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express4.js:8:3:8:20 | res.send(dynamic1) | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express.js:4:37:4:39 | res | src/express.js:4:23:9:1 | functio ... res);\\n} | +| src/express.js:4:37:4:39 | res | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:5:3:5:5 | res | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:6:3:6:5 | res | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:6:3:6:45 | res.hea ... rget")) | src/express.js:4:23:9:1 | functio ... res);\\n} | @@ -1139,18 +1202,22 @@ test_ResponseExpr | src/express.js:7:3:7:42 | res.hea ... plain") | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:8:7:8:9 | res | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:11:14:11:16 | arg | src/express.js:4:23:9:1 | functio ... res);\\n} | +| src/express.js:11:14:11:16 | arg | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:12:3:12:5 | arg | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:12:3:12:54 | arg.hea ... , true) | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:16:33:16:35 | res | src/express.js:16:19:18:3 | functio ... ");\\n } | +| src/express.js:16:33:16:35 | res | src/express.js:16:19:18:3 | functio ... ");\\n } | | src/express.js:17:5:17:7 | res | src/express.js:16:19:18:3 | functio ... ");\\n } | | src/express.js:17:5:17:24 | res.send("Go away.") | src/express.js:16:19:18:3 | functio ... ");\\n } | | src/express.js:22:44:22:46 | res | src/express.js:22:30:32:1 | functio ... ar');\\n} | +| src/express.js:22:44:22:46 | res | src/express.js:22:30:32:1 | functio ... ar');\\n} | | src/express.js:31:3:31:5 | res | src/express.js:22:30:32:1 | functio ... ar');\\n} | | src/express.js:31:3:31:26 | res.coo ... 'bar') | src/express.js:22:30:32:1 | functio ... ar');\\n} | | src/express.js:37:27:37:29 | res | src/express.js:37:12:37:32 | functio ... res){} | | src/express.js:42:18:42:20 | res | src/express.js:42:12:42:28 | (req, res) => f() | | src/express.js:46:36:46:38 | res | src/express.js:46:22:51:1 | functio ... ame];\\n} | | src/inheritedFromNode.js:4:29:4:31 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/inheritedFromNode.js:4:29:4:31 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:5:2:5:4 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:6:2:6:4 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/middleware-flow.js:5:25:5:27 | res | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | @@ -1159,20 +1226,27 @@ test_ResponseExpr | src/middleware-flow.js:24:23:24:25 | res | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | | src/middleware-flow.js:39:29:39:31 | res | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | | src/params.js:4:24:4:26 | res | src/params.js:4:18:12:1 | (req, r ... }\\n} | +| src/params.js:4:24:4:26 | res | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:8:9:8:11 | res | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:8:9:8:23 | res.send(value) | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:14:38:14:40 | res | src/params.js:14:24:16:1 | functio ... lo");\\n} | +| src/params.js:14:38:14:40 | res | src/params.js:14:24:16:1 | functio ... lo");\\n} | | src/params.js:15:3:15:5 | res | src/params.js:14:24:16:1 | functio ... lo");\\n} | | src/params.js:15:3:15:19 | res.send("Hello") | src/params.js:14:24:16:1 | functio ... lo");\\n} | | src/responseExprs.js:4:37:4:40 | res1 | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | +| src/responseExprs.js:4:37:4:40 | res1 | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | | src/responseExprs.js:5:5:5:8 | res1 | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | | src/responseExprs.js:7:37:7:40 | res2 | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | +| src/responseExprs.js:7:37:7:40 | res2 | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | | src/responseExprs.js:8:5:8:8 | res2 | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | | src/responseExprs.js:10:44:10:47 | res3 | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | +| src/responseExprs.js:10:44:10:47 | res3 | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | | src/responseExprs.js:11:5:11:8 | res3 | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | | src/responseExprs.js:13:37:13:40 | res4 | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | +| src/responseExprs.js:13:37:13:40 | res4 | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | | src/responseExprs.js:14:5:14:8 | res4 | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | | src/responseExprs.js:16:44:16:46 | res | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | +| src/responseExprs.js:16:44:16:46 | res | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:19:5:19:7 | res | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:19:5:19:16 | res.append() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:20:5:20:7 | res | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | @@ -1210,6 +1284,8 @@ test_ResponseExpr | src/responseExprs.js:37:5:37:28 | f(res.a ... ppend() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:37:7:37:9 | res | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:37:7:37:18 | res.append() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | +| src/responseExprs.js:39:5:41:5 | return of function f | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | +| src/responseExprs.js:39:16:39:21 | resArg | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:39:16:39:21 | resArg | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:40:16:40:21 | resArg | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:40:16:40:30 | resArg.append() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | @@ -1524,85 +1600,6 @@ test_RouteSetup_getRequestMethod | src/routesetups.js:12:1:12:16 | root.post('', h) | POST | | src/subrouter.js:9:3:9:35 | router. ... ndler1) | POST | | src/subrouter.js:10:3:10:41 | router. ... ndler2) | POST | -test_RouteExpr -| src/advanced-routehandler-registration.js:10:3:10:24 | app.get ... es0[p]) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:19:3:19:18 | app.use(handler) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:28:3:28:24 | app.get ... es2[p]) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:37:3:37:12 | app.use(h) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:51:1:51:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:64:1:64:54 | app.use ... , res)) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:73:1:73:56 | app.use ... , res)) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:92:1:92:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:111:1:111:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:116:3:116:31 | app.get ... tes[p]) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:118:1:118:30 | app.get ... utes.a) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:119:1:119:30 | app.get ... utes.b) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:125:29:125:41 | app.get(k, v) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:126:1:126:32 | app.get ... t("a")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:127:1:127:32 | app.get ... t("b")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:135:2:135:53 | app.get ... andler) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:139:1:139:58 | app.get ... andler) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:144:1:144:32 | app.use ... , args) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:147:1:147:37 | app.use ... (data)) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:150:2:150:14 | app.get(k, v) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:153:1:153:41 | app.get ... KEY!")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:160:1:160:33 | app.get ... t("c")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:161:1:161:39 | app.get ... own())) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:162:1:162:23 | app.get ... nown()) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/advanced-routehandler-registration.js:163:1:163:33 | app.get ... t("f")) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | -| src/auth.js:4:1:4:53 | app.use ... d' }})) | src/auth.js:1:13:1:32 | require('express')() | -| src/csurf-example.js:13:1:13:20 | app.use('/api', api) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:16:1:16:51 | app.use ... lse })) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:17:1:17:23 | app.use ... rser()) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:18:1:18:31 | app.use ... rue })) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:20:1:23:2 | app.get ... ) })\\n}) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:25:1:27:2 | app.pos ... re')\\n}) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:32:3:34:4 | router. ... ')\\n }) | src/csurf-example.js:30:16:30:35 | new express.Router() | -| src/csurf-example.js:39:1:39:48 | app.get ... es) {}) | src/csurf-example.js:7:11:7:19 | express() | -| src/csurf-example.js:40:1:40:49 | app.pos ... es) {}) | src/csurf-example.js:7:11:7:19 | express() | -| src/express2.js:2:14:2:23 | e.Router() | src/express2.js:2:14:2:23 | e.Router() | -| src/express2.js:3:1:3:56 | router. ... res }) | src/express2.js:2:14:2:23 | e.Router() | -| src/express2.js:3:1:4:77 | router. ... sult }) | src/express2.js:2:14:2:23 | e.Router() | -| src/express2.js:6:1:6:15 | app.use(router) | src/express2.js:5:11:5:13 | e() | -| src/express3.js:4:1:7:2 | app.get ... l");\\n}) | src/express3.js:2:11:2:19 | express() | -| src/express3.js:12:1:12:21 | app.use ... dler()) | src/express3.js:2:11:2:19 | express() | -| src/express4.js:4:1:9:2 | app.get ... c1);\\n}) | src/express4.js:2:11:2:19 | express() | -| src/express.js:4:1:9:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | -| src/express.js:16:3:18:4 | router. ... );\\n }) | src/express.js:2:11:2:19 | express() | -| src/express.js:22:1:32:2 | app.pos ... r');\\n}) | src/express.js:2:11:2:19 | express() | -| src/express.js:34:1:34:53 | app.get ... andler) | src/express.js:2:11:2:19 | express() | -| src/express.js:39:1:39:21 | app.use ... dler()) | src/express.js:2:11:2:19 | express() | -| src/express.js:44:1:44:26 | app.use ... dler()) | src/express.js:2:11:2:19 | express() | -| src/express.js:46:1:51:2 | app.pos ... me];\\n}) | src/express.js:2:11:2:19 | express() | -| src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:2:11:2:19 | express() | -| src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:2:13:2:21 | express() | -| src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:2:13:2:21 | express() | -| src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | src/middleware-flow.js:2:13:2:21 | express() | -| src/middleware-flow.js:39:1:43:2 | unrelat ... .db;\\n}) | src/middleware-flow.js:37:22:37:30 | express() | -| src/params.js:4:1:12:2 | app.par ... }\\n}) | src/params.js:2:11:2:19 | express() | -| src/params.js:4:1:12:2 | app.par ... }\\n}) | src/params.js:4:1:12:2 | app.par ... }\\n}) | -| src/params.js:14:1:16:2 | app.get ... o");\\n}) | src/params.js:2:11:2:19 | express() | -| src/responseExprs.js:4:1:6:2 | app.get ... res1\\n}) | src/responseExprs.js:2:11:2:19 | express() | -| src/responseExprs.js:7:1:9:2 | app.get ... es2;\\n}) | src/responseExprs.js:2:11:2:19 | express() | -| src/responseExprs.js:10:1:12:2 | app.get ... es3;\\n}) | src/responseExprs.js:2:11:2:19 | express() | -| src/responseExprs.js:13:1:15:2 | app.get ... es4;\\n}) | src/responseExprs.js:2:11:2:19 | express() | -| src/responseExprs.js:16:1:42:2 | app.pos ... }\\n}) | src/responseExprs.js:2:11:2:19 | express() | -| src/route.js:2:14:2:29 | express.Router() | src/route.js:2:14:2:29 | express.Router() | -| src/route.js:4:1:4:31 | router. ... er_id') | src/route.js:2:14:2:29 | express.Router() | -| src/route.js:4:1:5:39 | router. ... xt) {}) | src/route.js:2:14:2:29 | express.Router() | -| src/routesetups.js:3:1:3:16 | express.Router() | src/routesetups.js:3:1:3:16 | express.Router() | -| src/routesetups.js:3:1:4:14 | express ... ('', h) | src/routesetups.js:3:1:3:16 | express.Router() | -| src/routesetups.js:3:1:5:12 | express ... ('', h) | src/routesetups.js:3:1:3:16 | express.Router() | -| src/routesetups.js:7:11:7:32 | express ... erver() | src/routesetups.js:7:11:7:32 | express ... erver() | -| src/routesetups.js:8:1:8:12 | app.error(h) | src/routesetups.js:7:11:7:32 | express ... erver() | -| src/routesetups.js:10:14:10:29 | express.Router() | src/routesetups.js:10:14:10:29 | express.Router() | -| src/routesetups.js:11:12:11:28 | router.route('/') | src/routesetups.js:10:14:10:29 | express.Router() | -| src/routesetups.js:12:1:12:16 | root.post('', h) | src/routesetups.js:10:14:10:29 | express.Router() | -| src/subrouter.js:4:1:4:26 | app.use ... rotect) | src/subrouter.js:2:11:2:19 | express() | -| src/subrouter.js:5:1:5:29 | app.use ... uter()) | src/subrouter.js:2:11:2:19 | express() | -| src/subrouter.js:8:16:8:31 | express.Router() | src/subrouter.js:8:16:8:31 | express.Router() | -| src/subrouter.js:9:3:9:35 | router. ... ndler1) | src/subrouter.js:8:16:8:31 | express.Router() | -| src/subrouter.js:10:3:10:41 | router. ... ndler2) | src/subrouter.js:8:16:8:31 | express.Router() | test_RouteHandler_getAResponseExpr | src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:6:12:6:14 | res | | src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:7:12:7:14 | res | @@ -1611,37 +1608,52 @@ test_RouteHandler_getAResponseExpr | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:12:24:14 | res | | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:12:25:14 | res | | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:25:46:27 | res | +| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:25:46:27 | res | | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:47:32:47:34 | res | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:46:25:46:27 | res | +| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:46:25:46:27 | res | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:47:32:47:34 | res | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:15:51:17 | res | +| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:15:51:17 | res | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:45:51:47 | res | | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:25:59:27 | res | +| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:25:59:27 | res | | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:60:23:60:25 | res | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:59:25:59:27 | res | +| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:59:25:59:27 | res | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:60:23:60:25 | res | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:15:64:17 | res | +| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:15:64:17 | res | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:50:64:52 | res | | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:18:68:20 | res | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:18:68:20 | res | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:25:69:27 | res | +| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:25:69:27 | res | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:70:23:70:25 | res | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:18:68:20 | res | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:69:25:69:27 | res | +| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:69:25:69:27 | res | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:70:23:70:25 | res | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:15:73:17 | res | +| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:15:73:17 | res | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:52:73:54 | res | | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:25:81:27 | res | +| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:25:81:27 | res | | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:82:32:82:34 | res | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:81:25:81:27 | res | +| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:81:25:81:27 | res | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:82:32:82:34 | res | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:15:92:17 | res | +| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:15:92:17 | res | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:45:92:47 | res | | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:25:100:27 | res | +| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:25:100:27 | res | | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:101:36:101:38 | res | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:100:25:100:27 | res | +| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:100:25:100:27 | res | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:101:36:101:38 | res | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:15:111:17 | res | +| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:15:111:17 | res | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:45:111:47 | res | | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:26:123:28 | res | | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:26:124:28 | res | @@ -1650,32 +1662,40 @@ test_RouteHandler_getAResponseExpr | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:33:157:35 | res | | src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined | src/controllers/handler-in-bulk-require.js:1:50:1:52 | res | | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:20:33:20:35 | res | +| src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:20:33:20:35 | res | | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:22:3:22:5 | res | | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | src/csurf-example.js:25:37:25:39 | res | +| src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | src/csurf-example.js:25:37:25:39 | res | | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | src/csurf-example.js:26:3:26:5 | res | | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | src/csurf-example.js:26:3:26:43 | res.sen ... here') | | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | src/csurf-example.js:32:45:32:47 | res | +| src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | src/csurf-example.js:32:45:32:47 | res | | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | src/csurf-example.js:33:5:33:7 | res | | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | src/csurf-example.js:33:5:33:35 | res.sen ... here') | | src/csurf-example.js:39:26:39:47 | functio ... res) {} | src/csurf-example.js:39:41:39:43 | res | | src/csurf-example.js:40:27:40:48 | functio ... res) {} | src/csurf-example.js:40:42:40:44 | res | | src/exportedHandler.js:1:19:1:55 | functio ... res) {} | src/exportedHandler.js:1:49:1:51 | res | | src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:39:3:41 | res | +| src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:39:3:41 | res | | src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:46:3:53 | req, res | | src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:51:3:53 | res | | src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:50:4:55 | result | +| src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:50:4:55 | result | | src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:60:4:74 | request, result | | src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:69:4:74 | result | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:4:37:4:39 | res | +| src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:4:37:4:39 | res | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:5:3:5:5 | res | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:5:3:5:51 | res.hea ... "val")) | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:6:3:6:5 | res | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:6:3:6:17 | res.send("val") | | src/express3.js:10:12:10:32 | functio ... res){} | src/express3.js:10:27:10:29 | res | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:4:37:4:39 | res | +| src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:4:37:4:39 | res | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:8:3:8:5 | res | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:8:3:8:20 | res.send(dynamic1) | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:4:37:4:39 | res | +| src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:4:37:4:39 | res | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:5:3:5:5 | res | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:6:3:6:5 | res | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:6:3:6:45 | res.hea ... rget")) | @@ -1683,18 +1703,22 @@ test_RouteHandler_getAResponseExpr | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:7:3:7:42 | res.hea ... plain") | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:8:7:8:9 | res | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:11:14:11:16 | arg | +| src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:11:14:11:16 | arg | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:12:3:12:5 | arg | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:12:3:12:54 | arg.hea ... , true) | | src/express.js:16:19:18:3 | functio ... ");\\n } | src/express.js:16:33:16:35 | res | +| src/express.js:16:19:18:3 | functio ... ");\\n } | src/express.js:16:33:16:35 | res | | src/express.js:16:19:18:3 | functio ... ");\\n } | src/express.js:17:5:17:7 | res | | src/express.js:16:19:18:3 | functio ... ");\\n } | src/express.js:17:5:17:24 | res.send("Go away.") | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:22:44:22:46 | res | +| src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:22:44:22:46 | res | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:31:3:31:5 | res | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:31:3:31:26 | res.coo ... 'bar') | | src/express.js:37:12:37:32 | functio ... res){} | src/express.js:37:27:37:29 | res | | src/express.js:42:12:42:28 | (req, res) => f() | src/express.js:42:18:42:20 | res | | src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:46:36:46:38 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:29:4:31 | res | +| src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:29:4:31 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:5:2:5:4 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:6:2:6:4 | res | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:25:5:27 | res | @@ -1703,20 +1727,27 @@ test_RouteHandler_getAResponseExpr | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | src/middleware-flow.js:24:23:24:25 | res | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:39:29:39:31 | res | | src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:4:24:4:26 | res | +| src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:4:24:4:26 | res | | src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:8:9:8:11 | res | | src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:8:9:8:23 | res.send(value) | | src/params.js:14:24:16:1 | functio ... lo");\\n} | src/params.js:14:38:14:40 | res | +| src/params.js:14:24:16:1 | functio ... lo");\\n} | src/params.js:14:38:14:40 | res | | src/params.js:14:24:16:1 | functio ... lo");\\n} | src/params.js:15:3:15:5 | res | | src/params.js:14:24:16:1 | functio ... lo");\\n} | src/params.js:15:3:15:19 | res.send("Hello") | | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | src/responseExprs.js:4:37:4:40 | res1 | +| src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | src/responseExprs.js:4:37:4:40 | res1 | | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | src/responseExprs.js:5:5:5:8 | res1 | | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | src/responseExprs.js:7:37:7:40 | res2 | +| src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | src/responseExprs.js:7:37:7:40 | res2 | | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | src/responseExprs.js:8:5:8:8 | res2 | | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | src/responseExprs.js:10:44:10:47 | res3 | +| src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | src/responseExprs.js:10:44:10:47 | res3 | | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | src/responseExprs.js:11:5:11:8 | res3 | | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | src/responseExprs.js:13:37:13:40 | res4 | +| src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | src/responseExprs.js:13:37:13:40 | res4 | | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | src/responseExprs.js:14:5:14:8 | res4 | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:16:44:16:46 | res | +| src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:16:44:16:46 | res | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:19:5:19:7 | res | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:19:5:19:16 | res.append() | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:20:5:20:7 | res | @@ -1754,6 +1785,8 @@ test_RouteHandler_getAResponseExpr | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:37:5:37:28 | f(res.a ... ppend() | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:37:7:37:9 | res | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:37:7:37:18 | res.append() | +| src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:39:5:41:5 | return of function f | +| src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:39:16:39:21 | resArg | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:39:16:39:21 | resArg | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:40:16:40:21 | resArg | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:40:16:40:30 | resArg.append() | @@ -1768,25 +1801,35 @@ test_isResponse | src/advanced-routehandler-registration.js:24:12:24:14 | res | | src/advanced-routehandler-registration.js:25:12:25:14 | res | | src/advanced-routehandler-registration.js:46:25:46:27 | res | +| src/advanced-routehandler-registration.js:46:25:46:27 | res | | src/advanced-routehandler-registration.js:47:32:47:34 | res | | src/advanced-routehandler-registration.js:51:15:51:17 | res | +| src/advanced-routehandler-registration.js:51:15:51:17 | res | | src/advanced-routehandler-registration.js:51:45:51:47 | res | | src/advanced-routehandler-registration.js:59:25:59:27 | res | +| src/advanced-routehandler-registration.js:59:25:59:27 | res | | src/advanced-routehandler-registration.js:60:23:60:25 | res | | src/advanced-routehandler-registration.js:64:15:64:17 | res | +| src/advanced-routehandler-registration.js:64:15:64:17 | res | | src/advanced-routehandler-registration.js:64:50:64:52 | res | | src/advanced-routehandler-registration.js:68:18:68:20 | res | | src/advanced-routehandler-registration.js:69:25:69:27 | res | +| src/advanced-routehandler-registration.js:69:25:69:27 | res | | src/advanced-routehandler-registration.js:70:23:70:25 | res | | src/advanced-routehandler-registration.js:73:15:73:17 | res | +| src/advanced-routehandler-registration.js:73:15:73:17 | res | | src/advanced-routehandler-registration.js:73:52:73:54 | res | | src/advanced-routehandler-registration.js:81:25:81:27 | res | +| src/advanced-routehandler-registration.js:81:25:81:27 | res | | src/advanced-routehandler-registration.js:82:32:82:34 | res | | src/advanced-routehandler-registration.js:92:15:92:17 | res | +| src/advanced-routehandler-registration.js:92:15:92:17 | res | | src/advanced-routehandler-registration.js:92:45:92:47 | res | | src/advanced-routehandler-registration.js:100:25:100:27 | res | +| src/advanced-routehandler-registration.js:100:25:100:27 | res | | src/advanced-routehandler-registration.js:101:36:101:38 | res | | src/advanced-routehandler-registration.js:111:15:111:17 | res | +| src/advanced-routehandler-registration.js:111:15:111:17 | res | | src/advanced-routehandler-registration.js:111:45:111:47 | res | | src/advanced-routehandler-registration.js:123:26:123:28 | res | | src/advanced-routehandler-registration.js:124:26:124:28 | res | @@ -1795,32 +1838,40 @@ test_isResponse | src/advanced-routehandler-registration.js:157:33:157:35 | res | | src/controllers/handler-in-bulk-require.js:1:50:1:52 | res | | src/csurf-example.js:20:33:20:35 | res | +| src/csurf-example.js:20:33:20:35 | res | | src/csurf-example.js:22:3:22:5 | res | | src/csurf-example.js:25:37:25:39 | res | +| src/csurf-example.js:25:37:25:39 | res | | src/csurf-example.js:26:3:26:5 | res | | src/csurf-example.js:26:3:26:43 | res.sen ... here') | | src/csurf-example.js:32:45:32:47 | res | +| src/csurf-example.js:32:45:32:47 | res | | src/csurf-example.js:33:5:33:7 | res | | src/csurf-example.js:33:5:33:35 | res.sen ... here') | | src/csurf-example.js:39:41:39:43 | res | | src/csurf-example.js:40:42:40:44 | res | | src/exportedHandler.js:1:49:1:51 | res | | src/express2.js:3:39:3:41 | res | +| src/express2.js:3:39:3:41 | res | | src/express2.js:3:46:3:53 | req, res | | src/express2.js:3:51:3:53 | res | | src/express2.js:4:50:4:55 | result | +| src/express2.js:4:50:4:55 | result | | src/express2.js:4:60:4:74 | request, result | | src/express2.js:4:69:4:74 | result | | src/express3.js:4:37:4:39 | res | +| src/express3.js:4:37:4:39 | res | | src/express3.js:5:3:5:5 | res | | src/express3.js:5:3:5:51 | res.hea ... "val")) | | src/express3.js:6:3:6:5 | res | | src/express3.js:6:3:6:17 | res.send("val") | | src/express3.js:10:27:10:29 | res | | src/express4.js:4:37:4:39 | res | +| src/express4.js:4:37:4:39 | res | | src/express4.js:8:3:8:5 | res | | src/express4.js:8:3:8:20 | res.send(dynamic1) | | src/express.js:4:37:4:39 | res | +| src/express.js:4:37:4:39 | res | | src/express.js:5:3:5:5 | res | | src/express.js:6:3:6:5 | res | | src/express.js:6:3:6:45 | res.hea ... rget")) | @@ -1828,18 +1879,22 @@ test_isResponse | src/express.js:7:3:7:42 | res.hea ... plain") | | src/express.js:8:7:8:9 | res | | src/express.js:11:14:11:16 | arg | +| src/express.js:11:14:11:16 | arg | | src/express.js:12:3:12:5 | arg | | src/express.js:12:3:12:54 | arg.hea ... , true) | | src/express.js:16:33:16:35 | res | +| src/express.js:16:33:16:35 | res | | src/express.js:17:5:17:7 | res | | src/express.js:17:5:17:24 | res.send("Go away.") | | src/express.js:22:44:22:46 | res | +| src/express.js:22:44:22:46 | res | | src/express.js:31:3:31:5 | res | | src/express.js:31:3:31:26 | res.coo ... 'bar') | | src/express.js:37:27:37:29 | res | | src/express.js:42:18:42:20 | res | | src/express.js:46:36:46:38 | res | | src/inheritedFromNode.js:4:29:4:31 | res | +| src/inheritedFromNode.js:4:29:4:31 | res | | src/inheritedFromNode.js:5:2:5:4 | res | | src/inheritedFromNode.js:6:2:6:4 | res | | src/middleware-flow.js:5:25:5:27 | res | @@ -1848,20 +1903,27 @@ test_isResponse | src/middleware-flow.js:24:23:24:25 | res | | src/middleware-flow.js:39:29:39:31 | res | | src/params.js:4:24:4:26 | res | +| src/params.js:4:24:4:26 | res | | src/params.js:8:9:8:11 | res | | src/params.js:8:9:8:23 | res.send(value) | | src/params.js:14:38:14:40 | res | +| src/params.js:14:38:14:40 | res | | src/params.js:15:3:15:5 | res | | src/params.js:15:3:15:19 | res.send("Hello") | | src/responseExprs.js:4:37:4:40 | res1 | +| src/responseExprs.js:4:37:4:40 | res1 | | src/responseExprs.js:5:5:5:8 | res1 | | src/responseExprs.js:7:37:7:40 | res2 | +| src/responseExprs.js:7:37:7:40 | res2 | | src/responseExprs.js:8:5:8:8 | res2 | | src/responseExprs.js:10:44:10:47 | res3 | +| src/responseExprs.js:10:44:10:47 | res3 | | src/responseExprs.js:11:5:11:8 | res3 | | src/responseExprs.js:13:37:13:40 | res4 | +| src/responseExprs.js:13:37:13:40 | res4 | | src/responseExprs.js:14:5:14:8 | res4 | | src/responseExprs.js:16:44:16:46 | res | +| src/responseExprs.js:16:44:16:46 | res | | src/responseExprs.js:19:5:19:7 | res | | src/responseExprs.js:19:5:19:16 | res.append() | | src/responseExprs.js:20:5:20:7 | res | @@ -1899,6 +1961,8 @@ test_isResponse | src/responseExprs.js:37:5:37:28 | f(res.a ... ppend() | | src/responseExprs.js:37:7:37:9 | res | | src/responseExprs.js:37:7:37:18 | res.append() | +| src/responseExprs.js:39:5:41:5 | return of function f | +| src/responseExprs.js:39:16:39:21 | resArg | | src/responseExprs.js:39:16:39:21 | resArg | | src/responseExprs.js:40:16:40:21 | resArg | | src/responseExprs.js:40:16:40:30 | resArg.append() | @@ -2547,64 +2611,93 @@ test_RouteHandlerExpr_getPreviousMiddleware | src/subrouter.js:5:14:5:28 | makeSubRouter() | src/subrouter.js:4:19:4:25 | protect | test_RequestExpr | src/advanced-routehandler-registration.js:6:7:6:9 | req | src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:6:7:6:9 | req | src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:6:32:6:34 | req | src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:7:7:7:9 | req | src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:7:7:7:9 | req | src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:7:32:7:34 | req | src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:15:7:15:9 | req | src/advanced-routehandler-registration.js:15:6:15:35 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:15:7:15:9 | req | src/advanced-routehandler-registration.js:15:6:15:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:15:32:15:34 | req | src/advanced-routehandler-registration.js:15:6:15:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:16:7:16:9 | req | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:16:7:16:9 | req | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:16:32:16:34 | req | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:24:7:24:9 | req | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:24:7:24:9 | req | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:24:32:24:34 | req | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:25:7:25:9 | req | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:25:7:25:9 | req | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:25:32:25:34 | req | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:47:27:47:29 | req | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:47:27:47:29 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:51:10:51:12 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | +| src/advanced-routehandler-registration.js:51:10:51:12 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:51:40:51:42 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:60:18:60:20 | req | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:60:18:60:20 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:64:10:64:12 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | +| src/advanced-routehandler-registration.js:64:10:64:12 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:64:45:64:47 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | +| src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:68:38:68:40 | req | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:68:38:68:40 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:68:38:68:40 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:70:18:70:20 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:70:18:70:20 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:73:10:73:12 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | +| src/advanced-routehandler-registration.js:73:10:73:12 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:73:47:73:49 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | | src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:82:27:82:29 | req | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:82:27:82:29 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:92:10:92:12 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | +| src/advanced-routehandler-registration.js:92:10:92:12 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:92:40:92:42 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | +| src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:101:31:101:33 | req | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | | src/advanced-routehandler-registration.js:101:31:101:33 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:111:10:111:12 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | +| src/advanced-routehandler-registration.js:111:10:111:12 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:111:40:111:42 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:123:21:123:23 | req | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:123:21:123:23 | req | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:123:46:123:48 | req | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:124:21:124:23 | req | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:124:21:124:23 | req | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:124:46:124:48 | req | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:146:29:146:31 | req | src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined | | src/advanced-routehandler-registration.js:156:22:156:24 | req | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:156:22:156:24 | req | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:156:47:156:49 | req | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:157:28:157:30 | req | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | +| src/advanced-routehandler-registration.js:157:28:157:30 | req | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | | src/advanced-routehandler-registration.js:157:53:157:55 | req | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | | src/controllers/handler-in-bulk-require.js:1:45:1:47 | req | src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined | | src/csurf-example.js:20:28:20:30 | req | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | +| src/csurf-example.js:20:28:20:30 | req | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | | src/csurf-example.js:22:35:22:37 | req | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | | src/csurf-example.js:25:32:25:34 | req | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | | src/csurf-example.js:32:40:32:42 | req | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | @@ -2612,22 +2705,28 @@ test_RequestExpr | src/csurf-example.js:40:37:40:39 | req | src/csurf-example.js:40:27:40:48 | functio ... res) {} | | src/exportedHandler.js:1:44:1:46 | req | src/exportedHandler.js:1:19:1:55 | functio ... res) {} | | src/express2.js:3:34:3:36 | req | src/express2.js:3:25:3:55 | functio ... , res } | +| src/express2.js:3:34:3:36 | req | src/express2.js:3:25:3:55 | functio ... , res } | | src/express2.js:3:46:3:48 | req | src/express2.js:3:25:3:55 | functio ... , res } | | src/express2.js:4:41:4:47 | request | src/express2.js:4:32:4:76 | functio ... esult } | +| src/express2.js:4:41:4:47 | request | src/express2.js:4:32:4:76 | functio ... esult } | | src/express2.js:4:60:4:66 | request | src/express2.js:4:32:4:76 | functio ... esult } | | src/express3.js:4:32:4:34 | req | src/express3.js:4:23:7:1 | functio ... al");\\n} | +| src/express3.js:4:32:4:34 | req | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:5:14:5:16 | req | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:5:35:5:37 | req | src/express3.js:4:23:7:1 | functio ... al");\\n} | | src/express3.js:10:22:10:24 | req | src/express3.js:10:12:10:32 | functio ... res){} | | src/express4.js:4:32:4:34 | req | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | +| src/express4.js:4:32:4:34 | req | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express4.js:5:27:5:29 | req | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express4.js:6:18:6:20 | req | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express4.js:7:18:7:20 | req | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | | src/express.js:4:32:4:34 | req | src/express.js:4:23:9:1 | functio ... res);\\n} | +| src/express.js:4:32:4:34 | req | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:5:16:5:18 | req | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:6:26:6:28 | req | src/express.js:4:23:9:1 | functio ... res);\\n} | | src/express.js:16:28:16:30 | req | src/express.js:16:19:18:3 | functio ... ");\\n } | | src/express.js:22:39:22:41 | req | src/express.js:22:30:32:1 | functio ... ar');\\n} | +| src/express.js:22:39:22:41 | req | src/express.js:22:30:32:1 | functio ... ar');\\n} | | src/express.js:23:3:23:5 | req | src/express.js:22:30:32:1 | functio ... ar');\\n} | | src/express.js:24:3:24:5 | req | src/express.js:22:30:32:1 | functio ... ar');\\n} | | src/express.js:25:3:25:5 | req | src/express.js:22:30:32:1 | functio ... ar');\\n} | @@ -2639,47 +2738,60 @@ test_RequestExpr | src/express.js:37:22:37:24 | req | src/express.js:37:12:37:32 | functio ... res){} | | src/express.js:42:13:42:15 | req | src/express.js:42:12:42:28 | (req, res) => f() | | src/express.js:46:31:46:33 | req | src/express.js:46:22:51:1 | functio ... ame];\\n} | +| src/express.js:46:31:46:33 | req | src/express.js:46:22:51:1 | functio ... ame];\\n} | | src/express.js:47:3:47:5 | req | src/express.js:46:22:51:1 | functio ... ame];\\n} | | src/express.js:48:3:48:5 | req | src/express.js:46:22:51:1 | functio ... ame];\\n} | | src/express.js:49:3:49:5 | req | src/express.js:46:22:51:1 | functio ... ame];\\n} | | src/express.js:50:3:50:5 | req | src/express.js:46:22:51:1 | functio ... ame];\\n} | | src/inheritedFromNode.js:4:24:4:26 | req | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/inheritedFromNode.js:4:24:4:26 | req | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:7:2:7:4 | req | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/middleware-flow.js:5:20:5:22 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | +| src/middleware-flow.js:5:20:5:22 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:6:5:6:7 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:7:5:7:7 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:8:5:8:7 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:17:25:17:27 | req | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | +| src/middleware-flow.js:17:25:17:27 | req | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:18:9:18:11 | req | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:19:9:19:11 | req | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:20:9:20:11 | req | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:23:18:23:20 | req | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | +| src/middleware-flow.js:23:18:23:20 | req | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | | src/middleware-flow.js:23:33:23:35 | req | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | | src/middleware-flow.js:24:18:24:20 | req | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | +| src/middleware-flow.js:24:18:24:20 | req | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | | src/middleware-flow.js:24:33:24:35 | req | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | | src/middleware-flow.js:39:24:39:26 | req | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | +| src/middleware-flow.js:39:24:39:26 | req | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | | src/middleware-flow.js:40:5:40:7 | req | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | | src/middleware-flow.js:41:5:41:7 | req | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | | src/middleware-flow.js:42:5:42:7 | req | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | | src/params.js:4:19:4:21 | req | src/params.js:4:18:12:1 | (req, r ... }\\n} | +| src/params.js:4:19:4:21 | req | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:5:17:5:19 | req | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:6:17:6:19 | req | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:14:33:14:35 | req | src/params.js:14:24:16:1 | functio ... lo");\\n} | | src/passport.js:27:13:27:15 | req | src/passport.js:27:4:29:1 | functio ... ccss`\\n} | +| src/passport.js:27:13:27:15 | req | src/passport.js:27:4:29:1 | functio ... ccss`\\n} | | src/passport.js:28:2:28:4 | req | src/passport.js:27:4:29:1 | functio ... ccss`\\n} | | src/responseExprs.js:4:32:4:34 | req | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | | src/responseExprs.js:7:32:7:34 | req | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | | src/responseExprs.js:10:39:10:41 | req | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | | src/responseExprs.js:13:32:13:34 | req | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | | src/responseExprs.js:16:39:16:41 | req | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | +| src/responseExprs.js:16:39:16:41 | req | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:17:5:17:7 | req | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/route-collection.js:2:7:2:9 | req | src/route-collection.js:2:6:2:35 | (req, r ... og(req) | +| src/route-collection.js:2:7:2:9 | req | src/route-collection.js:2:6:2:35 | (req, r ... og(req) | | src/route-collection.js:2:32:2:34 | req | src/route-collection.js:2:6:2:35 | (req, r ... og(req) | | src/route-collection.js:3:7:3:9 | req | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | +| src/route-collection.js:3:7:3:9 | req | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | | src/route-collection.js:3:32:3:34 | req | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | | src/route.js:5:21:5:23 | req | src/route.js:5:12:5:38 | functio ... ext) {} | test_RequestExprStandalone | typed_src/tst.ts:5:15:5:15 | x | +| typed_src/tst.ts:5:15:5:15 | x | | typed_src/tst.ts:6:3:6:3 | x | test_RouteHandlerExpr_getAsSubRouter | src/csurf-example.js:13:17:13:19 | api | src/csurf-example.js:30:16:30:35 | new express.Router() | @@ -2690,64 +2802,93 @@ test_Credentials | src/auth.js:4:39:4:48 | 'passw0rd' | password | test_RouteHandler_getARequestExpr | src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:6:7:6:9 | req | +| src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:6:7:6:9 | req | | src/advanced-routehandler-registration.js:6:6:6:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:6:32:6:34 | req | | src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:7:7:7:9 | req | +| src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:7:7:7:9 | req | | src/advanced-routehandler-registration.js:7:6:7:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:7:32:7:34 | req | | src/advanced-routehandler-registration.js:15:6:15:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:15:7:15:9 | req | +| src/advanced-routehandler-registration.js:15:6:15:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:15:7:15:9 | req | | src/advanced-routehandler-registration.js:15:6:15:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:15:32:15:34 | req | | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:16:7:16:9 | req | +| src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:16:7:16:9 | req | | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:16:32:16:34 | req | | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:7:24:9 | req | +| src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:7:24:9 | req | | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:32:24:34 | req | | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:7:25:9 | req | +| src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:7:25:9 | req | | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:32:25:34 | req | | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:20:46:22 | req | +| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:20:46:22 | req | | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:47:27:47:29 | req | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:46:20:46:22 | req | +| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:46:20:46:22 | req | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:47:27:47:29 | req | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:10:51:12 | req | +| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:10:51:12 | req | | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:40:51:42 | req | | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:20:59:22 | req | +| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:20:59:22 | req | | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:60:18:60:20 | req | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:59:20:59:22 | req | +| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:59:20:59:22 | req | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:60:18:60:20 | req | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:10:64:12 | req | +| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:10:64:12 | req | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:45:64:47 | req | | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:13:68:15 | req | +| src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:13:68:15 | req | | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:38:68:40 | req | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:13:68:15 | req | +| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:13:68:15 | req | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:38:68:40 | req | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:20:69:22 | req | +| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:20:69:22 | req | | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:70:18:70:20 | req | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:13:68:15 | req | +| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:13:68:15 | req | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:38:68:40 | req | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:69:20:69:22 | req | +| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:69:20:69:22 | req | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:70:18:70:20 | req | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:10:73:12 | req | +| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:10:73:12 | req | | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:47:73:49 | req | | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:20:81:22 | req | +| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:20:81:22 | req | | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:82:27:82:29 | req | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:81:20:81:22 | req | +| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:81:20:81:22 | req | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:82:27:82:29 | req | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:10:92:12 | req | +| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:10:92:12 | req | | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:40:92:42 | req | | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:20:100:22 | req | +| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:20:100:22 | req | | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:101:31:101:33 | req | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:100:20:100:22 | req | +| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:100:20:100:22 | req | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:101:31:101:33 | req | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:10:111:12 | req | +| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:10:111:12 | req | | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:40:111:42 | req | | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:21:123:23 | req | +| src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:21:123:23 | req | | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:46:123:48 | req | | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:21:124:23 | req | +| src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:21:124:23 | req | | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:46:124:48 | req | | src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined | src/advanced-routehandler-registration.js:146:29:146:31 | req | | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:22:156:24 | req | +| src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:22:156:24 | req | | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:47:156:49 | req | | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:28:157:30 | req | +| src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:28:157:30 | req | | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:53:157:55 | req | | src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined | src/controllers/handler-in-bulk-require.js:1:45:1:47 | req | | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:20:28:20:30 | req | +| src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:20:28:20:30 | req | | src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:22:35:22:37 | req | | src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | src/csurf-example.js:25:32:25:34 | req | | src/csurf-example.js:32:30:34:3 | functio ... e')\\n } | src/csurf-example.js:32:40:32:42 | req | @@ -2755,22 +2896,28 @@ test_RouteHandler_getARequestExpr | src/csurf-example.js:40:27:40:48 | functio ... res) {} | src/csurf-example.js:40:37:40:39 | req | | src/exportedHandler.js:1:19:1:55 | functio ... res) {} | src/exportedHandler.js:1:44:1:46 | req | | src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:34:3:36 | req | +| src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:34:3:36 | req | | src/express2.js:3:25:3:55 | functio ... , res } | src/express2.js:3:46:3:48 | req | | src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:41:4:47 | request | +| src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:41:4:47 | request | | src/express2.js:4:32:4:76 | functio ... esult } | src/express2.js:4:60:4:66 | request | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:4:32:4:34 | req | +| src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:4:32:4:34 | req | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:5:14:5:16 | req | | src/express3.js:4:23:7:1 | functio ... al");\\n} | src/express3.js:5:35:5:37 | req | | src/express3.js:10:12:10:32 | functio ... res){} | src/express3.js:10:22:10:24 | req | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:4:32:4:34 | req | +| src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:4:32:4:34 | req | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:5:27:5:29 | req | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:6:18:6:20 | req | | src/express4.js:4:23:9:1 | functio ... ic1);\\n} | src/express4.js:7:18:7:20 | req | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:4:32:4:34 | req | +| src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:4:32:4:34 | req | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:5:16:5:18 | req | | src/express.js:4:23:9:1 | functio ... res);\\n} | src/express.js:6:26:6:28 | req | | src/express.js:16:19:18:3 | functio ... ");\\n } | src/express.js:16:28:16:30 | req | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:22:39:22:41 | req | +| src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:22:39:22:41 | req | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:23:3:23:5 | req | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:24:3:24:5 | req | | src/express.js:22:30:32:1 | functio ... ar');\\n} | src/express.js:25:3:25:5 | req | @@ -2782,43 +2929,55 @@ test_RouteHandler_getARequestExpr | src/express.js:37:12:37:32 | functio ... res){} | src/express.js:37:22:37:24 | req | | src/express.js:42:12:42:28 | (req, res) => f() | src/express.js:42:13:42:15 | req | | src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:46:31:46:33 | req | +| src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:46:31:46:33 | req | | src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:47:3:47:5 | req | | src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:48:3:48:5 | req | | src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:49:3:49:5 | req | | src/express.js:46:22:51:1 | functio ... ame];\\n} | src/express.js:50:3:50:5 | req | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:24:4:26 | req | +| src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:24:4:26 | req | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:7:2:7:4 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:20:5:22 | req | +| src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:20:5:22 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:6:5:6:7 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:7:5:7:7 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:8:5:8:7 | req | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:17:25:17:27 | req | +| src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:17:25:17:27 | req | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:18:9:18:11 | req | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:19:9:19:11 | req | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:20:9:20:11 | req | | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | src/middleware-flow.js:23:18:23:20 | req | +| src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | src/middleware-flow.js:23:18:23:20 | req | | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | src/middleware-flow.js:23:33:23:35 | req | | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | src/middleware-flow.js:24:18:24:20 | req | +| src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | src/middleware-flow.js:24:18:24:20 | req | | src/middleware-flow.js:24:17:24:41 | (req, r ... q.db; } | src/middleware-flow.js:24:33:24:35 | req | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:39:24:39:26 | req | +| src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:39:24:39:26 | req | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:40:5:40:7 | req | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:41:5:41:7 | req | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:42:5:42:7 | req | | src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:4:19:4:21 | req | +| src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:4:19:4:21 | req | | src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:5:17:5:19 | req | | src/params.js:4:18:12:1 | (req, r ... }\\n} | src/params.js:6:17:6:19 | req | | src/params.js:14:24:16:1 | functio ... lo");\\n} | src/params.js:14:33:14:35 | req | | src/passport.js:27:4:29:1 | functio ... ccss`\\n} | src/passport.js:27:13:27:15 | req | +| src/passport.js:27:4:29:1 | functio ... ccss`\\n} | src/passport.js:27:13:27:15 | req | | src/passport.js:27:4:29:1 | functio ... ccss`\\n} | src/passport.js:28:2:28:4 | req | | src/responseExprs.js:4:23:6:1 | functio ... res1\\n} | src/responseExprs.js:4:32:4:34 | req | | src/responseExprs.js:7:23:9:1 | functio ... res2;\\n} | src/responseExprs.js:7:32:7:34 | req | | src/responseExprs.js:10:23:12:1 | functio ... res3;\\n} | src/responseExprs.js:10:39:10:41 | req | | src/responseExprs.js:13:23:15:1 | functio ... res4;\\n} | src/responseExprs.js:13:32:13:34 | req | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:16:39:16:41 | req | +| src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:16:39:16:41 | req | | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | src/responseExprs.js:17:5:17:7 | req | | src/route-collection.js:2:6:2:35 | (req, r ... og(req) | src/route-collection.js:2:7:2:9 | req | +| src/route-collection.js:2:6:2:35 | (req, r ... og(req) | src/route-collection.js:2:7:2:9 | req | | src/route-collection.js:2:6:2:35 | (req, r ... og(req) | src/route-collection.js:2:32:2:34 | req | | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | src/route-collection.js:3:7:3:9 | req | +| src/route-collection.js:3:6:3:35 | (req, r ... og(req) | src/route-collection.js:3:7:3:9 | req | | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | src/route-collection.js:3:32:3:34 | req | | src/route.js:5:12:5:38 | functio ... ext) {} | src/route.js:5:21:5:23 | req | getRouteHandlerContainerStep diff --git a/javascript/ql/test/library-tests/frameworks/Express/tests.ql b/javascript/ql/test/library-tests/frameworks/Express/tests.ql index ec76c73df27b..d708732267af 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Express/tests.ql @@ -27,7 +27,6 @@ import RouterDefinition_getASubRouter import HeaderDefinition_getNameExpr import appCreation import RouteSetup_getRequestMethod -import RouteExpr import RouteHandler_getAResponseExpr import isResponse import ResponseBody diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll index 87f73f43770a..b62e44bf9471 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll @@ -1,5 +1,7 @@ import javascript -query predicate test_HeaderDefinition_getNameExpr(HTTP::ExplicitHeaderDefinition hd, Expr res) { - hd.getRouteHandler() instanceof NodeJSLib::RouteHandler and res = hd.getNameExpr() +query predicate test_HeaderDefinition_getNameExpr( + HTTP::ExplicitHeaderDefinition hd, DataFlow::Node res +) { + hd.getRouteHandler() instanceof NodeJSLib::RouteHandler and res = hd.getNameNode() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll index 50db052e6258..282c04ce3140 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(NodeJSLib::RequestExpr e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(NodeJSLib::RequestNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll index 106b07d90062..b509b70c884e 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(NodeJSLib::ResponseExpr e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(NodeJSLib::ResponseNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler.qll index 61f7f8dea0e0..9114d2d48f19 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteHandler(NodeJSLib::RouteHandler rh, Expr res) { res = rh.getServer() } +query predicate test_RouteHandler(NodeJSLib::RouteHandler rh, DataFlow::Node res) { + res = rh.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll index e43789bb1a7f..147e788d6423 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getARequestExpr(NodeJSLib::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(NodeJSLib::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll index fcef32d90e9c..f28717545510 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandler_getAResponseExpr( - NodeJSLib::RouteHandler rh, HTTP::ResponseExpr res + NodeJSLib::RouteHandler rh, HTTP::ResponseNode res ) { - res = rh.getAResponseExpr() + res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteSetup_getServer.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteSetup_getServer.qll index a10c7e0da8e7..24dfd61fb666 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteSetup_getServer.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteSetup_getServer.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteSetup_getServer(NodeJSLib::RouteSetup r, Expr res) { res = r.getServer() } +query predicate test_RouteSetup_getServer(NodeJSLib::RouteSetup r, DataFlow::Node res) { + res = r.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/isCreateServer.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/isCreateServer.qll index 86bcb37b728c..aacfe28ae28b 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/isCreateServer.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/isCreateServer.qll @@ -1,3 +1,3 @@ import javascript -query predicate test_isCreateServer(CallExpr e) { NodeJSLib::isCreateServer(e) } +query predicate test_isCreateServer(DataFlow::CallNode e) { NodeJSLib::isCreateServer(e) } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected index 2677e7854877..7d2d6abfddbe 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected @@ -45,43 +45,61 @@ test_ResponseExpr | createServer.js:3:38:3:40 | res | createServer.js:3:23:3:44 | functio ... res) {} | | createServer.js:4:37:4:39 | res | createServer.js:4:31:4:46 | (req, res) => {} | | createServer.js:25:52:25:54 | res | createServer.js:25:37:27:5 | functio ... ;\\n } | +| createServer.js:25:52:25:54 | res | createServer.js:25:37:27:5 | functio ... ;\\n } | | createServer.js:26:9:26:11 | res | createServer.js:25:37:27:5 | functio ... ;\\n } | | src/http.js:4:46:4:48 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:4:46:4:48 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:7:3:7:5 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:12:33:12:35 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:12:33:12:35 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} | | src/http.js:13:3:13:5 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} | | src/http.js:14:3:14:5 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} | | src/http.js:15:3:15:5 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} | | src/http.js:55:25:55:27 | res | src/http.js:55:12:55:30 | function(req,res){} | | src/http.js:60:27:60:29 | res | src/http.js:60:14:60:32 | function(req,res){} | | src/http.js:62:33:62:35 | res | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:62:33:62:35 | res | src/http.js:62:19:65:1 | functio ... r2");\\n} | | src/http.js:63:3:63:5 | res | src/http.js:62:19:65:1 | functio ... r2");\\n} | | src/http.js:64:3:64:5 | res | src/http.js:62:19:65:1 | functio ... r2");\\n} | | src/http.js:68:17:68:19 | res | src/http.js:68:12:68:27 | (req,res) => f() | | src/http.js:72:34:72:36 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:72:34:72:36 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:72:34:72:36 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:73:18:73:17 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} | | src/http.js:74:5:74:7 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} | | src/http.js:81:46:81:48 | res | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:81:46:81:48 | res | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:81:46:81:48 | res | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:82:18:82:17 | res | src/http.js:81:22:86:1 | functio ... la");\\n} | | src/http.js:83:5:83:7 | res | src/http.js:81:22:86:1 | functio ... la");\\n} | | src/http.js:85:3:85:5 | res | src/http.js:81:22:86:1 | functio ... la");\\n} | | src/https.js:4:47:4:49 | res | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:4:47:4:49 | res | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:7:3:7:5 | res | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:12:34:12:36 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/https.js:12:34:12:36 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/https.js:13:3:13:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/https.js:14:3:14:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/https.js:15:3:15:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/indirect2.js:9:19:9:21 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:9:19:9:21 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:10:47:10:49 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:13:33:13:35 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:33:13:35 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:33:13:35 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect2.js:13:33:13:35 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect2.js:14:3:14:5 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:14:3:14:5 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect2.js:15:3:15:5 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:15:3:15:5 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect.js:16:26:16:28 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:16:26:16:28 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:19:38:19:40 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:25:30:25:32 | res | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:25:30:25:32 | res | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | | src/indirect.js:26:5:26:7 | res | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | | src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +| src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | | src/indirect.js:29:5:29:7 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | test_HeaderDefinition | src/http.js:7:3:7:42 | res.wri ... rget }) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | @@ -150,43 +168,61 @@ test_RouteHandler_getAResponseExpr | createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:38:3:40 | res | | createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:37:4:39 | res | | createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:52:25:54 | res | +| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:52:25:54 | res | | createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:26:9:26:11 | res | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:46:4:48 | res | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:46:4:48 | res | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:7:3:7:5 | res | | src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:33:12:35 | res | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:33:12:35 | res | | src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:13:3:13:5 | res | | src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:14:3:14:5 | res | | src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:15:3:15:5 | res | | src/http.js:55:12:55:30 | function(req,res){} | src/http.js:55:25:55:27 | res | | src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:27:60:29 | res | | src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:33:62:35 | res | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:33:62:35 | res | | src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:3:63:5 | res | | src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:64:3:64:5 | res | | src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:17:68:19 | res | | src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:34:72:36 | res | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:34:72:36 | res | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:34:72:36 | res | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:18:73:17 | res | | src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:74:5:74:7 | res | | src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:46:81:48 | res | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:46:81:48 | res | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:46:81:48 | res | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:18:82:17 | res | | src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:83:5:83:7 | res | | src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:85:3:85:5 | res | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:47:4:49 | res | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:47:4:49 | res | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:7:3:7:5 | res | | src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:34:12:36 | res | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:34:12:36 | res | | src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:13:3:13:5 | res | | src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:14:3:14:5 | res | | src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:15:3:15:5 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:19:9:21 | res | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:19:9:21 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:47:10:49 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:33:13:35 | res | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:33:13:35 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:14:3:14:5 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:15:3:15:5 | res | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:33:13:35 | res | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:33:13:35 | res | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:14:3:14:5 | res | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:15:3:15:5 | res | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:26:16:28 | res | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:26:16:28 | res | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:38:19:40 | res | | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:30:25:32 | res | +| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:30:25:32 | res | | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:26:5:26:7 | res | | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res | +| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res | | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:29:5:29:7 | res | test_ServerDefinition_getARouteHandler | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | @@ -294,6 +330,7 @@ test_RequestExpr | createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} | | createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } | | src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:9:3:9:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | @@ -301,23 +338,29 @@ test_RequestExpr | src/http.js:55:21:55:23 | req | src/http.js:55:12:55:30 | function(req,res){} | | src/http.js:60:23:60:25 | req | src/http.js:60:14:60:32 | function(req,res){} | | src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | | src/http.js:63:17:63:19 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | | src/http.js:68:13:68:15 | req | src/http.js:68:12:68:27 | (req,res) => f() | | src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | | src/http.js:73:3:73:5 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | | src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | | src/http.js:82:3:82:5 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | | src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:6:26:6:28 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:8:3:8:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:9:3:9:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:12:29:12:31 | req | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:13:28:13:30 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:19:33:19:35 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:25:25:25:27 | req | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | @@ -337,6 +380,7 @@ test_RouteHandler_getARequestExpr | createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req | | createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:9:3:9:5 | req | @@ -344,23 +388,29 @@ test_RouteHandler_getARequestExpr | src/http.js:55:12:55:30 | function(req,res){} | src/http.js:55:21:55:23 | req | | src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:23:60:25 | req | | src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | | src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:17:63:19 | req | | src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:13:68:15 | req | | src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | | src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:3:73:5 | req | | src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | | src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:3:82:5 | req | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:6:26:6:28 | req | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:8:3:8:5 | req | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:9:3:9:5 | req | | src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:29:12:31 | req | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:28:13:30 | req | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:33:19:35 | req | | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:25:25:27 | req | diff --git a/javascript/ql/test/library-tests/frameworks/SQL/Credentials.ql b/javascript/ql/test/library-tests/frameworks/SQL/Credentials.ql index 5e32f342c200..2451052eaf4c 100644 --- a/javascript/ql/test/library-tests/frameworks/SQL/Credentials.ql +++ b/javascript/ql/test/library-tests/frameworks/SQL/Credentials.ql @@ -1,4 +1,4 @@ import javascript -from CredentialsExpr ce +from CredentialsNode ce select ce, ce.getCredentialsKind() diff --git a/javascript/ql/test/library-tests/frameworks/connect/tests.expected b/javascript/ql/test/library-tests/frameworks/connect/tests.expected index 65e9bf665e34..f383805827ab 100644 --- a/javascript/ql/test/library-tests/frameworks/connect/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/connect/tests.expected @@ -9,6 +9,7 @@ test_RouteSetup | src/test.js:32:1:35:2 | app.use ... rl);\\n}) | test_RequestInputAccess | src/test.js:8:5:8:26 | req.coo ... ('foo') | cookie | src/test.js:6:9:9:1 | functio ... oo');\\n} | +| src/test.js:28:20:28:22 | url | url | src/test.js:28:9:30:1 | functio ... bar);\\n} | | src/test.js:33:15:33:21 | req.url | url | src/test.js:32:9:35:1 | functio ... url);\\n} | test_RouteHandler_getAResponseHeader | src/test.js:6:9:9:1 | functio ... oo');\\n} | header1 | src/test.js:7:5:7:32 | res.set ... 1', '') | @@ -18,14 +19,17 @@ test_HeaderDefinition_defines | src/test.js:25:5:25:32 | res.set ... 2', '') | header2 | | test_ResponseExpr | src/test.js:6:32:6:34 | res | src/test.js:6:9:9:1 | functio ... oo');\\n} | +| src/test.js:6:32:6:34 | res | src/test.js:6:9:9:1 | functio ... oo');\\n} | | src/test.js:7:5:7:7 | res | src/test.js:6:9:9:1 | functio ... oo');\\n} | | src/test.js:15:27:15:29 | res | src/test.js:15:12:15:32 | functio ... res){} | | src/test.js:19:22:19:24 | res | src/test.js:19:9:19:27 | function(req,res){} | | src/test.js:20:23:20:25 | res | src/test.js:20:10:20:28 | function(req,res){} | | src/test.js:24:31:24:33 | res | src/test.js:24:9:26:1 | functio ... '');\\n} | +| src/test.js:24:31:24:33 | res | src/test.js:24:9:26:1 | functio ... '');\\n} | | src/test.js:25:5:25:7 | res | src/test.js:24:9:26:1 | functio ... '');\\n} | | src/test.js:28:42:28:44 | res | src/test.js:28:9:30:1 | functio ... bar);\\n} | | src/test.js:32:24:32:26 | res | src/test.js:32:9:35:1 | functio ... url);\\n} | +| src/test.js:32:24:32:26 | res | src/test.js:32:9:35:1 | functio ... url);\\n} | | src/test.js:34:5:34:7 | res | src/test.js:32:9:35:1 | functio ... url);\\n} | test_HeaderDefinition | src/test.js:7:5:7:32 | res.set ... 1', '') | src/test.js:6:9:9:1 | functio ... oo');\\n} | @@ -46,14 +50,17 @@ test_ServerDefinition | src/test.js:4:11:4:19 | connect() | test_RouteHandler_getAResponseExpr | src/test.js:6:9:9:1 | functio ... oo');\\n} | src/test.js:6:32:6:34 | res | +| src/test.js:6:9:9:1 | functio ... oo');\\n} | src/test.js:6:32:6:34 | res | | src/test.js:6:9:9:1 | functio ... oo');\\n} | src/test.js:7:5:7:7 | res | | src/test.js:15:12:15:32 | functio ... res){} | src/test.js:15:27:15:29 | res | | src/test.js:19:9:19:27 | function(req,res){} | src/test.js:19:22:19:24 | res | | src/test.js:20:10:20:28 | function(req,res){} | src/test.js:20:23:20:25 | res | | src/test.js:24:9:26:1 | functio ... '');\\n} | src/test.js:24:31:24:33 | res | +| src/test.js:24:9:26:1 | functio ... '');\\n} | src/test.js:24:31:24:33 | res | | src/test.js:24:9:26:1 | functio ... '');\\n} | src/test.js:25:5:25:7 | res | | src/test.js:28:9:30:1 | functio ... bar);\\n} | src/test.js:28:42:28:44 | res | | src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:32:24:32:26 | res | +| src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:32:24:32:26 | res | | src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:34:5:34:7 | res | test_RouteSetup_getARouteHandler | src/test.js:6:1:9:2 | app.use ... o');\\n}) | src/test.js:6:9:9:1 | functio ... oo');\\n} | @@ -76,6 +83,7 @@ test_RouteHandler | src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:4:11:4:19 | connect() | test_RequestExpr | src/test.js:6:27:6:29 | req | src/test.js:6:9:9:1 | functio ... oo');\\n} | +| src/test.js:6:27:6:29 | req | src/test.js:6:9:9:1 | functio ... oo');\\n} | | src/test.js:8:5:8:7 | req | src/test.js:6:9:9:1 | functio ... oo');\\n} | | src/test.js:15:22:15:24 | req | src/test.js:15:12:15:32 | functio ... res){} | | src/test.js:19:18:19:20 | req | src/test.js:19:9:19:27 | function(req,res){} | @@ -83,12 +91,14 @@ test_RequestExpr | src/test.js:24:26:24:28 | req | src/test.js:24:9:26:1 | functio ... '');\\n} | | src/test.js:28:19:28:39 | {url, q ... ookies} | src/test.js:28:9:30:1 | functio ... bar);\\n} | | src/test.js:32:19:32:21 | req | src/test.js:32:9:35:1 | functio ... url);\\n} | +| src/test.js:32:19:32:21 | req | src/test.js:32:9:35:1 | functio ... url);\\n} | | src/test.js:33:15:33:17 | req | src/test.js:32:9:35:1 | functio ... url);\\n} | test_Credentials | src/test.js:12:19:12:28 | 'username' | user name | | src/test.js:12:31:12:40 | 'password' | password | test_RouteHandler_getARequestExpr | src/test.js:6:9:9:1 | functio ... oo');\\n} | src/test.js:6:27:6:29 | req | +| src/test.js:6:9:9:1 | functio ... oo');\\n} | src/test.js:6:27:6:29 | req | | src/test.js:6:9:9:1 | functio ... oo');\\n} | src/test.js:8:5:8:7 | req | | src/test.js:15:12:15:32 | functio ... res){} | src/test.js:15:22:15:24 | req | | src/test.js:19:9:19:27 | function(req,res){} | src/test.js:19:18:19:20 | req | @@ -96,4 +106,5 @@ test_RouteHandler_getARequestExpr | src/test.js:24:9:26:1 | functio ... '');\\n} | src/test.js:24:26:24:28 | req | | src/test.js:28:9:30:1 | functio ... bar);\\n} | src/test.js:28:19:28:39 | {url, q ... ookies} | | src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:32:19:32:21 | req | +| src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:32:19:32:21 | req | | src/test.js:32:9:35:1 | functio ... url);\\n} | src/test.js:33:15:33:17 | req | diff --git a/javascript/ql/test/library-tests/frameworks/connect/tests.ql b/javascript/ql/test/library-tests/frameworks/connect/tests.ql index 24ddefeaf5d0..17211377fbf5 100644 --- a/javascript/ql/test/library-tests/frameworks/connect/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/connect/tests.ql @@ -18,7 +18,7 @@ query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string hd.defines(name, value) and hd.getRouteHandler() instanceof Connect::RouteHandler } -query predicate test_ResponseExpr(HTTP::ResponseExpr e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(HTTP::ResponseNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } @@ -26,7 +26,9 @@ query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Connect::RouteH rh = hd.getRouteHandler() } -query predicate test_RouteSetup_getServer(Connect::RouteSetup rs, Expr res) { res = rs.getServer() } +query predicate test_RouteSetup_getServer(Connect::RouteSetup rs, DataFlow::Node res) { + res = rs.getServer() +} query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Connect::RouteHandler and res = hd.getAHeaderName() @@ -34,17 +36,19 @@ query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, query predicate test_ServerDefinition(Connect::ServerDefinition s) { any() } -query predicate test_RouteHandler_getAResponseExpr(Connect::RouteHandler rh, HTTP::ResponseExpr res) { - res = rh.getAResponseExpr() +query predicate test_RouteHandler_getAResponseExpr(Connect::RouteHandler rh, HTTP::ResponseNode res) { + res = rh.getAResponseNode() } query predicate test_RouteSetup_getARouteHandler(Connect::RouteSetup r, DataFlow::SourceNode res) { res = r.getARouteHandler() } -query predicate test_RouteHandler(Connect::RouteHandler rh, Expr res) { res = rh.getServer() } +query predicate test_RouteHandler(Connect::RouteHandler rh, DataFlow::Node res) { + res = rh.getServer() +} -query predicate test_RequestExpr(HTTP::RequestExpr e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(HTTP::RequestNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } @@ -52,6 +56,6 @@ query predicate test_Credentials(Connect::Credentials cr, string res) { res = cr.getCredentialsKind() } -query predicate test_RouteHandler_getARequestExpr(Connect::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(Connect::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler.qll b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler.qll index 89598e2169ed..68ec89563ea6 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteHandler(Fastify::RouteHandler rh, Expr res) { res = rh.getServer() } +query predicate test_RouteHandler(Fastify::RouteHandler rh, DataFlow::Node res) { + res = rh.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll index dbc8d7cb8968..c709d84e745b 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Fastify::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(Fastify::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RouteSetup_getServer.qll b/javascript/ql/test/library-tests/frameworks/fastify/RouteSetup_getServer.qll index 8339498d0949..5a19750fd507 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RouteSetup_getServer.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RouteSetup_getServer.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteSetup_getServer(Fastify::RouteSetup rs, Expr res) { res = rs.getServer() } +query predicate test_RouteSetup_getServer(Fastify::RouteSetup rs, DataFlow::Node res) { + res = rs.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/fastify/tests.expected b/javascript/ql/test/library-tests/frameworks/fastify/tests.expected index 1371bf551c84..36a5420a1789 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/fastify/tests.expected @@ -97,23 +97,28 @@ test_RouteHandler_getARequestExpr | src/fastify.js:20:26:20:47 | (reques ... ) => {} | src/fastify.js:20:27:20:33 | request | | src/fastify.js:26:17:28:3 | (reques ... nse\\n } | src/fastify.js:26:18:26:24 | request | | src/fastify.js:34:17:46:3 | functio ... eam\\n } | src/fastify.js:34:26:34:32 | request | +| src/fastify.js:34:17:46:3 | functio ... eam\\n } | src/fastify.js:34:26:34:32 | request | | src/fastify.js:34:17:46:3 | functio ... eam\\n } | src/fastify.js:36:5:36:11 | request | | src/fastify.js:34:17:46:3 | functio ... eam\\n } | src/fastify.js:37:5:37:11 | request | | src/fastify.js:34:17:46:3 | functio ... eam\\n } | src/fastify.js:38:5:38:11 | request | | src/fastify.js:34:17:46:3 | functio ... eam\\n } | src/fastify.js:39:5:39:11 | request | | src/fastify.js:54:17:58:3 | functio ... ms;\\n } | src/fastify.js:54:26:54:32 | request | +| src/fastify.js:54:17:58:3 | functio ... ms;\\n } | src/fastify.js:54:26:54:32 | request | | src/fastify.js:54:17:58:3 | functio ... ms;\\n } | src/fastify.js:55:5:55:11 | request | | src/fastify.js:54:17:58:3 | functio ... ms;\\n } | src/fastify.js:56:5:56:11 | request | | src/fastify.js:54:17:58:3 | functio ... ms;\\n } | src/fastify.js:57:5:57:11 | request | | src/fastify.js:65:17:69:3 | functio ... ms;\\n } | src/fastify.js:65:26:65:32 | request | +| src/fastify.js:65:17:69:3 | functio ... ms;\\n } | src/fastify.js:65:26:65:32 | request | | src/fastify.js:65:17:69:3 | functio ... ms;\\n } | src/fastify.js:66:5:66:11 | request | | src/fastify.js:65:17:69:3 | functio ... ms;\\n } | src/fastify.js:67:5:67:11 | request | | src/fastify.js:65:17:69:3 | functio ... ms;\\n } | src/fastify.js:68:5:68:11 | request | | src/fastify.js:76:17:80:3 | functio ... ms;\\n } | src/fastify.js:76:26:76:32 | request | +| src/fastify.js:76:17:80:3 | functio ... ms;\\n } | src/fastify.js:76:26:76:32 | request | | src/fastify.js:76:17:80:3 | functio ... ms;\\n } | src/fastify.js:77:5:77:11 | request | | src/fastify.js:76:17:80:3 | functio ... ms;\\n } | src/fastify.js:78:5:78:11 | request | | src/fastify.js:76:17:80:3 | functio ... ms;\\n } | src/fastify.js:79:5:79:11 | request | | src/fastify.js:87:17:91:3 | functio ... ms;\\n } | src/fastify.js:87:26:87:32 | request | +| src/fastify.js:87:17:91:3 | functio ... ms;\\n } | src/fastify.js:87:26:87:32 | request | | src/fastify.js:87:17:91:3 | functio ... ms;\\n } | src/fastify.js:88:5:88:11 | request | | src/fastify.js:87:17:91:3 | functio ... ms;\\n } | src/fastify.js:89:5:89:11 | request | | src/fastify.js:87:17:91:3 | functio ... ms;\\n } | src/fastify.js:90:5:90:11 | request | diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll index d412847a950e..6e3118f13452 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(Hapi::RequestExpr e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Hapi::RequestNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll index 9acfedd73f79..93a356284fea 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Hapi::ResponseExpr e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Hapi::ResponseNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler.qll b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler.qll index 45e51d1b9995..58bcd7ab42bb 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteHandler(Hapi::RouteHandler rh, Expr res) { res = rh.getServer() } +query predicate test_RouteHandler(Hapi::RouteHandler rh, DataFlow::Node res) { + res = rh.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll index 51b719430d76..668ded20aea7 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Hapi::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(Hapi::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RouteSetup_getServer.qll b/javascript/ql/test/library-tests/frameworks/hapi/RouteSetup_getServer.qll index ffdbe44e168e..11c510a91d67 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RouteSetup_getServer.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RouteSetup_getServer.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteSetup_getServer(Hapi::RouteSetup rs, Expr res) { res = rs.getServer() } +query predicate test_RouteSetup_getServer(Hapi::RouteSetup rs, DataFlow::Node res) { + res = rs.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/hapi/tests.expected b/javascript/ql/test/library-tests/frameworks/hapi/tests.expected index 2579ed7a75aa..fb73a32acf62 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/hapi/tests.expected @@ -48,9 +48,11 @@ test_RouteHandler | src/hapi.js:34:12:34:30 | function (req, h){} | src/hapi.js:4:15:4:31 | new Hapi.Server() | test_RequestExpr | src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } | +| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } | | src/hapi.js:14:9:14:15 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } | | src/hapi.js:17:48:17:54 | request | src/hapi.js:17:30:18:1 | functio ... ndler\\n} | | src/hapi.js:20:19:20:25 | request | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | +| src/hapi.js:20:19:20:25 | request | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | | src/hapi.js:21:3:21:9 | request | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | | src/hapi.js:22:3:22:9 | request | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | | src/hapi.js:23:3:23:9 | request | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | @@ -60,9 +62,11 @@ test_RequestExpr | src/hapi.js:34:22:34:24 | req | src/hapi.js:34:12:34:30 | function (req, h){} | test_RouteHandler_getARequestExpr | src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request | +| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request | | src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:14:9:14:15 | request | | src/hapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapi.js:17:48:17:54 | request | | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapi.js:20:19:20:25 | request | +| src/hapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapi.js:20:19:20:25 | request | | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapi.js:21:3:21:9 | request | | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapi.js:22:3:22:9 | request | | src/hapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapi.js:23:3:23:9 | request | diff --git a/javascript/ql/test/library-tests/frameworks/koa/ContextExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/ContextExpr.qll index d33c4e12229c..c1218e2aabe7 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/ContextExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/ContextExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ContextExpr(Koa::ContextExpr e, Koa::RouteHandler res) { +query predicate test_ContextExpr(Koa::ContextNode e, Koa::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll b/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll index 8648d75eb636..c6d46ef8a022 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RedirectInvocation( - HTTP::RedirectInvocation redirect, Expr url, HTTP::RouteHandler rh + HTTP::RedirectInvocation redirect, DataFlow::Node url, HTTP::RouteHandler rh ) { redirect.getUrlArgument() = url and redirect.getRouteHandler() = rh diff --git a/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll index cb80c0da255a..bcb3177b0534 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(Koa::RequestExpr e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Koa::RequestNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll index dc846988cc23..908dcdc745fb 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Koa::ResponseExpr e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Koa::ResponseNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler.qll index 032d5a293660..1c7fafa4d406 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler.qll @@ -1,3 +1,3 @@ import javascript -query predicate test_RouteHandler(Koa::RouteHandler rh, Expr res) { res = rh.getServer() } +query predicate test_RouteHandler(Koa::RouteHandler rh, DataFlow::Node res) { res = rh.getServer() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAContextExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAContextExpr.qll index cbbe41ebb857..c5049096d5ae 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAContextExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAContextExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getAContextExpr(Koa::RouteHandler rh, Expr res) { - res = rh.getAContextExpr() +query predicate test_RouteHandler_getAContextExpr(Koa::RouteHandler rh, DataFlow::Node res) { + res = rh.getAContextNode() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll index ca15b9b465b5..3c844c953e4c 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Koa::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(Koa::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll index 6d5fa8ff7464..492386d40537 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getAResponseExpr(Koa::RouteHandler rh, HTTP::ResponseExpr res) { - res = rh.getAResponseExpr() +query predicate test_RouteHandler_getAResponseExpr(Koa::RouteHandler rh, HTTP::ResponseNode res) { + res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteSetup_getServer.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteSetup_getServer.qll index bb674e0d1927..b54b22498175 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteSetup_getServer.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteSetup_getServer.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteSetup_getServer(Koa::RouteSetup rs, Expr res) { res = rs.getServer() } +query predicate test_RouteSetup_getServer(Koa::RouteSetup rs, DataFlow::Node res) { + res = rs.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/koa/tests.expected b/javascript/ql/test/library-tests/frameworks/koa/tests.expected index e0a56e4e5328..042fc7227c29 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/koa/tests.expected @@ -41,11 +41,15 @@ test_HeaderDefinition_defines test_ResponseExpr | src/koa.js:12:3:12:15 | this.response | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:14:3:14:14 | ctx.response | src/koa.js:10:10:28:1 | functio ... az');\\n} | +| src/koa.js:15:7:15:24 | rsp | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:15:13:15:24 | ctx.response | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:16:3:16:5 | rsp | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:18:3:18:14 | ctx.response | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:44:2:44:13 | ctx.response | src/koa.js:30:10:45:1 | async c ... url);\\n} | test_RouteHandler_getAContextExpr +| src/koa.js:7:1:7:22 | functio ... r1() {} | src/koa.js:7:1:7:0 | this | +| src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:10:10:10:9 | this | +| src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:10:28:10:30 | ctx | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:10:28:10:30 | ctx | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:11:3:11:6 | this | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:12:3:12:6 | this | @@ -63,6 +67,7 @@ test_RouteHandler_getAContextExpr | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:26:3:26:5 | ctx | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:27:3:27:5 | ctx | | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:30:16:30:18 | ctx | +| src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:30:16:30:18 | ctx | | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:31:2:31:4 | ctx | | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:32:2:32:4 | ctx | | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:33:2:33:4 | ctx | @@ -77,9 +82,11 @@ test_RouteHandler_getAContextExpr | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:43:2:43:4 | ctx | | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:44:2:44:4 | ctx | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:47:16:47:18 | ctx | +| src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:47:16:47:18 | ctx | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:48:16:48:18 | ctx | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:51:14:51:16 | ctx | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:54:16:54:18 | ctx | +| src/koa.js:59:10:61:1 | functio ... .url;\\n} | src/koa.js:59:10:59:9 | this | | src/koa.js:59:10:61:1 | functio ... .url;\\n} | src/koa.js:60:2:60:5 | this | test_HeaderDefinition | src/koa.js:11:3:11:25 | this.se ... 1', '') | src/koa.js:10:10:28:1 | functio ... az');\\n} | @@ -111,6 +118,7 @@ test_HeaderAccess test_RouteHandler_getAResponseExpr | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:12:3:12:15 | this.response | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:14:3:14:14 | ctx.response | +| src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:15:7:15:24 | rsp | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:15:13:15:24 | ctx.response | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:16:3:16:5 | rsp | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:18:3:18:14 | ctx.response | @@ -155,6 +163,9 @@ test_RouteHandler_getARequestExpr | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:26:3:26:13 | ctx.request | | src/koa.js:59:10:61:1 | functio ... .url;\\n} | src/koa.js:60:2:60:13 | this.request | test_ContextExpr +| src/koa.js:7:1:7:0 | this | src/koa.js:7:1:7:22 | functio ... r1() {} | +| src/koa.js:10:10:10:9 | this | src/koa.js:10:10:28:1 | functio ... az');\\n} | +| src/koa.js:10:28:10:30 | ctx | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:10:28:10:30 | ctx | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:11:3:11:6 | this | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:12:3:12:6 | this | src/koa.js:10:10:28:1 | functio ... az');\\n} | @@ -172,6 +183,7 @@ test_ContextExpr | src/koa.js:26:3:26:5 | ctx | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:27:3:27:5 | ctx | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:30:16:30:18 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | +| src/koa.js:30:16:30:18 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:31:2:31:4 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:32:2:32:4 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:33:2:33:4 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | @@ -186,9 +198,11 @@ test_ContextExpr | src/koa.js:43:2:43:4 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:44:2:44:4 | ctx | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:47:16:47:18 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | +| src/koa.js:47:16:47:18 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:48:16:48:18 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:51:14:51:16 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:54:16:54:18 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | +| src/koa.js:59:10:59:9 | this | src/koa.js:59:10:61:1 | functio ... .url;\\n} | | src/koa.js:60:2:60:5 | this | src/koa.js:59:10:61:1 | functio ... .url;\\n} | test_RedirectInvocation | src/koa.js:43:2:43:18 | ctx.redirect(url) | src/koa.js:43:15:43:17 | url | src/koa.js:30:10:45:1 | async c ... url);\\n} | diff --git a/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll index 16facf7c3a91..c4759c6892fc 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(Restify::RequestExpr e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Restify::RequestNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll index a02524c0b9fd..1384ad6c8501 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Restify::ResponseExpr e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Restify::ResponseNode e, HTTP::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler.qll index c15bb690a72c..dc7315cc4922 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteHandler(Restify::RouteHandler rh, Expr res) { res = rh.getServer() } +query predicate test_RouteHandler(Restify::RouteHandler rh, DataFlow::Node res) { + res = rh.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll index 97c54cbceff7..d02c6f82ad32 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Restify::RouteHandler rh, HTTP::RequestExpr res) { - res = rh.getARequestExpr() +query predicate test_RouteHandler_getARequestExpr(Restify::RouteHandler rh, HTTP::RequestNode res) { + res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll index 749964afa526..e09d139d6517 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getAResponseExpr(Restify::RouteHandler rh, HTTP::ResponseExpr res) { - res = rh.getAResponseExpr() +query predicate test_RouteHandler_getAResponseExpr(Restify::RouteHandler rh, HTTP::ResponseNode res) { + res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteSetup_getServer.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteSetup_getServer.qll index fb6d67c3e54c..e84c65c3fc20 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteSetup_getServer.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteSetup_getServer.qll @@ -1,3 +1,5 @@ import javascript -query predicate test_RouteSetup_getServer(Restify::RouteSetup rs, Expr res) { res = rs.getServer() } +query predicate test_RouteSetup_getServer(Restify::RouteSetup rs, DataFlow::Node res) { + res = rs.getServer() +} diff --git a/javascript/ql/test/library-tests/frameworks/restify/tests.expected b/javascript/ql/test/library-tests/frameworks/restify/tests.expected index 618b05e7cca4..3f26379a3fa0 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/restify/tests.expected @@ -18,8 +18,10 @@ test_HeaderDefinition_defines | src/test.js:13:5:13:37 | respons ... 2', '') | header2 | | test_ResponseExpr | src/test.js:9:46:9:53 | response | src/test.js:9:19:11:1 | functio ... ition\\n} | +| src/test.js:9:46:9:53 | response | src/test.js:9:19:11:1 | functio ... ition\\n} | | src/test.js:10:5:10:12 | response | src/test.js:9:19:11:1 | functio ... ition\\n} | | src/test.js:12:46:12:53 | response | src/test.js:12:19:22:1 | functio ... okie;\\n} | +| src/test.js:12:46:12:53 | response | src/test.js:12:19:22:1 | functio ... okie;\\n} | | src/test.js:13:5:13:12 | response | src/test.js:12:19:22:1 | functio ... okie;\\n} | test_HeaderDefinition | src/test.js:10:5:10:34 | respons ... 1', '') | src/test.js:9:19:11:1 | functio ... ition\\n} | @@ -36,8 +38,10 @@ test_ServerDefinition | src/test.js:4:15:4:36 | restify ... erver() | test_RouteHandler_getAResponseExpr | src/test.js:9:19:11:1 | functio ... ition\\n} | src/test.js:9:46:9:53 | response | +| src/test.js:9:19:11:1 | functio ... ition\\n} | src/test.js:9:46:9:53 | response | | src/test.js:9:19:11:1 | functio ... ition\\n} | src/test.js:10:5:10:12 | response | | src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:12:46:12:53 | response | +| src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:12:46:12:53 | response | | src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:13:5:13:12 | response | test_RouteSetup_getARouteHandler | src/test.js:7:1:7:26 | server2 ... ndler1) | src/test.js:6:1:6:21 | functio ... er1(){} | @@ -50,6 +54,7 @@ test_RouteHandler test_RequestExpr | src/test.js:9:37:9:43 | request | src/test.js:9:19:11:1 | functio ... ition\\n} | | src/test.js:12:37:12:43 | request | src/test.js:12:19:22:1 | functio ... okie;\\n} | +| src/test.js:12:37:12:43 | request | src/test.js:12:19:22:1 | functio ... okie;\\n} | | src/test.js:14:5:14:11 | request | src/test.js:12:19:22:1 | functio ... okie;\\n} | | src/test.js:15:5:15:11 | request | src/test.js:12:19:22:1 | functio ... okie;\\n} | | src/test.js:16:5:16:11 | request | src/test.js:12:19:22:1 | functio ... okie;\\n} | @@ -61,6 +66,7 @@ test_RequestExpr test_RouteHandler_getARequestExpr | src/test.js:9:19:11:1 | functio ... ition\\n} | src/test.js:9:37:9:43 | request | | src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:12:37:12:43 | request | +| src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:12:37:12:43 | request | | src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:14:5:14:11 | request | | src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:15:5:15:11 | request | | src/test.js:12:19:22:1 | functio ... okie;\\n} | src/test.js:16:5:16:11 | request | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 3af55bfd598c..3effc99fcb3f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -116,6 +116,11 @@ nodes | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | | classnames.js:15:52:15:62 | window.name | +| classnames.js:17:32:17:79 | `` | +| classnames.js:17:32:17:79 | `` | +| classnames.js:17:48:17:64 | clsx(window.name) | +| classnames.js:17:53:17:63 | window.name | +| classnames.js:17:53:17:63 | window.name | | clipboard.ts:8:11:8:51 | html | | clipboard.ts:8:11:8:51 | html | | clipboard.ts:8:18:8:51 | clipboa ... /html') | @@ -1187,6 +1192,10 @@ edges | classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | +| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | +| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | +| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | +| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | @@ -2182,6 +2191,7 @@ edges | classnames.js:11:31:11:79 | `` | classnames.js:10:45:10:55 | window.name | classnames.js:11:31:11:79 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:10:45:10:55 | window.name | user-provided value | | classnames.js:13:31:13:83 | `` | classnames.js:13:57:13:67 | window.name | classnames.js:13:31:13:83 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:13:57:13:67 | window.name | user-provided value | | classnames.js:15:31:15:78 | `` | classnames.js:15:52:15:62 | window.name | classnames.js:15:31:15:78 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:15:52:15:62 | window.name | user-provided value | +| classnames.js:17:32:17:79 | `` | classnames.js:17:53:17:63 | window.name | classnames.js:17:32:17:79 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:17:53:17:63 | window.name | user-provided value | | clipboard.ts:15:25:15:28 | html | clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:15:25:15:28 | html | Cross-site scripting vulnerability due to $@. | clipboard.ts:8:18:8:51 | clipboa ... /html') | user-provided value | | clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:24:23:24:58 | e.clipb ... /html') | user-provided value | | clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:29:19:29:54 | e.clipb ... /html') | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index f8f72db0b4a9..fa65ccbe3dff 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -116,6 +116,11 @@ nodes | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | | classnames.js:15:52:15:62 | window.name | +| classnames.js:17:32:17:79 | `` | +| classnames.js:17:32:17:79 | `` | +| classnames.js:17:48:17:64 | clsx(window.name) | +| classnames.js:17:53:17:63 | window.name | +| classnames.js:17:53:17:63 | window.name | | clipboard.ts:8:11:8:51 | html | | clipboard.ts:8:11:8:51 | html | | clipboard.ts:8:18:8:51 | clipboa ... /html') | @@ -1237,6 +1242,10 @@ edges | classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | +| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | +| classnames.js:17:48:17:64 | clsx(window.name) | classnames.js:17:32:17:79 | `` | +| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | +| classnames.js:17:53:17:63 | window.name | classnames.js:17:48:17:64 | clsx(window.name) | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | | clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/classnames.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/classnames.js index e18f7844f68e..a0e75045a2eb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/classnames.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/classnames.js @@ -13,4 +13,6 @@ function main() { document.body.innerHTML = `Hello`; // NOT OK document.body.innerHTML = `Hello`; // OK document.body.innerHTML = `Hello`; // NOT OK + + document.body.innerHTML += `Hello`; // NOT OK } diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query20.qll b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query20.qll index 86c7ab712c5a..7b8b7843fc8b 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query20.qll +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query20.qll @@ -1,5 +1,5 @@ import javascript query predicate test_query20(SQL::SqlString ss, string res) { - ss instanceof AddExpr and res = "Use templating instead of string concatenation." + ss.asExpr() instanceof AddExpr and res = "Use templating instead of string concatenation." }