diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index a768f29795c6..dc461861aceb 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -17,13 +17,9 @@ private import semmle.python.Frameworks * Extend this class to refine existing API models. If you want to model new APIs, * extend `SystemCommandExecution::Range` instead. */ -class SystemCommandExecution extends DataFlow::Node { - SystemCommandExecution::Range range; - - SystemCommandExecution() { this = range } - +class SystemCommandExecution extends DataFlow::Node instanceof SystemCommandExecution::Range { /** Gets the argument that specifies the command to be executed. */ - DataFlow::Node getCommand() { result = range.getCommand() } + DataFlow::Node getCommand() { result = super.getCommand() } } /** Provides a class for modeling new system-command execution APIs. */ @@ -48,13 +44,9 @@ module SystemCommandExecution { * Extend this class to refine existing API models. If you want to model new APIs, * extend `FileSystemAccess::Range` instead. */ -class FileSystemAccess extends DataFlow::Node { - FileSystemAccess::Range range; - - FileSystemAccess() { this = range } - +class FileSystemAccess extends DataFlow::Node instanceof FileSystemAccess::Range { /** Gets an argument to this file system access that is interpreted as a path. */ - DataFlow::Node getAPathArgument() { result = range.getAPathArgument() } + DataFlow::Node getAPathArgument() { result = super.getAPathArgument() } } /** Provides a class for modeling new file system access APIs. */ @@ -78,14 +70,12 @@ module FileSystemAccess { * Extend this class to refine existing API models. If you want to model new APIs, * extend `FileSystemWriteAccess::Range` instead. */ -class FileSystemWriteAccess extends FileSystemAccess { - override FileSystemWriteAccess::Range range; - +class FileSystemWriteAccess extends FileSystemAccess instanceof FileSystemWriteAccess::Range { /** * Gets a node that represents data to be written to the file system (possibly with * some transformation happening before it is written, like JSON encoding). */ - DataFlow::Node getADataNode() { result = range.getADataNode() } + DataFlow::Node getADataNode() { result = super.getADataNode() } } /** Provides a class for modeling new file system writes. */ @@ -111,13 +101,9 @@ module Path { * A data-flow node that performs path normalization. This is often needed in order * to safely access paths. */ - class PathNormalization extends DataFlow::Node { - PathNormalization::Range range; - - PathNormalization() { this = range } - + class PathNormalization extends DataFlow::Node instanceof PathNormalization::Range { /** Gets an argument to this path normalization that is interpreted as a path. */ - DataFlow::Node getPathArg() { result = range.getPathArg() } + DataFlow::Node getPathArg() { result = super.getPathArg() } } /** Provides a class for modeling new path normalization APIs. */ @@ -133,12 +119,10 @@ module Path { } /** A data-flow node that checks that a path is safe to access. */ - class SafeAccessCheck extends DataFlow::BarrierGuard { - SafeAccessCheck::Range range; - - SafeAccessCheck() { this = range } - - override predicate checks(ControlFlowNode node, boolean branch) { range.checks(node, branch) } + class SafeAccessCheck extends DataFlow::BarrierGuard instanceof SafeAccessCheck::Range { + override predicate checks(ControlFlowNode node, boolean branch) { + SafeAccessCheck::Range.super.checks(node, branch) + } } /** Provides a class for modeling new path safety checks. */ @@ -160,22 +144,18 @@ module Path { * Extend this class to refine existing API models. If you want to model new APIs, * extend `Decoding::Range` instead. */ -class Decoding extends DataFlow::Node { - Decoding::Range range; - - Decoding() { this = range } - +class Decoding extends DataFlow::Node instanceof Decoding::Range { /** Holds if this call may execute code embedded in its input. */ - predicate mayExecuteInput() { range.mayExecuteInput() } + predicate mayExecuteInput() { super.mayExecuteInput() } /** Gets an input that is decoded by this function. */ - DataFlow::Node getAnInput() { result = range.getAnInput() } + DataFlow::Node getAnInput() { result = super.getAnInput() } /** Gets the output that contains the decoded data produced by this function. */ - DataFlow::Node getOutput() { result = range.getOutput() } + DataFlow::Node getOutput() { result = super.getOutput() } /** Gets an identifier for the format this function decodes from, such as "JSON". */ - string getFormat() { result = range.getFormat() } + string getFormat() { result = super.getFormat() } } /** Provides a class for modeling new decoding mechanisms. */ @@ -226,19 +206,15 @@ private class DecodingAdditionalTaintStep extends TaintTracking::AdditionalTaint * Extend this class to refine existing API models. If you want to model new APIs, * extend `Encoding::Range` instead. */ -class Encoding extends DataFlow::Node { - Encoding::Range range; - - Encoding() { this = range } - +class Encoding extends DataFlow::Node instanceof Encoding::Range { /** Gets an input that is encoded by this function. */ - DataFlow::Node getAnInput() { result = range.getAnInput() } + DataFlow::Node getAnInput() { result = super.getAnInput() } /** Gets the output that contains the encoded data produced by this function. */ - DataFlow::Node getOutput() { result = range.getOutput() } + DataFlow::Node getOutput() { result = super.getOutput() } /** Gets an identifier for the format this function decodes from, such as "JSON". */ - string getFormat() { result = range.getFormat() } + string getFormat() { result = super.getFormat() } } /** Provides a class for modeling new encoding mechanisms. */ @@ -280,13 +256,9 @@ private class EncodingAdditionalTaintStep extends TaintTracking::AdditionalTaint * Extend this class to refine existing API models. If you want to model new APIs, * extend `Logging::Range` instead. */ -class Logging extends DataFlow::Node { - Logging::Range range; - - Logging() { this = range } - +class Logging extends DataFlow::Node instanceof Logging::Range { /** Gets an input that is logged. */ - DataFlow::Node getAnInput() { result = range.getAnInput() } + DataFlow::Node getAnInput() { result = super.getAnInput() } } /** Provides a class for modeling new logging mechanisms. */ @@ -309,13 +281,9 @@ module Logging { * Extend this class to refine existing API models. If you want to model new APIs, * extend `CodeExecution::Range` instead. */ -class CodeExecution extends DataFlow::Node { - CodeExecution::Range range; - - CodeExecution() { this = range } - +class CodeExecution extends DataFlow::Node instanceof CodeExecution::Range { /** Gets the argument that specifies the code to be executed. */ - DataFlow::Node getCode() { result = range.getCode() } + DataFlow::Node getCode() { result = super.getCode() } } /** Provides a class for modeling new dynamic code execution APIs. */ @@ -343,13 +311,9 @@ module CodeExecution { * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlConstruction::Range` instead. */ -class SqlConstruction extends DataFlow::Node { - SqlConstruction::Range range; - - SqlConstruction() { this = range } - +class SqlConstruction extends DataFlow::Node instanceof SqlConstruction::Range { /** Gets the argument that specifies the SQL statements to be constructed. */ - DataFlow::Node getSql() { result = range.getSql() } + DataFlow::Node getSql() { result = super.getSql() } } /** Provides a class for modeling new SQL execution APIs. */ @@ -380,13 +344,9 @@ module SqlConstruction { * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlExecution::Range` instead. */ -class SqlExecution extends DataFlow::Node { - SqlExecution::Range range; - - SqlExecution() { this = range } - +class SqlExecution extends DataFlow::Node instanceof SqlExecution::Range { /** Gets the argument that specifies the SQL statements to be executed. */ - DataFlow::Node getSql() { result = range.getSql() } + DataFlow::Node getSql() { result = super.getSql() } } /** Provides a class for modeling new SQL execution APIs. */ @@ -412,22 +372,18 @@ module SqlExecution { * Extend this class to refine existing API models. If you want to model new APIs, * extend `RegexExecution::Range` instead. */ -class RegexExecution extends DataFlow::Node { - RegexExecution::Range range; - - RegexExecution() { this = range } - +class RegexExecution extends DataFlow::Node instanceof RegexExecution::Range { /** Gets the data flow node for the regex being executed by this node. */ - DataFlow::Node getRegex() { result = range.getRegex() } + DataFlow::Node getRegex() { result = super.getRegex() } /** Gets a dataflow node for the string to be searched or matched against. */ - DataFlow::Node getString() { result = range.getString() } + DataFlow::Node getString() { result = super.getString() } /** * Gets the name of this regex execution, typically the name of an executing method. * This is used for nice alert messages and should include the module if possible. */ - string getName() { result = range.getName() } + string getName() { result = super.getName() } } /** Provides classes for modeling new regular-expression execution APIs. */ @@ -466,19 +422,15 @@ module XML { * Extend this class to refine existing API models. If you want to model new APIs, * extend `XPathConstruction::Range` instead. */ - class XPathConstruction extends DataFlow::Node { - XPathConstruction::Range range; - - XPathConstruction() { this = range } - + class XPathConstruction extends DataFlow::Node instanceof XPathConstruction::Range { /** Gets the argument that specifies the XPath expressions to be constructed. */ - DataFlow::Node getXPath() { result = range.getXPath() } + DataFlow::Node getXPath() { result = super.getXPath() } /** * Gets the name of this XPath expression construction, typically the name of an executing method. * This is used for nice alert messages and should include the module if possible. */ - string getName() { result = range.getName() } + string getName() { result = super.getName() } } /** Provides a class for modeling new XPath construction APIs. */ @@ -513,19 +465,15 @@ module XML { * Extend this class to refine existing API models. If you want to model new APIs, * extend `XPathExecution::Range` instead. */ - class XPathExecution extends DataFlow::Node { - XPathExecution::Range range; - - XPathExecution() { this = range } - + class XPathExecution extends DataFlow::Node instanceof XPathExecution::Range { /** Gets the data flow node for the XPath expression being executed by this node. */ - DataFlow::Node getXPath() { result = range.getXPath() } + DataFlow::Node getXPath() { result = super.getXPath() } /** * Gets the name of this XPath expression execution, typically the name of an executing method. * This is used for nice alert messages and should include the module if possible. */ - string getName() { result = range.getName() } + string getName() { result = super.getName() } } /** Provides classes for modeling new regular-expression execution APIs. */ @@ -560,16 +508,12 @@ module LDAP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `LDAPQuery::Range` instead. */ - class LdapExecution extends DataFlow::Node { - LdapExecution::Range range; - - LdapExecution() { this = range } - + class LdapExecution extends DataFlow::Node instanceof LdapExecution::Range { /** Gets the argument containing the filter string. */ - DataFlow::Node getFilter() { result = range.getFilter() } + DataFlow::Node getFilter() { result = super.getFilter() } /** Gets the argument containing the base DN. */ - DataFlow::Node getBaseDn() { result = range.getBaseDn() } + DataFlow::Node getBaseDn() { result = super.getBaseDn() } } /** Provides classes for modeling new LDAP query execution-related APIs. */ @@ -597,26 +541,23 @@ module LDAP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `Escaping::Range` instead. */ -class Escaping extends DataFlow::Node { - Escaping::Range range; - +class Escaping extends DataFlow::Node instanceof Escaping::Range { Escaping() { - this = range and // escapes that don't have _both_ input/output defined are not valid - exists(range.getAnInput()) and - exists(range.getOutput()) + exists(super.getAnInput()) and + exists(super.getOutput()) } /** Gets an input that will be escaped. */ - DataFlow::Node getAnInput() { result = range.getAnInput() } + DataFlow::Node getAnInput() { result = super.getAnInput() } /** Gets the output that contains the escaped data. */ - DataFlow::Node getOutput() { result = range.getOutput() } + DataFlow::Node getOutput() { result = super.getOutput() } /** * Gets the context that this function escapes for, such as `html`, or `url`. */ - string getKind() { result = range.getKind() } + string getKind() { result = super.getKind() } } /** Provides a class for modeling new escaping APIs. */ @@ -674,7 +615,7 @@ module Escaping { * `

{}

`. */ class HtmlEscaping extends Escaping { - HtmlEscaping() { range.getKind() = Escaping::getHtmlKind() } + HtmlEscaping() { super.getKind() = Escaping::getHtmlKind() } } /** @@ -682,7 +623,7 @@ class HtmlEscaping extends Escaping { * the body of a regex. */ class RegexEscaping extends Escaping { - RegexEscaping() { range.getKind() = Escaping::getRegexKind() } + RegexEscaping() { super.getKind() = Escaping::getRegexKind() } } /** @@ -690,14 +631,14 @@ class RegexEscaping extends Escaping { * in an LDAP search. */ class LdapDnEscaping extends Escaping { - LdapDnEscaping() { range.getKind() = Escaping::getLdapDnKind() } + LdapDnEscaping() { super.getKind() = Escaping::getLdapDnKind() } } /** * An escape of a string so it can be safely used as a filter in an LDAP search. */ class LdapFilterEscaping extends Escaping { - LdapFilterEscaping() { range.getKind() = Escaping::getLdapFilterKind() } + LdapFilterEscaping() { super.getKind() = Escaping::getLdapFilterKind() } } /** Provides classes for modeling HTTP-related APIs. */ @@ -716,29 +657,25 @@ module HTTP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `RouteSetup::Range` instead. */ - class RouteSetup extends DataFlow::Node { - RouteSetup::Range range; - - RouteSetup() { this = range } - + class RouteSetup extends DataFlow::Node instanceof RouteSetup::Range { /** Gets the URL pattern for this route, if it can be statically determined. */ - string getUrlPattern() { result = range.getUrlPattern() } + string getUrlPattern() { result = super.getUrlPattern() } /** * Gets a function that will handle incoming requests for this route, if any. * * NOTE: This will be modified in the near future to have a `RequestHandler` result, instead of a `Function`. */ - Function getARequestHandler() { result = range.getARequestHandler() } + Function getARequestHandler() { result = super.getARequestHandler() } /** * Gets a parameter that will receive parts of the url when handling incoming * requests for this route, if any. These automatically become a `RemoteFlowSource`. */ - Parameter getARoutedParameter() { result = range.getARoutedParameter() } + Parameter getARoutedParameter() { result = super.getARoutedParameter() } /** Gets a string that identifies the framework used for this route setup. */ - string getFramework() { result = range.getFramework() } + string getFramework() { result = super.getFramework() } } /** Provides a class for modeling new HTTP routing APIs. */ @@ -785,19 +722,15 @@ module HTTP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `RequestHandler::Range` instead. */ - class RequestHandler extends Function { - RequestHandler::Range range; - - RequestHandler() { this = range } - + class RequestHandler extends Function instanceof RequestHandler::Range { /** * Gets a parameter that could receive parts of the url when handling incoming * requests, if any. These automatically become a `RemoteFlowSource`. */ - Parameter getARoutedParameter() { result = range.getARoutedParameter() } + Parameter getARoutedParameter() { result = super.getARoutedParameter() } /** Gets a string that identifies the framework used for this route setup. */ - string getFramework() { result = range.getFramework() } + string getFramework() { result = super.getFramework() } } /** Provides a class for modeling new HTTP request handlers. */ @@ -853,16 +786,12 @@ module HTTP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `HttpResponse::Range` instead. */ - class HttpResponse extends DataFlow::Node { - HttpResponse::Range range; - - HttpResponse() { this = range } - + class HttpResponse extends DataFlow::Node instanceof HttpResponse::Range { /** Gets the data-flow node that specifies the body of this HTTP response. */ - DataFlow::Node getBody() { result = range.getBody() } + DataFlow::Node getBody() { result = super.getBody() } /** Gets the mimetype of this HTTP response, if it can be statically determined. */ - string getMimetype() { result = range.getMimetype() } + string getMimetype() { result = super.getMimetype() } } /** Provides a class for modeling new HTTP response APIs. */ @@ -908,13 +837,9 @@ module HTTP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `HttpRedirectResponse::Range` instead. */ - class HttpRedirectResponse extends HttpResponse { - override HttpRedirectResponse::Range range; - - HttpRedirectResponse() { this = range } - + class HttpRedirectResponse extends HttpResponse instanceof HttpRedirectResponse::Range { /** Gets the data-flow node that specifies the location of this HTTP redirect response. */ - DataFlow::Node getRedirectLocation() { result = range.getRedirectLocation() } + DataFlow::Node getRedirectLocation() { result = super.getRedirectLocation() } } /** Provides a class for modeling new HTTP redirect response APIs. */ @@ -940,25 +865,21 @@ module HTTP { * Extend this class to refine existing API models. If you want to model new APIs, * extend `HTTP::CookieWrite::Range` instead. */ - class CookieWrite extends DataFlow::Node { - CookieWrite::Range range; - - CookieWrite() { this = range } - + class CookieWrite extends DataFlow::Node instanceof CookieWrite::Range { /** * Gets the argument, if any, specifying the raw cookie header. */ - DataFlow::Node getHeaderArg() { result = range.getHeaderArg() } + DataFlow::Node getHeaderArg() { result = super.getHeaderArg() } /** * Gets the argument, if any, specifying the cookie name. */ - DataFlow::Node getNameArg() { result = range.getNameArg() } + DataFlow::Node getNameArg() { result = super.getNameArg() } /** * Gets the argument, if any, specifying the cookie value. */ - DataFlow::Node getValueArg() { result = range.getValueArg() } + DataFlow::Node getValueArg() { result = super.getValueArg() } } /** Provides a class for modeling new cookie writes on HTTP responses. */ @@ -1075,27 +996,23 @@ module Cryptography { * Extend this class to refine existing API models. If you want to model new APIs, * extend `KeyGeneration::Range` instead. */ - class KeyGeneration extends DataFlow::Node { - KeyGeneration::Range range; - - KeyGeneration() { this = range } - + class KeyGeneration extends DataFlow::Node instanceof KeyGeneration::Range { /** Gets the name of the cryptographic algorithm (for example `"RSA"` or `"AES"`). */ - string getName() { result = range.getName() } + string getName() { result = super.getName() } /** Gets the argument that specifies the size of the key in bits, if available. */ - DataFlow::Node getKeySizeArg() { result = range.getKeySizeArg() } + DataFlow::Node getKeySizeArg() { result = super.getKeySizeArg() } /** * Gets the size of the key generated (in bits), as well as the `origin` that * explains how we obtained this specific key size. */ int getKeySizeWithOrigin(DataFlow::Node origin) { - result = range.getKeySizeWithOrigin(origin) + result = super.getKeySizeWithOrigin(origin) } /** Gets the minimum key size (in bits) for this algorithm to be considered secure. */ - int minimumSecureKeySize() { result = range.minimumSecureKeySize() } + int minimumSecureKeySize() { result = super.minimumSecureKeySize() } } /** Provides classes for modeling new key-pair generation APIs. */ @@ -1174,16 +1091,12 @@ module Cryptography { * Extend this class to refine existing API models. If you want to model new APIs, * extend `CryptographicOperation::Range` instead. */ - class CryptographicOperation extends DataFlow::Node { - CryptographicOperation::Range range; - - CryptographicOperation() { this = range } - + class CryptographicOperation extends DataFlow::Node instanceof CryptographicOperation::Range { /** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */ - CryptographicAlgorithm getAlgorithm() { result = range.getAlgorithm() } + CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() } /** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */ - DataFlow::Node getAnInput() { result = range.getAnInput() } + DataFlow::Node getAnInput() { result = super.getAnInput() } } /** Provides classes for modeling new applications of a cryptographic algorithms. */