mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Merge pull request #11660 from erik-krogh/dynamic-useInstanceOf
Py/JS/RB: Use instanceof in more places
This commit is contained in:
@@ -51,9 +51,7 @@ class TaintedPathAtmConfig extends AtmConfig {
|
||||
* of barrier guards, we port the barrier guards for the boosted query from the standard library to
|
||||
* sanitizer guards here.
|
||||
*/
|
||||
private class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode {
|
||||
BarrierGuardNodeAsSanitizerGuardNode() { this instanceof TaintedPath::BarrierGuardNode }
|
||||
|
||||
private class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode instanceof TaintedPath::BarrierGuardNode {
|
||||
override predicate sanitizes(boolean outcome, Expr e) {
|
||||
blocks(outcome, e) or blocks(outcome, e, _)
|
||||
}
|
||||
|
||||
@@ -75,8 +75,7 @@ module Closure {
|
||||
/**
|
||||
* A top-level call to `goog.provide`.
|
||||
*/
|
||||
class ClosureProvideCall extends ClosureNamespaceRef, DataFlow::MethodCallNode {
|
||||
ClosureProvideCall() { this instanceof DefaultClosureProvideCall }
|
||||
class ClosureProvideCall extends ClosureNamespaceRef, DataFlow::MethodCallNode instanceof DefaultClosureProvideCall {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,8 +88,7 @@ module Closure {
|
||||
/**
|
||||
* A call to `goog.require`.
|
||||
*/
|
||||
class ClosureRequireCall extends ClosureNamespaceAccess, DataFlow::MethodCallNode {
|
||||
ClosureRequireCall() { this instanceof DefaultClosureRequireCall }
|
||||
class ClosureRequireCall extends ClosureNamespaceAccess, DataFlow::MethodCallNode instanceof DefaultClosureRequireCall {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +104,7 @@ module Closure {
|
||||
/**
|
||||
* A top-level call to `goog.module` or `goog.declareModuleId`.
|
||||
*/
|
||||
class ClosureModuleDeclaration extends ClosureNamespaceRef, DataFlow::MethodCallNode {
|
||||
ClosureModuleDeclaration() { this instanceof DefaultClosureModuleDeclaration }
|
||||
class ClosureModuleDeclaration extends ClosureNamespaceRef, DataFlow::MethodCallNode instanceof DefaultClosureModuleDeclaration {
|
||||
}
|
||||
|
||||
private GlobalVariable googVariable() { variables(result, "goog", any(GlobalScope sc)) }
|
||||
|
||||
@@ -138,16 +138,14 @@ module DOM {
|
||||
/**
|
||||
* A JSX attribute, viewed as an `AttributeDefinition`.
|
||||
*/
|
||||
private class JsxAttributeDefinition extends AttributeDefinition, @jsx_attribute {
|
||||
JsxAttribute attr;
|
||||
private class JsxAttributeDefinition extends AttributeDefinition, @jsx_attribute instanceof JsxAttribute {
|
||||
override string getName() { result = JsxAttribute.super.getName() }
|
||||
|
||||
JsxAttributeDefinition() { this = attr }
|
||||
override DataFlow::Node getValueNode() {
|
||||
result = DataFlow::valueNode(JsxAttribute.super.getValue())
|
||||
}
|
||||
|
||||
override string getName() { result = attr.getName() }
|
||||
|
||||
override DataFlow::Node getValueNode() { result = DataFlow::valueNode(attr.getValue()) }
|
||||
|
||||
override ElementDefinition getElement() { result = attr.getElement() }
|
||||
override ElementDefinition getElement() { result = JsxAttribute.super.getElement() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -222,9 +222,7 @@ class VarDef extends ControlFlowNode {
|
||||
*
|
||||
* Some variable definitions are also uses, notably the operands of update expressions.
|
||||
*/
|
||||
class VarUse extends ControlFlowNode, @varref {
|
||||
VarUse() { this instanceof RValue }
|
||||
|
||||
class VarUse extends ControlFlowNode, @varref instanceof RValue {
|
||||
/** Gets the variable this use refers to. */
|
||||
Variable getVariable() { result = this.(VarRef).getVariable() }
|
||||
|
||||
|
||||
@@ -384,16 +384,11 @@ module DefensiveExpressionTest {
|
||||
*
|
||||
* Example: `typeof x === "undefined"'.
|
||||
*/
|
||||
class TypeofUndefinedTest extends UndefinedNullTest {
|
||||
TypeofTest test;
|
||||
class TypeofUndefinedTest extends UndefinedNullTest instanceof TypeofTest {
|
||||
TypeofUndefinedTest() { super.getTag() = "undefined" }
|
||||
|
||||
TypeofUndefinedTest() {
|
||||
this = test and
|
||||
test.getTag() = "undefined"
|
||||
}
|
||||
override boolean getTheTestResult() { result = TypeofTest.super.getTheTestResult() }
|
||||
|
||||
override boolean getTheTestResult() { result = test.getTheTestResult() }
|
||||
|
||||
override Expr getOperand() { result = test.getOperand() }
|
||||
override Expr getOperand() { result = TypeofTest.super.getOperand() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@ abstract class GeneratedCodeMarkerComment extends Comment { }
|
||||
/**
|
||||
* A source mapping comment, viewed as a marker comment indicating generated code.
|
||||
*/
|
||||
private class SourceMappingCommentMarkerComment extends GeneratedCodeMarkerComment {
|
||||
SourceMappingCommentMarkerComment() { this instanceof SourceMappingComment }
|
||||
private class SourceMappingCommentMarkerComment extends GeneratedCodeMarkerComment instanceof SourceMappingComment {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -508,9 +508,7 @@ module Routing {
|
||||
/**
|
||||
* An array which has been determined to be a route node, seen as a route node with arguments.
|
||||
*/
|
||||
private class ImpliedArrayRoute extends ValueNode::WithArguments, DataFlow::ArrayCreationNode {
|
||||
ImpliedArrayRoute() { this instanceof ValueNode::UseSite }
|
||||
|
||||
private class ImpliedArrayRoute extends ValueNode::WithArguments, DataFlow::ArrayCreationNode instanceof ValueNode::UseSite {
|
||||
override DataFlow::Node getArgumentNode(int n) { result = this.getElement(n) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,9 +298,7 @@ class MethodCallNode extends CallNode instanceof DataFlow::Impl::MethodCallNodeD
|
||||
* new Array(16)
|
||||
* ```
|
||||
*/
|
||||
class NewNode extends InvokeNode {
|
||||
NewNode() { this instanceof DataFlow::Impl::NewNodeDef }
|
||||
}
|
||||
class NewNode extends InvokeNode instanceof DataFlow::Impl::NewNodeDef { }
|
||||
|
||||
/**
|
||||
* A data flow node corresponding to the `this` parameter in a function or `this` at the top-level.
|
||||
|
||||
@@ -180,13 +180,9 @@ class AnalyzedValueNode extends AnalyzedNode, DataFlow::ValueNode { }
|
||||
* exports are modeled as property writes on `module.exports`, and imports
|
||||
* as property reads on any potential value of `module.exports`.
|
||||
*/
|
||||
class AnalyzedModule extends TopLevel {
|
||||
Module m;
|
||||
|
||||
AnalyzedModule() { this = m }
|
||||
|
||||
class AnalyzedModule extends TopLevel instanceof Module {
|
||||
/** Gets the name of this module. */
|
||||
string getName() { result = m.getName() }
|
||||
string getName() { result = super.getName() }
|
||||
|
||||
/**
|
||||
* Gets the abstract value representing this module's `module` object.
|
||||
@@ -216,7 +212,7 @@ class AnalyzedModule extends TopLevel {
|
||||
exists(AbstractValue exports | exports = getAnExportsValue() |
|
||||
// CommonJS modules export `module.exports` as their `default`
|
||||
// export in an ES2015 setting
|
||||
not m instanceof ES2015Module and
|
||||
not this instanceof ES2015Module and
|
||||
name = "default" and
|
||||
result = exports
|
||||
or
|
||||
|
||||
@@ -120,15 +120,13 @@ abstract class AnalyzedPropertyWrite extends DataFlow::Node {
|
||||
/**
|
||||
* Flow analysis for property writes.
|
||||
*/
|
||||
private class AnalyzedExplicitPropertyWrite extends AnalyzedPropertyWrite {
|
||||
AnalyzedExplicitPropertyWrite() { this instanceof DataFlow::PropWrite }
|
||||
|
||||
private class AnalyzedExplicitPropertyWrite extends AnalyzedPropertyWrite instanceof DataFlow::PropWrite {
|
||||
override predicate writes(AbstractValue base, string prop, DataFlow::AnalyzedNode source) {
|
||||
explicitPropertyWrite(this, base, prop, source)
|
||||
}
|
||||
|
||||
override predicate baseIsIncomplete(DataFlow::Incompleteness reason) {
|
||||
this.(DataFlow::PropWrite).getBase().isIncomplete(reason)
|
||||
super.getBase().isIncomplete(reason)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,9 +144,7 @@ class AnalyzedVarDef extends VarDef {
|
||||
/**
|
||||
* Flow analysis for simple parameters of selected functions.
|
||||
*/
|
||||
private class AnalyzedParameterAsVarDef extends AnalyzedVarDef, @var_decl {
|
||||
AnalyzedParameterAsVarDef() { this instanceof Parameter }
|
||||
|
||||
private class AnalyzedParameterAsVarDef extends AnalyzedVarDef, @var_decl instanceof Parameter {
|
||||
override AbstractValue getAnRhsValue() {
|
||||
result = DataFlow::valueNode(this).(AnalyzedValueNode).getALocalValue()
|
||||
}
|
||||
@@ -692,25 +690,20 @@ abstract private class CallWithAnalyzedParameters extends FunctionWithAnalyzedPa
|
||||
/**
|
||||
* Flow analysis for simple parameters of IIFEs.
|
||||
*/
|
||||
private class IifeWithAnalyzedParameters extends CallWithAnalyzedParameters {
|
||||
ImmediatelyInvokedFunctionExpr iife;
|
||||
private class IifeWithAnalyzedParameters extends CallWithAnalyzedParameters instanceof ImmediatelyInvokedFunctionExpr {
|
||||
IifeWithAnalyzedParameters() { super.getInvocationKind() = "direct" }
|
||||
|
||||
IifeWithAnalyzedParameters() {
|
||||
this = iife and
|
||||
iife.getInvocationKind() = "direct"
|
||||
}
|
||||
|
||||
override DataFlow::InvokeNode getAnInvocation() { result = iife.getInvocation().flow() }
|
||||
override DataFlow::InvokeNode getAnInvocation() { result = super.getInvocation().flow() }
|
||||
|
||||
override predicate isIncomplete(DataFlow::Incompleteness cause) {
|
||||
// if the IIFE has a name and that name is referenced, we conservatively
|
||||
// assume that there may be other calls than the direct one
|
||||
exists(iife.getVariable().getAnAccess()) and cause = "call"
|
||||
exists(ImmediatelyInvokedFunctionExpr.super.getVariable().getAnAccess()) and cause = "call"
|
||||
or
|
||||
// if the IIFE is non-strict and its `arguments` object is accessed, we
|
||||
// also assume that there may be other calls (through `arguments.callee`)
|
||||
not iife.isStrict() and
|
||||
exists(iife.getArgumentsVariable().getAnAccess()) and
|
||||
not ImmediatelyInvokedFunctionExpr.super.isStrict() and
|
||||
exists(ImmediatelyInvokedFunctionExpr.super.getArgumentsVariable().getAnAccess()) and
|
||||
cause = "call"
|
||||
}
|
||||
}
|
||||
@@ -718,12 +711,8 @@ private class IifeWithAnalyzedParameters extends CallWithAnalyzedParameters {
|
||||
/**
|
||||
* Enables inter-procedural type inference for `LocalFunction`.
|
||||
*/
|
||||
private class LocalFunctionWithAnalyzedParameters extends CallWithAnalyzedParameters {
|
||||
LocalFunction local;
|
||||
|
||||
LocalFunctionWithAnalyzedParameters() { this = local }
|
||||
|
||||
override DataFlow::InvokeNode getAnInvocation() { result = local.getAnInvocation() }
|
||||
private class LocalFunctionWithAnalyzedParameters extends CallWithAnalyzedParameters instanceof LocalFunction {
|
||||
override DataFlow::InvokeNode getAnInvocation() { result = LocalFunction.super.getAnInvocation() }
|
||||
|
||||
override predicate isIncomplete(DataFlow::Incompleteness cause) { none() }
|
||||
}
|
||||
|
||||
@@ -226,21 +226,17 @@ abstract class ScriptDependency extends Dependency {
|
||||
/**
|
||||
* An embedded JavaScript library included inside a `<script>` tag.
|
||||
*/
|
||||
class InlineScriptDependency extends ScriptDependency, @toplevel {
|
||||
FrameworkLibraryInstance fli;
|
||||
|
||||
InlineScriptDependency() { this = fli }
|
||||
|
||||
class InlineScriptDependency extends ScriptDependency, @toplevel instanceof FrameworkLibraryInstance {
|
||||
override predicate info(string id, string v) {
|
||||
exists(FrameworkLibrary fl |
|
||||
fli.info(fl, v) and
|
||||
FrameworkLibraryInstance.super.info(fl, v) and
|
||||
id = fl.getId()
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getAnApiUse() {
|
||||
exists(FrameworkLibrary fl |
|
||||
fli.info(fl, _) and
|
||||
FrameworkLibraryInstance.super.info(fl, _) and
|
||||
propAccessOnGlobal(result, fl.getAnEntryPoint()) and
|
||||
result.getFile() = this.getFile() and
|
||||
result.getTopLevel() != this
|
||||
@@ -252,21 +248,17 @@ class InlineScriptDependency extends ScriptDependency, @toplevel {
|
||||
* An external JavaScript library referenced via the `src` attribute
|
||||
* of a `<script>` tag.
|
||||
*/
|
||||
class ExternalScriptDependency extends ScriptDependency, @xmlattribute {
|
||||
FrameworkLibraryReference flr;
|
||||
|
||||
ExternalScriptDependency() { this = flr }
|
||||
|
||||
class ExternalScriptDependency extends ScriptDependency, @xmlattribute instanceof FrameworkLibraryReference {
|
||||
override predicate info(string id, string v) {
|
||||
exists(FrameworkLibrary fl |
|
||||
flr.info(fl, v) and
|
||||
FrameworkLibraryReference.super.info(fl, v) and
|
||||
id = fl.getId()
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getAnApiUse() {
|
||||
exists(FrameworkLibrary fl |
|
||||
flr.info(fl, _) and
|
||||
FrameworkLibraryReference.super.info(fl, _) and
|
||||
propAccessOnGlobal(result, fl.getAnEntryPoint()) and
|
||||
result.getFile() = this.getFile()
|
||||
)
|
||||
@@ -276,9 +268,7 @@ class ExternalScriptDependency extends ScriptDependency, @xmlattribute {
|
||||
/**
|
||||
* A dependency on GWT indicated by a GWT header script.
|
||||
*/
|
||||
private class GwtDependency extends ScriptDependency {
|
||||
GwtDependency() { this instanceof GwtHeader }
|
||||
|
||||
private class GwtDependency extends ScriptDependency instanceof GwtHeader {
|
||||
override predicate info(string id, string v) {
|
||||
id = "gwt" and
|
||||
exists(GwtHeader h | h = this |
|
||||
|
||||
@@ -468,14 +468,10 @@ abstract class DirectiveTarget extends Locatable {
|
||||
/**
|
||||
* A DOM element, viewed as directive target.
|
||||
*/
|
||||
private class DomElementAsElement extends DirectiveTarget {
|
||||
DOM::ElementDefinition element;
|
||||
private class DomElementAsElement extends DirectiveTarget instanceof DOM::ElementDefinition {
|
||||
override string getName() { result = DOM::ElementDefinition.super.getName() }
|
||||
|
||||
DomElementAsElement() { this = element }
|
||||
|
||||
override string getName() { result = element.getName() }
|
||||
|
||||
override DOM::ElementDefinition getElement() { result = element }
|
||||
override DOM::ElementDefinition getElement() { result = this }
|
||||
|
||||
override DirectiveTargetType getType() { result = E() }
|
||||
}
|
||||
@@ -483,18 +479,16 @@ private class DomElementAsElement extends DirectiveTarget {
|
||||
/**
|
||||
* A DOM attribute, viewed as a directive target.
|
||||
*/
|
||||
private class DomAttributeAsElement extends DirectiveTarget {
|
||||
DOM::AttributeDefinition attr;
|
||||
private class DomAttributeAsElement extends DirectiveTarget instanceof DOM::AttributeDefinition {
|
||||
override string getName() { result = DOM::AttributeDefinition.super.getName() }
|
||||
|
||||
DomAttributeAsElement() { this = attr }
|
||||
|
||||
override string getName() { result = attr.getName() }
|
||||
|
||||
override DOM::ElementDefinition getElement() { result = attr.getElement() }
|
||||
override DOM::ElementDefinition getElement() {
|
||||
result = DOM::AttributeDefinition.super.getElement()
|
||||
}
|
||||
|
||||
override DirectiveTargetType getType() { result = A() }
|
||||
|
||||
DOM::AttributeDefinition asAttribute() { result = attr }
|
||||
DOM::AttributeDefinition asAttribute() { result = this }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,17 +956,13 @@ abstract class Controller extends DataFlow::Node {
|
||||
/**
|
||||
* A controller instantiated through a directive, e.g. `<div ngController="myController"/>`.
|
||||
*/
|
||||
private class DirectiveController extends Controller {
|
||||
ControllerDefinition def;
|
||||
|
||||
DirectiveController() { this = def }
|
||||
|
||||
private class DirectiveController extends Controller instanceof ControllerDefinition {
|
||||
private predicate boundAnonymously(DOM::ElementDefinition elem) {
|
||||
exists(DirectiveInstance instance, DomAttributeAsElement attr |
|
||||
instance.getName() = "ngController" and
|
||||
instance.getATarget() = attr and
|
||||
elem = attr.getElement() and
|
||||
attr.asAttribute().getStringValue() = def.getName()
|
||||
attr.asAttribute().getStringValue() = super.getName()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -989,28 +979,26 @@ private class DirectiveController extends Controller {
|
||||
attributeValue = attr.asAttribute().getStringValue() and
|
||||
pattern = "([^ ]+) +as +([^ ]+)"
|
||||
|
|
||||
attributeValue.regexpCapture(pattern, 1) = def.getName() and
|
||||
attributeValue.regexpCapture(pattern, 1) = ControllerDefinition.super.getName() and
|
||||
attributeValue.regexpCapture(pattern, 2) = alias
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override InjectableFunction getFactoryFunction() { result = def.getAFactoryFunction() }
|
||||
override InjectableFunction getFactoryFunction() {
|
||||
result = ControllerDefinition.super.getAFactoryFunction()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A controller instantiated through routes, e.g. `$routeProvider.otherwise({controller: ...})`.
|
||||
*/
|
||||
private class RouteInstantiatedController extends Controller {
|
||||
RouteSetup setup;
|
||||
|
||||
RouteInstantiatedController() { this = setup }
|
||||
|
||||
override InjectableFunction getFactoryFunction() { result = setup.getController() }
|
||||
private class RouteInstantiatedController extends Controller instanceof RouteSetup {
|
||||
override InjectableFunction getFactoryFunction() { result = super.getController() }
|
||||
|
||||
override predicate boundTo(DOM::ElementDefinition elem) {
|
||||
exists(string url, HTML::HtmlFile template |
|
||||
setup.getRouteParam("templateUrl").mayHaveStringValue(url) and
|
||||
super.getRouteParam("templateUrl").mayHaveStringValue(url) and
|
||||
template.getAbsolutePath().regexpMatch(".*\\Q" + url + "\\E") and
|
||||
elem.getFile() = template
|
||||
)
|
||||
@@ -1018,7 +1006,7 @@ private class RouteInstantiatedController extends Controller {
|
||||
|
||||
override predicate boundToAs(DOM::ElementDefinition elem, string name) {
|
||||
this.boundTo(elem) and
|
||||
setup.getRouteParam("controllerAs").mayHaveStringValue(name)
|
||||
super.getRouteParam("controllerAs").mayHaveStringValue(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -808,23 +808,19 @@ private import Parser
|
||||
*
|
||||
* Will eventually be a subtype of `DataFlow::Node`.
|
||||
*/
|
||||
class NgDataFlowNode extends TNode {
|
||||
NgAstNode astNode;
|
||||
|
||||
NgDataFlowNode() { this = astNode }
|
||||
|
||||
class NgDataFlowNode extends TNode instanceof NgAstNode {
|
||||
/** Gets the AST node this node corresponds to. */
|
||||
NgAstNode getAstNode() { result = astNode }
|
||||
NgAstNode getAstNode() { result = this }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = astNode.toString() }
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
/**
|
||||
* Gets a scope object for this node.
|
||||
*/
|
||||
AngularJS::AngularScope getAScope() {
|
||||
exists(NgToken token, NgSource source |
|
||||
astNode.at(token, _) and
|
||||
super.at(token, _) and
|
||||
token.at(source, _)
|
||||
|
|
||||
result.mayApplyTo(source.getProvider().getEnclosingElement())
|
||||
|
||||
@@ -473,27 +473,21 @@ abstract class ServiceRequestNode extends DataFlow::Node {
|
||||
/**
|
||||
* The request for a scope service in the form of the link-function of a directive.
|
||||
*/
|
||||
private class LinkFunctionWithScopeInjection extends ServiceRequestNode {
|
||||
LinkFunctionWithScopeInjection() { this instanceof LinkFunction }
|
||||
|
||||
private class LinkFunctionWithScopeInjection extends ServiceRequestNode instanceof LinkFunction {
|
||||
override DataFlow::ParameterNode getDependencyParameter(ServiceReference service) {
|
||||
service instanceof ScopeServiceReference and
|
||||
result = this.(LinkFunction).getScopeParameter()
|
||||
result = super.getScopeParameter()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A request for a service, in the form of a dependency-injected function.
|
||||
*/
|
||||
class InjectableFunctionServiceRequest extends ServiceRequestNode {
|
||||
InjectableFunction injectedFunction;
|
||||
|
||||
InjectableFunctionServiceRequest() { injectedFunction = this }
|
||||
|
||||
class InjectableFunctionServiceRequest extends ServiceRequestNode instanceof InjectableFunction {
|
||||
/**
|
||||
* Gets the function of this request.
|
||||
*/
|
||||
InjectableFunction getAnInjectedFunction() { result = injectedFunction }
|
||||
InjectableFunction getAnInjectedFunction() { result = this }
|
||||
|
||||
/**
|
||||
* Gets a name of a requested service.
|
||||
@@ -512,7 +506,7 @@ class InjectableFunctionServiceRequest extends ServiceRequestNode {
|
||||
}
|
||||
|
||||
override DataFlow::ParameterNode getDependencyParameter(ServiceReference service) {
|
||||
service = injectedFunction.getAResolvedDependency(result)
|
||||
service = super.getAResolvedDependency(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,12 +625,8 @@ class ProviderRecipeDefinition extends RecipeDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
private class ProviderRecipeServiceInjection extends DependencyInjection {
|
||||
ProviderRecipeServiceInjection() { this instanceof ProviderRecipeDefinition }
|
||||
|
||||
override DataFlow::Node getAnInjectableFunction() {
|
||||
result = this.(ProviderRecipeDefinition).getAService()
|
||||
}
|
||||
private class ProviderRecipeServiceInjection extends DependencyInjection instanceof ProviderRecipeDefinition {
|
||||
override DataFlow::Node getAnInjectableFunction() { result = super.getAService() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -762,14 +762,12 @@ module ClientRequest {
|
||||
/**
|
||||
* A shell execution of `curl` that downloads some file.
|
||||
*/
|
||||
class CurlDownload extends ClientRequest::Range {
|
||||
SystemCommandExecution cmd;
|
||||
|
||||
class CurlDownload extends ClientRequest::Range instanceof SystemCommandExecution {
|
||||
CurlDownload() {
|
||||
this = cmd and
|
||||
(
|
||||
cmd.getACommandArgument().getStringValue() = "curl" or
|
||||
cmd.getACommandArgument()
|
||||
super.getACommandArgument().getStringValue() = "curl" or
|
||||
super
|
||||
.getACommandArgument()
|
||||
.(StringOps::ConcatenationRoot)
|
||||
.getConstantStringParts()
|
||||
.matches("curl %")
|
||||
@@ -777,8 +775,8 @@ module ClientRequest {
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() {
|
||||
result = cmd.getArgumentList().getALocalSource().getAPropertyWrite().getRhs() or
|
||||
result = cmd.getACommandArgument().(StringOps::ConcatenationRoot).getALeaf()
|
||||
result = super.getArgumentList().getALocalSource().getAPropertyWrite().getRhs() or
|
||||
result = super.getACommandArgument().(StringOps::ConcatenationRoot).getALeaf()
|
||||
}
|
||||
|
||||
override DataFlow::Node getHost() { none() }
|
||||
|
||||
@@ -16,16 +16,12 @@ module Electron {
|
||||
/**
|
||||
* An instantiation of `BrowserWindow` or `BrowserView`.
|
||||
*/
|
||||
abstract private class NewBrowserObject extends BrowserObject {
|
||||
DataFlow::NewNode self;
|
||||
|
||||
NewBrowserObject() { this = self }
|
||||
|
||||
abstract private class NewBrowserObject extends BrowserObject instanceof DataFlow::NewNode {
|
||||
/**
|
||||
* Gets the data flow node from which this instantiation takes its `webPreferences` object.
|
||||
*/
|
||||
DataFlow::SourceNode getWebPreferences() {
|
||||
result = self.getOptionArgument(0, "webPreferences").getALocalSource()
|
||||
result = super.getOptionArgument(0, "webPreferences").getALocalSource()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,8 +178,7 @@ module Electron {
|
||||
/**
|
||||
* A Node.js-style HTTP or HTTPS request made using an Electron module.
|
||||
*/
|
||||
class ElectronClientRequest extends NodeJSLib::NodeJSClientRequest {
|
||||
ElectronClientRequest() { this instanceof ElectronClientRequest::Range }
|
||||
class ElectronClientRequest extends NodeJSLib::NodeJSClientRequest instanceof ElectronClientRequest::Range {
|
||||
}
|
||||
|
||||
module ElectronClientRequest {
|
||||
|
||||
@@ -76,17 +76,11 @@ module Express {
|
||||
result = "del"
|
||||
}
|
||||
|
||||
private class RouterRange extends Routing::Router::Range {
|
||||
RouterDefinition def;
|
||||
|
||||
RouterRange() { this = def }
|
||||
|
||||
override DataFlow::SourceNode getAReference() { result = def.ref() }
|
||||
private class RouterRange extends Routing::Router::Range instanceof RouterDefinition {
|
||||
override DataFlow::SourceNode getAReference() { result = super.ref() }
|
||||
}
|
||||
|
||||
private class RoutingTreeSetup extends Routing::RouteSetup::MethodCall {
|
||||
RoutingTreeSetup() { this instanceof RouteSetup }
|
||||
|
||||
private class RoutingTreeSetup extends Routing::RouteSetup::MethodCall instanceof RouteSetup {
|
||||
override string getRelativePath() {
|
||||
not this.getMethodName() = "param" and // do not treat parameter name as a path
|
||||
result = this.getArgument(0).getStringValue()
|
||||
|
||||
@@ -18,9 +18,7 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A header produced by a route handler of the "x-frame-options" module.
|
||||
*/
|
||||
class XFrameOptionsRouteHandlerHeader extends Http::ImplicitHeaderDefinition {
|
||||
XFrameOptionsRouteHandlerHeader() { this instanceof XFrameOptionsRouteHandler }
|
||||
|
||||
class XFrameOptionsRouteHandlerHeader extends Http::ImplicitHeaderDefinition instanceof XFrameOptionsRouteHandler {
|
||||
override predicate defines(string headerName, string headerValue) {
|
||||
xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue)
|
||||
}
|
||||
@@ -45,9 +43,7 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A header produced by a route handler of the "frameguard" module.
|
||||
*/
|
||||
class FrameGuardRouteHandlerHeader extends Http::ImplicitHeaderDefinition {
|
||||
FrameGuardRouteHandlerHeader() { this instanceof FrameGuardRouteHandler }
|
||||
|
||||
class FrameGuardRouteHandlerHeader extends Http::ImplicitHeaderDefinition instanceof FrameGuardRouteHandler {
|
||||
override predicate defines(string headerName, string headerValue) {
|
||||
xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue)
|
||||
}
|
||||
@@ -70,9 +66,7 @@ module ExpressLibraries {
|
||||
/**
|
||||
* A header produced by a route handler of the "helmet" module.
|
||||
*/
|
||||
class HelmetRouteHandlerHeader extends Http::ImplicitHeaderDefinition {
|
||||
HelmetRouteHandlerHeader() { this instanceof HelmetRouteHandler }
|
||||
|
||||
class HelmetRouteHandlerHeader extends Http::ImplicitHeaderDefinition instanceof HelmetRouteHandler {
|
||||
override predicate defines(string headerName, string headerValue) {
|
||||
xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue)
|
||||
}
|
||||
|
||||
@@ -168,11 +168,8 @@ module Fastify {
|
||||
}
|
||||
}
|
||||
|
||||
private class ShorthandRoutingTreeSetup extends Routing::RouteSetup::MethodCall {
|
||||
ShorthandRoutingTreeSetup() {
|
||||
this instanceof RouteSetup and
|
||||
not this.getMethodName() = "route"
|
||||
}
|
||||
private class ShorthandRoutingTreeSetup extends Routing::RouteSetup::MethodCall instanceof RouteSetup {
|
||||
ShorthandRoutingTreeSetup() { not this.getMethodName() = "route" }
|
||||
|
||||
override string getRelativePath() { result = this.getArgument(0).getStringValue() }
|
||||
|
||||
@@ -186,11 +183,8 @@ module Fastify {
|
||||
.splitAt(",", n)
|
||||
}
|
||||
|
||||
private class FullRoutingTreeSetup extends Routing::RouteSetup::MethodCall {
|
||||
FullRoutingTreeSetup() {
|
||||
this instanceof RouteSetup and
|
||||
this.getMethodName() = "route"
|
||||
}
|
||||
private class FullRoutingTreeSetup extends Routing::RouteSetup::MethodCall instanceof RouteSetup {
|
||||
FullRoutingTreeSetup() { this.getMethodName() = "route" }
|
||||
|
||||
override string getRelativePath() { result = this.getOptionArgument(0, "url").getStringValue() }
|
||||
|
||||
|
||||
@@ -156,19 +156,14 @@ module Http {
|
||||
/**
|
||||
* An expression that sets the `Set-Cookie` header of an HTTP response.
|
||||
*/
|
||||
class SetCookieHeader extends CookieDefinition {
|
||||
HeaderDefinition header;
|
||||
|
||||
SetCookieHeader() {
|
||||
this = header and
|
||||
header.getAHeaderName() = "set-cookie"
|
||||
}
|
||||
class SetCookieHeader extends CookieDefinition instanceof HeaderDefinition {
|
||||
SetCookieHeader() { super.getAHeaderName() = "set-cookie" }
|
||||
|
||||
override DataFlow::Node getHeaderArgument() {
|
||||
header.(ExplicitHeaderDefinition).definesHeaderValue("set-cookie", result)
|
||||
this.(ExplicitHeaderDefinition).definesHeaderValue("set-cookie", result)
|
||||
}
|
||||
|
||||
override RouteHandler getRouteHandler() { result = header.getRouteHandler() }
|
||||
override RouteHandler getRouteHandler() { result = HeaderDefinition.super.getRouteHandler() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -174,23 +174,19 @@ module Templating {
|
||||
/**
|
||||
* A place where a template is instantiated or rendered.
|
||||
*/
|
||||
class TemplateInstantiation extends DataFlow::Node {
|
||||
TemplateInstantiation::Range range;
|
||||
|
||||
TemplateInstantiation() { this = range }
|
||||
|
||||
class TemplateInstantiation extends DataFlow::Node instanceof TemplateInstantiation::Range {
|
||||
/** Gets a data flow node that refers to the instantiated template string, if any. */
|
||||
DataFlow::SourceNode getOutput() { result = range.getOutput() }
|
||||
DataFlow::SourceNode getOutput() { result = super.getOutput() }
|
||||
|
||||
/** Gets a data flow node that refers a template file to be instantiated, if any. */
|
||||
DataFlow::Node getTemplateFileNode() { result = range.getTemplateFileNode() }
|
||||
DataFlow::Node getTemplateFileNode() { result = super.getTemplateFileNode() }
|
||||
|
||||
/** Gets a data flow node that refers to an object whose properties become variables in the template. */
|
||||
DataFlow::Node getTemplateParamsNode() { result = range.getTemplateParamsNode() }
|
||||
DataFlow::Node getTemplateParamsNode() { result = super.getTemplateParamsNode() }
|
||||
|
||||
/** Gets a data flow node that provides the value for the template variable at the given access path. */
|
||||
DataFlow::Node getTemplateParamForValue(string accessPath) {
|
||||
result = range.getTemplateParamForValue(accessPath)
|
||||
result = super.getTemplateParamForValue(accessPath)
|
||||
}
|
||||
|
||||
/** Gets the template file instantiated here, if any. */
|
||||
@@ -203,7 +199,7 @@ module Templating {
|
||||
*
|
||||
* If not known, the relevant syntax will be determined by a heuristic.
|
||||
*/
|
||||
TemplateSyntax getTemplateSyntax() { result = range.getTemplateSyntax() }
|
||||
TemplateSyntax getTemplateSyntax() { result = super.getTemplateSyntax() }
|
||||
}
|
||||
|
||||
/** Companion module to the `TemplateInstantiation` class. */
|
||||
|
||||
@@ -11,24 +11,19 @@ private import semmle.javascript.frameworks.ConnectExpressShared
|
||||
* Add `NodeJSLib::RouteHandlerCandidate` to the extent of `NodeJSLib::RouteHandler`.
|
||||
*/
|
||||
private class PromotedNodeJSLibCandidate extends NodeJSLib::RouteHandler,
|
||||
Http::Servers::StandardRouteHandler {
|
||||
PromotedNodeJSLibCandidate() { this instanceof NodeJSLib::RouteHandlerCandidate }
|
||||
}
|
||||
Http::Servers::StandardRouteHandler instanceof NodeJSLib::RouteHandlerCandidate { }
|
||||
|
||||
/**
|
||||
* Add `Hapi::RouteHandlerCandidate` to the extent of `Hapi::RouteHandler`.
|
||||
*/
|
||||
private class PromotedHapiCandidate extends Hapi::RouteHandler, Http::Servers::StandardRouteHandler {
|
||||
PromotedHapiCandidate() { this instanceof Hapi::RouteHandlerCandidate }
|
||||
private class PromotedHapiCandidate extends Hapi::RouteHandler, Http::Servers::StandardRouteHandler instanceof Hapi::RouteHandlerCandidate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Express::RouteHandler`.
|
||||
*/
|
||||
private class PromotedExpressCandidate extends Express::RouteHandler,
|
||||
Http::Servers::StandardRouteHandler {
|
||||
PromotedExpressCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate }
|
||||
|
||||
Http::Servers::StandardRouteHandler instanceof ConnectExpressShared::RouteHandlerCandidate {
|
||||
override DataFlow::ParameterNode getRouteHandlerParameter(string kind) {
|
||||
result = ConnectExpressShared::getRouteHandlerParameter(this, kind)
|
||||
}
|
||||
@@ -38,9 +33,7 @@ private class PromotedExpressCandidate extends Express::RouteHandler,
|
||||
* Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Connect::RouteHandler`.
|
||||
*/
|
||||
private class PromotedConnectCandidate extends Connect::RouteHandler,
|
||||
Http::Servers::StandardRouteHandler {
|
||||
PromotedConnectCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate }
|
||||
|
||||
Http::Servers::StandardRouteHandler instanceof ConnectExpressShared::RouteHandlerCandidate {
|
||||
override DataFlow::ParameterNode getRouteHandlerParameter(string kind) {
|
||||
result = ConnectExpressShared::getRouteHandlerParameter(this, kind)
|
||||
}
|
||||
|
||||
@@ -27,9 +27,7 @@ private class RemoteFlowPassword extends HeuristicSource, RemoteFlowSource {
|
||||
* since it does not properly escape single quotes and dollar symbols.
|
||||
*/
|
||||
private class JsonStringifyAsCommandInjectionSource extends HeuristicSource,
|
||||
CommandInjection::Source {
|
||||
JsonStringifyAsCommandInjectionSource() { this instanceof JsonStringifyCall }
|
||||
|
||||
CommandInjection::Source instanceof JsonStringifyCall {
|
||||
override string getSourceType() { result = "a string from JSON.stringify" }
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@ string describeCharacters(string rep) {
|
||||
* A local sequence of calls to `String.prototype.replace`,
|
||||
* represented by the last call.
|
||||
*/
|
||||
class StringReplaceCallSequence extends DataFlow::CallNode {
|
||||
class StringReplaceCallSequence extends DataFlow::CallNode instanceof StringReplaceCall {
|
||||
StringReplaceCallSequence() {
|
||||
this instanceof StringReplaceCall and
|
||||
not exists(getAStringReplaceMethodCall(this)) // terminal
|
||||
}
|
||||
|
||||
|
||||
@@ -10,21 +10,17 @@ import Declarations.UnusedVariable
|
||||
* A call that executes a system command.
|
||||
* This class provides utility predicates for reasoning about command execution calls.
|
||||
*/
|
||||
private class CommandCall extends DataFlow::InvokeNode {
|
||||
SystemCommandExecution command;
|
||||
|
||||
CommandCall() { this = command }
|
||||
|
||||
private class CommandCall extends DataFlow::InvokeNode instanceof SystemCommandExecution {
|
||||
/**
|
||||
* Holds if the call is synchronous (e.g. `execFileSync`).
|
||||
*/
|
||||
predicate isSync() { command.isSync() }
|
||||
predicate isSync() { super.isSync() }
|
||||
|
||||
/**
|
||||
* Gets a list that specifies the arguments given to the command.
|
||||
*/
|
||||
DataFlow::ArrayCreationNode getArgumentList() {
|
||||
result = command.getArgumentList().getALocalSource()
|
||||
result = super.getArgumentList().getALocalSource()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +38,7 @@ private class CommandCall extends DataFlow::InvokeNode {
|
||||
/**
|
||||
* Gets the data-flow node (if it exists) for an options argument for an `exec`-like call.
|
||||
*/
|
||||
DataFlow::Node getOptionsArg() { result = command.getOptionsArg() }
|
||||
DataFlow::Node getOptionsArg() { result = super.getOptionsArg() }
|
||||
|
||||
/**
|
||||
* Gets the constant-string parts that are not part of the command itself.
|
||||
@@ -99,7 +95,6 @@ private string getConstantStringParts(DataFlow::Node node) {
|
||||
*/
|
||||
class UselessCat extends CommandCall {
|
||||
UselessCat() {
|
||||
this = command and
|
||||
this.isACallTo(getACatExecuteable()) and
|
||||
// There is a file to read, it's not just spawning `cat`.
|
||||
not (
|
||||
|
||||
@@ -40,9 +40,7 @@ module CleartextStorage {
|
||||
}
|
||||
|
||||
/** A call to any function whose name suggests that it encodes or encrypts its arguments. */
|
||||
class ProtectSanitizer extends Sanitizer {
|
||||
ProtectSanitizer() { this instanceof ProtectCall }
|
||||
}
|
||||
class ProtectSanitizer extends Sanitizer instanceof ProtectCall { }
|
||||
|
||||
/**
|
||||
* An expression set as a value on a cookie instance.
|
||||
|
||||
@@ -39,11 +39,8 @@ module ClientSideUrlRedirect {
|
||||
}
|
||||
|
||||
/** A source of remote user input, considered as a flow source for unvalidated URL redirects. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() {
|
||||
this instanceof RemoteFlowSource and
|
||||
not this.(ClientSideRemoteFlowSource).getKind().isPath()
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource {
|
||||
RemoteFlowSourceAsSource() { not this.(ClientSideRemoteFlowSource).getKind().isPath() }
|
||||
|
||||
override DataFlow::FlowLabel getAFlowLabel() {
|
||||
if this.(ClientSideRemoteFlowSource).getKind().isUrl()
|
||||
|
||||
@@ -34,9 +34,7 @@ module CodeInjection {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for code injection. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* An expression which may be interpreted as an AngularJS expression.
|
||||
|
||||
@@ -26,11 +26,8 @@ module CommandInjection {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for command injection. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() {
|
||||
this instanceof RemoteFlowSource and
|
||||
not this instanceof ClientSideRemoteFlowSource
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource {
|
||||
RemoteFlowSourceAsSource() { not this instanceof ClientSideRemoteFlowSource }
|
||||
|
||||
override string getSourceType() { result = "a user-provided value" }
|
||||
}
|
||||
|
||||
@@ -32,9 +32,7 @@ module ConditionalBypass {
|
||||
* A source of remote user input, considered as a flow source for bypass of
|
||||
* sensitive action guards.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* Holds if `bb` dominates the basic block in which `action` occurs.
|
||||
|
||||
@@ -28,11 +28,8 @@ module CorsMisconfigurationForCredentials {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for CORS misconfiguration. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() {
|
||||
this instanceof RemoteFlowSource and
|
||||
not this instanceof ClientSideRemoteFlowSource
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource {
|
||||
RemoteFlowSourceAsSource() { not this instanceof ClientSideRemoteFlowSource }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,15 +19,11 @@ module DeepObjectResourceExhaustion {
|
||||
DataFlow::FlowLabel getAFlowLabel() { result = TaintedObject::label() }
|
||||
}
|
||||
|
||||
private class TaintedObjectSourceAsSource extends Source {
|
||||
TaintedObjectSourceAsSource() { this instanceof TaintedObject::Source }
|
||||
|
||||
private class TaintedObjectSourceAsSource extends Source instanceof TaintedObject::Source {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result = TaintedObject::label() }
|
||||
}
|
||||
|
||||
private class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
|
||||
private class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result.isTaint() }
|
||||
}
|
||||
|
||||
|
||||
@@ -30,19 +30,15 @@ module DifferentKindsComparisonBypass {
|
||||
/**
|
||||
* A HTTP request input that is suspicious to compare with another HTTP request input of a different kind.
|
||||
*/
|
||||
class RequestInputComparisonSource extends Source {
|
||||
Http::RequestInputAccess input;
|
||||
|
||||
RequestInputComparisonSource() { input = this }
|
||||
|
||||
class RequestInputComparisonSource extends Source instanceof Http::RequestInputAccess {
|
||||
override predicate isSuspiciousToCompareWith(Source other) {
|
||||
input.getKind() != other.(RequestInputComparisonSource).getInput().getKind()
|
||||
super.getKind() != other.(RequestInputComparisonSource).getInput().getKind()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP request input of this source.
|
||||
*/
|
||||
private Http::RequestInputAccess getInput() { result = input }
|
||||
private Http::RequestInputAccess getInput() { result = this }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -318,9 +318,7 @@ module DomBasedXss {
|
||||
}
|
||||
|
||||
/** A source of remote user input, considered as a flow source for DOM-based XSS. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* A flow-label representing tainted values where the prefix is attacker controlled.
|
||||
|
||||
@@ -42,9 +42,7 @@ module ExceptionXss {
|
||||
NotYetThrown() { this = "NotYetThrown" }
|
||||
}
|
||||
|
||||
private class XssSourceAsSource extends Source {
|
||||
XssSourceAsSource() { this instanceof Shared::Source }
|
||||
|
||||
private class XssSourceAsSource extends Source instanceof Shared::Source {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result instanceof NotYetThrown }
|
||||
|
||||
override string getDescription() { result = "Exception text" }
|
||||
|
||||
@@ -55,9 +55,7 @@ module ExternalApiUsedWithUntrustedData {
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
private class RemoteFlowAsSource extends Source {
|
||||
RemoteFlowAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* A package name whose entire API is considered "safe" for the purpose of this query.
|
||||
|
||||
@@ -59,9 +59,7 @@ class Configuration extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
/** A node representing data being passed to an external API. */
|
||||
class ExternalApiDataNode extends DataFlow::Node {
|
||||
ExternalApiDataNode() { this instanceof Sink }
|
||||
}
|
||||
class ExternalApiDataNode extends DataFlow::Node instanceof Sink { }
|
||||
|
||||
/** DEPRECATED: Alias for ExternalApiDataNode */
|
||||
deprecated class ExternalAPIDataNode = ExternalApiDataNode;
|
||||
|
||||
@@ -49,9 +49,7 @@ module HardcodedDataInterpretedAsCode {
|
||||
/**
|
||||
* A code injection sink; hard-coded data should not flow here.
|
||||
*/
|
||||
private class DefaultCodeInjectionSink extends Sink {
|
||||
DefaultCodeInjectionSink() { this instanceof CodeInjection::Sink }
|
||||
|
||||
private class DefaultCodeInjectionSink extends Sink instanceof CodeInjection::Sink {
|
||||
override DataFlow::FlowLabel getLabel() { result.isTaint() }
|
||||
|
||||
override string getKind() { result = "Code" }
|
||||
|
||||
@@ -8,9 +8,7 @@ private import HttpToFileAccessCustomizations::HttpToFileAccess
|
||||
/**
|
||||
* An access to a user-controlled HTTP request input, considered as a flow source for writing user-controlled data to files
|
||||
*/
|
||||
private class RequestInputAccessAsSource extends Source {
|
||||
RequestInputAccessAsSource() { this instanceof Http::RequestInputAccess }
|
||||
}
|
||||
private class RequestInputAccessAsSource extends Source instanceof Http::RequestInputAccess { }
|
||||
|
||||
/** A response from a server, considered as a flow source for writing user-controlled data to files. */
|
||||
private class ServerResponseAsSource extends Source {
|
||||
|
||||
@@ -28,16 +28,12 @@ module ImproperCodeSanitization {
|
||||
/**
|
||||
* A call to an HTML sanitizer seen as a source for improper code sanitization
|
||||
*/
|
||||
class HtmlSanitizerCallAsSource extends Source {
|
||||
HtmlSanitizerCallAsSource() { this instanceof HtmlSanitizerCall }
|
||||
}
|
||||
class HtmlSanitizerCallAsSource extends Source instanceof HtmlSanitizerCall { }
|
||||
|
||||
/**
|
||||
* A call to `JSON.stringify()` seen as a source for improper code sanitization
|
||||
*/
|
||||
class JsonStringifyAsSource extends Source {
|
||||
JsonStringifyAsSource() { this instanceof JsonStringifyCall }
|
||||
}
|
||||
class JsonStringifyAsSource extends Source instanceof JsonStringifyCall { }
|
||||
|
||||
/** DEPRECATED: Alias for JsonStringifyAsSource */
|
||||
deprecated class JSONStringifyAsSource = JsonStringifyAsSource;
|
||||
|
||||
@@ -25,8 +25,7 @@ module IndirectCommandInjection {
|
||||
/**
|
||||
* A source of user input from the command-line, considered as a flow source for command injection.
|
||||
*/
|
||||
private class CommandLineArgumentsArrayAsSource extends Source {
|
||||
CommandLineArgumentsArrayAsSource() { this instanceof CommandLineArgumentsArray }
|
||||
private class CommandLineArgumentsArrayAsSource extends Source instanceof CommandLineArgumentsArray {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,17 +78,13 @@ module InsecureRandomness {
|
||||
* A sensitive write, considered as a sink for random values that are not cryptographically
|
||||
* secure.
|
||||
*/
|
||||
class SensitiveWriteSink extends Sink {
|
||||
SensitiveWriteSink() { this instanceof SensitiveWrite }
|
||||
}
|
||||
class SensitiveWriteSink extends Sink instanceof SensitiveWrite { }
|
||||
|
||||
/**
|
||||
* A cryptographic key, considered as a sink for random values that are not cryptographically
|
||||
* secure.
|
||||
*/
|
||||
class CryptoKeySink extends Sink {
|
||||
CryptoKeySink() { this instanceof CryptographicKey }
|
||||
}
|
||||
class CryptoKeySink extends Sink instanceof CryptographicKey { }
|
||||
|
||||
/**
|
||||
* Holds if the step `pred` -> `succ` is an additional taint-step for random values that are not cryptographically secure.
|
||||
|
||||
@@ -35,10 +35,8 @@ class LogInjectionConfiguration extends TaintTracking::Configuration {
|
||||
/**
|
||||
* A source of remote user controlled input.
|
||||
*/
|
||||
class RemoteSource extends Source {
|
||||
RemoteSource() {
|
||||
this instanceof RemoteFlowSource and not this instanceof ClientSideRemoteFlowSource
|
||||
}
|
||||
class RemoteSource extends Source instanceof RemoteFlowSource {
|
||||
RemoteSource() { not this instanceof ClientSideRemoteFlowSource }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,9 +58,7 @@ class StringReplaceSanitizer extends Sanitizer {
|
||||
/**
|
||||
* A call to an HTML sanitizer is considered to sanitize the user input.
|
||||
*/
|
||||
class HtmlSanitizer extends Sanitizer {
|
||||
HtmlSanitizer() { this instanceof HtmlSanitizerCall }
|
||||
}
|
||||
class HtmlSanitizer extends Sanitizer instanceof HtmlSanitizerCall { }
|
||||
|
||||
/**
|
||||
* A call to `JSON.stringify` or similar, seen as sanitizing log output.
|
||||
|
||||
@@ -169,9 +169,7 @@ module LoopBoundInjection {
|
||||
/**
|
||||
* A source of remote user input objects.
|
||||
*/
|
||||
class TaintedObjectSource extends Source {
|
||||
TaintedObjectSource() { this instanceof TaintedObject::Source }
|
||||
}
|
||||
class TaintedObjectSource extends Source instanceof TaintedObject::Source { }
|
||||
|
||||
/**
|
||||
* A sanitizer that blocks taint flow if the array is checked to be an array using an `isArray` function.
|
||||
|
||||
@@ -80,30 +80,22 @@ abstract class ExpensiveAction extends DataFlow::Node {
|
||||
}
|
||||
|
||||
/** A call to an authorization function, considered as an expensive action. */
|
||||
class AuthorizationCallAsExpensiveAction extends ExpensiveAction {
|
||||
AuthorizationCallAsExpensiveAction() { this instanceof AuthorizationCall }
|
||||
|
||||
class AuthorizationCallAsExpensiveAction extends ExpensiveAction instanceof AuthorizationCall {
|
||||
override string describe() { result = "authorization" }
|
||||
}
|
||||
|
||||
/** A file system access, considered as an expensive action. */
|
||||
class FileSystemAccessAsExpensiveAction extends ExpensiveAction {
|
||||
FileSystemAccessAsExpensiveAction() { this instanceof FileSystemAccess }
|
||||
|
||||
class FileSystemAccessAsExpensiveAction extends ExpensiveAction instanceof FileSystemAccess {
|
||||
override string describe() { result = "a file system access" }
|
||||
}
|
||||
|
||||
/** A system command execution, considered as an expensive action. */
|
||||
class SystemCommandExecutionAsExpensiveAction extends ExpensiveAction {
|
||||
SystemCommandExecutionAsExpensiveAction() { this instanceof SystemCommandExecution }
|
||||
|
||||
class SystemCommandExecutionAsExpensiveAction extends ExpensiveAction instanceof SystemCommandExecution {
|
||||
override string describe() { result = "a system command" }
|
||||
}
|
||||
|
||||
/** A database access, considered as an expensive action. */
|
||||
class DatabaseAccessAsExpensiveAction extends ExpensiveAction {
|
||||
DatabaseAccessAsExpensiveAction() { this instanceof DatabaseAccess }
|
||||
|
||||
class DatabaseAccessAsExpensiveAction extends ExpensiveAction instanceof DatabaseAccess {
|
||||
override string describe() { result = "a database access" }
|
||||
}
|
||||
|
||||
@@ -208,8 +200,7 @@ class RateLimiterFlexibleRateLimiter extends DataFlow::FunctionNode {
|
||||
/**
|
||||
* A route-handler expression that is rate-limited by the `rate-limiter-flexible` package.
|
||||
*/
|
||||
class RouteHandlerLimitedByRateLimiterFlexible extends RateLimitingMiddleware {
|
||||
RouteHandlerLimitedByRateLimiterFlexible() { this instanceof RateLimiterFlexibleRateLimiter }
|
||||
class RouteHandlerLimitedByRateLimiterFlexible extends RateLimitingMiddleware instanceof RateLimiterFlexibleRateLimiter {
|
||||
}
|
||||
|
||||
private class FastifyRateLimiter extends RateLimitingMiddleware {
|
||||
|
||||
@@ -31,9 +31,7 @@ module NosqlInjection {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for NoSql injection. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/** An expression interpreted as a NoSql query, viewed as a sink. */
|
||||
class NosqlQuerySink extends Sink instanceof NoSql::Query { }
|
||||
|
||||
@@ -44,9 +44,7 @@ module PostMessageStar {
|
||||
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 {
|
||||
ProtectSanitizer() { this instanceof ProtectCall }
|
||||
}
|
||||
class ProtectSanitizer extends Sanitizer instanceof ProtectCall { }
|
||||
|
||||
/**
|
||||
* An expression sent using `postMessage` without restricting the target window origin.
|
||||
|
||||
@@ -57,9 +57,7 @@ module PrototypePollutingAssignment {
|
||||
}
|
||||
|
||||
/** A remote flow source or location.{hash,search} as a taint source. */
|
||||
private class DefaultSource extends Source {
|
||||
DefaultSource() { this instanceof RemoteFlowSource }
|
||||
|
||||
private class DefaultSource extends Source instanceof RemoteFlowSource {
|
||||
override string describe() { result = "user controlled input" }
|
||||
}
|
||||
|
||||
|
||||
@@ -68,18 +68,14 @@ module PrototypePollution {
|
||||
* Note that values from this type of source will need to flow through a `JSON.parse` call
|
||||
* in order to be flagged for prototype pollution.
|
||||
*/
|
||||
private class RemoteFlowAsSource extends Source {
|
||||
RemoteFlowAsSource() { this instanceof RemoteFlowSource }
|
||||
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result.isTaint() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A source of user-controlled objects.
|
||||
*/
|
||||
private class TaintedObjectSource extends Source {
|
||||
TaintedObjectSource() { this instanceof TaintedObject::Source }
|
||||
|
||||
private class TaintedObjectSource extends Source instanceof TaintedObject::Source {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result = TaintedObject::label() }
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,8 @@ module RegExpInjection {
|
||||
* A source of remote user input, considered as a flow source for regular
|
||||
* expression injection.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() {
|
||||
this instanceof RemoteFlowSource and
|
||||
not this instanceof ClientSideRemoteFlowSource
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource {
|
||||
RemoteFlowSourceAsSource() { not this instanceof ClientSideRemoteFlowSource }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,9 +34,7 @@ module RemotePropertyInjection {
|
||||
* A source of remote user input, considered as a flow source for remote property
|
||||
* injection.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* A sink for property writes with dynamically computed property name.
|
||||
|
||||
@@ -27,9 +27,7 @@ module ShellCommandInjectionFromEnvironment {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** An file name from the local file system, considered as a flow source for command injection. */
|
||||
class FileNameSourceAsSource extends Source {
|
||||
FileNameSourceAsSource() { this instanceof FileNameSource }
|
||||
|
||||
class FileNameSourceAsSource extends Source instanceof FileNameSource {
|
||||
override string getSourceType() { result = "file name" }
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,7 @@ module SqlInjection {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for string based query injection. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/** An SQL expression passed to an API call that executes SQL. */
|
||||
class SqlInjectionExprSink extends Sink instanceof SQL::SqlString { }
|
||||
@@ -36,9 +34,7 @@ module SqlInjection {
|
||||
}
|
||||
|
||||
/** An GraphQL expression passed to an API call that executes GraphQL. */
|
||||
class GraphqlInjectionSink extends Sink {
|
||||
GraphqlInjectionSink() { this instanceof GraphQL::GraphQLString }
|
||||
}
|
||||
class GraphqlInjectionSink extends Sink instanceof GraphQL::GraphQLString { }
|
||||
|
||||
/**
|
||||
* An LDAPjs sink.
|
||||
|
||||
@@ -27,13 +27,10 @@ module StoredXss {
|
||||
}
|
||||
|
||||
/** A file name, considered as a flow source for stored XSS. */
|
||||
class FileNameSourceAsSource extends Source {
|
||||
FileNameSourceAsSource() { this instanceof FileNameSource }
|
||||
}
|
||||
class FileNameSourceAsSource extends Source instanceof FileNameSource { }
|
||||
|
||||
/** An instance of user-controlled torrent information, considered as a flow source for stored XSS. */
|
||||
class UserControlledTorrentInfoAsSource extends Source {
|
||||
UserControlledTorrentInfoAsSource() { this instanceof ParseTorrent::UserControlledTorrentInfo }
|
||||
class UserControlledTorrentInfoAsSource extends Source instanceof ParseTorrent::UserControlledTorrentInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -345,21 +345,16 @@ module TaintedPath {
|
||||
*
|
||||
* This is relevant for paths that are known to be normalized.
|
||||
*/
|
||||
class StartsWithDotDotSanitizer extends BarrierGuardNode {
|
||||
StringOps::StartsWith startsWith;
|
||||
|
||||
StartsWithDotDotSanitizer() {
|
||||
this = startsWith and
|
||||
isDotDotSlashPrefix(startsWith.getSubstring())
|
||||
}
|
||||
class StartsWithDotDotSanitizer extends BarrierGuardNode instanceof StringOps::StartsWith {
|
||||
StartsWithDotDotSanitizer() { isDotDotSlashPrefix(super.getSubstring()) }
|
||||
|
||||
override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) {
|
||||
// Sanitize in the false case for:
|
||||
// .startsWith(".")
|
||||
// .startsWith("..")
|
||||
// .startsWith("../")
|
||||
outcome = startsWith.getPolarity().booleanNot() and
|
||||
e = startsWith.getBaseString().asExpr() and
|
||||
outcome = super.getPolarity().booleanNot() and
|
||||
e = super.getBaseString().asExpr() and
|
||||
exists(Label::PosixPath posixPath | posixPath = label |
|
||||
posixPath.isNormalized() and
|
||||
posixPath.isRelative()
|
||||
|
||||
@@ -30,15 +30,11 @@ module TemplateObjectInjection {
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
private class TaintedObjectSourceAsSource extends Source {
|
||||
TaintedObjectSourceAsSource() { this instanceof TaintedObject::Source }
|
||||
|
||||
private class TaintedObjectSourceAsSource extends Source instanceof TaintedObject::Source {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result = TaintedObject::label() }
|
||||
}
|
||||
|
||||
private class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
|
||||
private class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource {
|
||||
override DataFlow::FlowLabel getAFlowLabel() { result.isTaint() }
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,7 @@ module UnsafeDeserialization {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for unsafe deserialization. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* An expression passed to one of the unsafe load functions of the `js-yaml` package.
|
||||
|
||||
@@ -54,9 +54,7 @@ module UnsafeDynamicMethodAccess {
|
||||
/**
|
||||
* A source of remote user input, considered as a source for unsafe dynamic method access.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* A function invocation of an unsafe function, as a sink for remote unsafe dynamic method access.
|
||||
|
||||
@@ -175,10 +175,8 @@ module UnsafeJQueryPlugin {
|
||||
/**
|
||||
* An argument that may act as an HTML fragment rather than a CSS selector, as a sink for remote unsafe jQuery plugins.
|
||||
*/
|
||||
class AmbiguousHtmlOrSelectorArgumentAsSink extends Sink {
|
||||
AmbiguousHtmlOrSelectorArgumentAsSink() {
|
||||
this instanceof AmbiguousHtmlOrSelectorArgument and not isLikelyIntentionalHtmlSink(this)
|
||||
}
|
||||
class AmbiguousHtmlOrSelectorArgumentAsSink extends Sink instanceof AmbiguousHtmlOrSelectorArgument {
|
||||
AmbiguousHtmlOrSelectorArgumentAsSink() { not isLikelyIntentionalHtmlSink(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,9 +60,7 @@ module UnvalidatedDynamicMethodCall {
|
||||
/**
|
||||
* A source of remote user input, considered as a source for unvalidated dynamic method calls.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* The page URL considered as a flow source for unvalidated dynamic method calls.
|
||||
|
||||
@@ -24,9 +24,7 @@ module XmlBomb {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for XML bomb vulnerabilities. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* An access to `document.location`, considered as a flow source for XML bomb vulnerabilities.
|
||||
|
||||
@@ -24,9 +24,7 @@ module XpathInjection {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for XPath injection. */
|
||||
class RemoteSource extends Source {
|
||||
RemoteSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* The `expression` argument to `xpath.parse` or `xpath.select` (and similar) from
|
||||
|
||||
@@ -24,9 +24,7 @@ module Xxe {
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for XXE vulnerabilities. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* An access to `document.location`, considered as a flow source for XXE vulnerabilities.
|
||||
|
||||
@@ -52,9 +52,7 @@ class SuppressionComment extends Locatable {
|
||||
/**
|
||||
* The scope of an alert suppression comment.
|
||||
*/
|
||||
class SuppressionScope extends @locatable {
|
||||
SuppressionScope() { this instanceof SuppressionComment }
|
||||
|
||||
class SuppressionScope extends @locatable instanceof SuppressionComment {
|
||||
/** Gets a suppression comment with this scope. */
|
||||
SuppressionComment getSuppressionComment() { result = this }
|
||||
|
||||
@@ -68,7 +66,7 @@ class SuppressionScope extends @locatable {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
|
||||
super.covers(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
|
||||
Reference in New Issue
Block a user