Files
codeql/python/ql/test/experimental/meta/ConceptsTest.qll
Rasmus Wriedt Larsen 85f00fda19 Merge pull request #6776 from yoff/python/model-asyncpg
Python: Model `asyncpg`
2021-10-29 13:54:44 +02:00

478 lines
16 KiB
Plaintext

import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.Concepts
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
class SystemCommandExecutionTest extends InlineExpectationsTest {
SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" }
override string getARelevantTag() { result = "getCommand" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SystemCommandExecution sce, DataFlow::Node command |
command = sce.getCommand() and
location = command.getLocation() and
element = command.toString() and
value = prettyNodeForInlineTest(command) and
tag = "getCommand"
)
}
}
class DecodingTest extends InlineExpectationsTest {
DecodingTest() { this = "DecodingTest" }
override string getARelevantTag() {
result in ["decodeInput", "decodeOutput", "decodeFormat", "decodeMayExecuteInput"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Decoding d |
exists(DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = prettyNodeForInlineTest(data) and
(
data = d.getAnInput() and
tag = "decodeInput"
or
data = d.getOutput() and
tag = "decodeOutput"
)
)
or
exists(string format |
location = d.getLocation() and
element = format and
value = format and
format = d.getFormat() and
tag = "decodeFormat"
)
or
d.mayExecuteInput() and
location = d.getLocation() and
element = d.toString() and
value = "" and
tag = "decodeMayExecuteInput"
)
}
}
class EncodingTest extends InlineExpectationsTest {
EncodingTest() { this = "EncodingTest" }
override string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Encoding e |
exists(DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = prettyNodeForInlineTest(data) and
(
data = e.getAnInput() and
tag = "encodeInput"
or
data = e.getOutput() and
tag = "encodeOutput"
)
)
or
exists(string format |
location = e.getLocation() and
element = format and
value = format and
format = e.getFormat() and
tag = "encodeFormat"
)
)
}
}
class LoggingTest extends InlineExpectationsTest {
LoggingTest() { this = "LoggingTest" }
override string getARelevantTag() { result = "loggingInput" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Logging logging, DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = prettyNodeForInlineTest(data) and
data = logging.getAnInput() and
tag = "loggingInput"
)
}
}
class CodeExecutionTest extends InlineExpectationsTest {
CodeExecutionTest() { this = "CodeExecutionTest" }
override string getARelevantTag() { result = "getCode" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CodeExecution ce, DataFlow::Node code |
exists(location.getFile().getRelativePath()) and
code = ce.getCode() and
location = code.getLocation() and
element = code.toString() and
value = prettyNodeForInlineTest(code) and
tag = "getCode"
)
}
}
class SqlConstructionTest extends InlineExpectationsTest {
SqlConstructionTest() { this = "SqlConstructionTest" }
override string getARelevantTag() { result = "constructedSql" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SqlConstruction e, DataFlow::Node sql |
exists(location.getFile().getRelativePath()) and
sql = e.getSql() and
location = e.getLocation() and
element = sql.toString() and
value = prettyNodeForInlineTest(sql) and
tag = "constructedSql"
)
}
}
class SqlExecutionTest extends InlineExpectationsTest {
SqlExecutionTest() { this = "SqlExecutionTest" }
override string getARelevantTag() { result = "getSql" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SqlExecution e, DataFlow::Node sql |
exists(location.getFile().getRelativePath()) and
sql = e.getSql() and
location = e.getLocation() and
element = sql.toString() and
value = prettyNodeForInlineTest(sql) and
tag = "getSql"
)
}
}
class EscapingTest extends InlineExpectationsTest {
EscapingTest() { this = "EscapingTest" }
override string getARelevantTag() { result in ["escapeInput", "escapeOutput", "escapeKind"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Escaping esc |
exists(DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = prettyNodeForInlineTest(data) and
(
data = esc.getAnInput() and
tag = "escapeInput"
or
data = esc.getOutput() and
tag = "escapeOutput"
)
)
or
exists(string format |
location = esc.getLocation() and
element = format and
value = format and
format = esc.getKind() and
tag = "escapeKind"
)
)
}
}
class HttpServerRouteSetupTest extends InlineExpectationsTest {
HttpServerRouteSetupTest() { this = "HttpServerRouteSetupTest" }
override string getARelevantTag() { result = "routeSetup" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(HTTP::Server::RouteSetup setup |
location = setup.getLocation() and
element = setup.toString() and
(
value = "\"" + setup.getUrlPattern() + "\""
or
not exists(setup.getUrlPattern()) and
value = ""
) and
tag = "routeSetup"
)
}
}
class HttpServerRequestHandlerTest extends InlineExpectationsTest {
HttpServerRequestHandlerTest() { this = "HttpServerRequestHandlerTest" }
override string getARelevantTag() { result in ["requestHandler", "routedParameter"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
(
exists(HTTP::Server::RequestHandler handler |
location = handler.getLocation() and
element = handler.toString() and
value = "" and
tag = "requestHandler"
)
or
exists(HTTP::Server::RequestHandler handler, Parameter param |
param = handler.getARoutedParameter() and
location = param.getLocation() and
element = param.toString() and
value = param.asName().getId() and
tag = "routedParameter"
)
)
}
}
class HttpServerHttpResponseTest extends InlineExpectationsTest {
File file;
HttpServerHttpResponseTest() {
file.getExtension() = "py" and
this = "HttpServerHttpResponseTest: " + file
}
override string getARelevantTag() { result in ["HttpResponse", "responseBody", "mimetype"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
// By adding `file` as a class field, and these two restrictions, it's possible to
// say that we only want to check _some_ tags for certain files. This helped make
// flask tests more readable since adding full annotations for HttpResponses in the
// the tests for routing setup is both annoying and not very useful.
location.getFile() = file and
exists(file.getRelativePath()) and
// we need to do this step since we expect subclasses could override getARelevantTag
tag = getARelevantTag() and
(
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = "" and
tag = "HttpResponse"
)
or
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = prettyNodeForInlineTest(response.getBody()) and
tag = "responseBody"
)
or
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
// Ensure that an expectation value such as "mimetype=text/html; charset=utf-8" is parsed as a
// single expectation with tag mimetype, and not as two expecations with tags mimetype and
// charset.
(
if exists(response.getMimetype().indexOf(" "))
then value = "\"" + response.getMimetype() + "\""
else value = response.getMimetype()
) and
tag = "mimetype"
)
)
}
}
class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest {
HttpServerHttpRedirectResponseTest() { this = "HttpServerHttpRedirectResponseTest" }
override string getARelevantTag() { result in ["HttpRedirectResponse", "redirectLocation"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
(
exists(HTTP::Server::HttpRedirectResponse redirect |
location = redirect.getLocation() and
element = redirect.toString() and
value = "" and
tag = "HttpRedirectResponse"
)
or
exists(HTTP::Server::HttpRedirectResponse redirect |
location = redirect.getLocation() and
element = redirect.toString() and
value = prettyNodeForInlineTest(redirect.getRedirectLocation()) and
tag = "redirectLocation"
)
)
}
}
class HttpServerCookieWriteTest extends InlineExpectationsTest {
HttpServerCookieWriteTest() { this = "HttpServerCookieWriteTest" }
override string getARelevantTag() {
result in ["CookieWrite", "CookieRawHeader", "CookieName", "CookieValue"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(HTTP::Server::CookieWrite cookieWrite |
location = cookieWrite.getLocation() and
(
element = cookieWrite.toString() and
value = "" and
tag = "CookieWrite"
or
element = cookieWrite.toString() and
value = prettyNodeForInlineTest(cookieWrite.getHeaderArg()) and
tag = "CookieRawHeader"
or
element = cookieWrite.toString() and
value = prettyNodeForInlineTest(cookieWrite.getNameArg()) and
tag = "CookieName"
or
element = cookieWrite.toString() and
value = prettyNodeForInlineTest(cookieWrite.getValueArg()) and
tag = "CookieValue"
)
)
}
}
class FileSystemAccessTest extends InlineExpectationsTest {
FileSystemAccessTest() { this = "FileSystemAccessTest" }
override string getARelevantTag() { result = "getAPathArgument" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(FileSystemAccess a, DataFlow::Node path |
path = a.getAPathArgument() and
location = a.getLocation() and
element = path.toString() and
value = prettyNodeForInlineTest(path) and
tag = "getAPathArgument"
)
}
}
class FileSystemWriteAccessTest extends InlineExpectationsTest {
FileSystemWriteAccessTest() { this = "FileSystemWriteAccessTest" }
override string getARelevantTag() { result = "fileWriteData" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(FileSystemWriteAccess write, DataFlow::Node data |
data = write.getADataNode() and
location = data.getLocation() and
element = data.toString() and
value = prettyNodeForInlineTest(data) and
tag = "fileWriteData"
)
}
}
class PathNormalizationTest extends InlineExpectationsTest {
PathNormalizationTest() { this = "PathNormalizationTest" }
override string getARelevantTag() { result = "pathNormalization" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Path::PathNormalization n |
location = n.getLocation() and
element = n.toString() and
value = "" and
tag = "pathNormalization"
)
}
}
class SafeAccessCheckTest extends InlineExpectationsTest {
SafeAccessCheckTest() { this = "SafeAccessCheckTest" }
override string getARelevantTag() { result in ["checks", "branch"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Path::SafeAccessCheck c, DataFlow::Node checks, boolean branch |
c.checks(checks.asCfgNode(), branch) and
location = c.getLocation() and
(
element = checks.toString() and
value = prettyNodeForInlineTest(checks) and
tag = "checks"
or
element = branch.toString() and
value = branch.toString() and
tag = "branch"
)
)
}
}
class PublicKeyGenerationTest extends InlineExpectationsTest {
PublicKeyGenerationTest() { this = "PublicKeyGenerationTest" }
override string getARelevantTag() { result in ["PublicKeyGeneration", "keySize"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Cryptography::PublicKey::KeyGeneration keyGen |
location = keyGen.getLocation() and
(
element = keyGen.toString() and
value = "" and
tag = "PublicKeyGeneration"
or
element = keyGen.toString() and
value = keyGen.getKeySizeWithOrigin(_).toString() and
tag = "keySize"
)
)
}
}
class CryptographicOperationTest extends InlineExpectationsTest {
CryptographicOperationTest() { this = "CryptographicOperationTest" }
override string getARelevantTag() {
result in [
"CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm"
]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Cryptography::CryptographicOperation cryptoOperation |
location = cryptoOperation.getLocation() and
(
element = cryptoOperation.toString() and
value = "" and
tag = "CryptographicOperation"
or
element = cryptoOperation.toString() and
value = prettyNodeForInlineTest(cryptoOperation.getAnInput()) and
tag = "CryptographicOperationInput"
or
element = cryptoOperation.toString() and
value = cryptoOperation.getAlgorithm().getName() and
tag = "CryptographicOperationAlgorithm"
)
)
}
}