mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
Python: asCfgNode cleanup
This commit is contained in:
@@ -13,12 +13,12 @@ class PyOpenSSLContextCreation extends ContextCreation, DataFlow::CallCfgNode {
|
||||
}
|
||||
|
||||
override string getProtocol() {
|
||||
exists(ControlFlowNode protocolArg, PyOpenSSL pyo |
|
||||
protocolArg in [node.getArg(0), node.getArgByName("method")]
|
||||
exists(DataFlow::Node protocolArg, PyOpenSSL pyo |
|
||||
protocolArg in [this.getArg(0), this.getArgByName("method")]
|
||||
|
|
||||
protocolArg =
|
||||
[pyo.specific_version(result).getAUse(), pyo.unspecific_version(result).getAUse()]
|
||||
.asCfgNode()
|
||||
protocolArg in [
|
||||
pyo.specific_version(result).getAUse(), pyo.unspecific_version(result).getAUse()
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class ConnectionCall extends ConnectionCreation, DataFlow::CallCfgNode {
|
||||
}
|
||||
|
||||
override DataFlow::CfgNode getContext() {
|
||||
result.getNode() in [node.getArg(0), node.getArgByName("context")]
|
||||
result in [this.getArg(0), this.getArgByName("context")]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ class SetOptionsCall extends ProtocolRestriction, DataFlow::CallCfgNode {
|
||||
}
|
||||
|
||||
override ProtocolVersion getRestriction() {
|
||||
API::moduleImport("OpenSSL").getMember("SSL").getMember("OP_NO_" + result).getAUse().asCfgNode() in [
|
||||
node.getArg(0), node.getArgByName("options")
|
||||
API::moduleImport("OpenSSL").getMember("SSL").getMember("OP_NO_" + result).getAUse() in [
|
||||
this.getArg(0), this.getArgByName("options")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,14 @@ class SSLContextCreation extends ContextCreation, DataFlow::CallCfgNode {
|
||||
SSLContextCreation() { this = API::moduleImport("ssl").getMember("SSLContext").getACall() }
|
||||
|
||||
override string getProtocol() {
|
||||
exists(ControlFlowNode protocolArg, Ssl ssl |
|
||||
protocolArg in [node.getArg(0), node.getArgByName("protocol")]
|
||||
exists(DataFlow::Node protocolArg, Ssl ssl |
|
||||
protocolArg in [this.getArg(0), this.getArgByName("protocol")]
|
||||
|
|
||||
protocolArg =
|
||||
[ssl.specific_version(result).getAUse(), ssl.unspecific_version(result).getAUse()]
|
||||
.asCfgNode()
|
||||
)
|
||||
or
|
||||
not exists(node.getAnArg()) and
|
||||
not exists(this.getArg(_)) and
|
||||
result = "TLS"
|
||||
}
|
||||
}
|
||||
@@ -133,7 +132,7 @@ class ContextSetVersion extends ProtocolRestriction, ProtocolUnrestriction, Data
|
||||
|
||||
ContextSetVersion() {
|
||||
exists(DataFlow::AttrWrite aw |
|
||||
aw.getObject().asCfgNode() = node and
|
||||
this = aw.getObject() and
|
||||
aw.getAttributeName() = "minimum_version" and
|
||||
aw.getValue() =
|
||||
API::moduleImport("ssl").getMember("TLSVersion").getMember(restriction).getAUse()
|
||||
|
||||
@@ -80,6 +80,6 @@ module ClickHouseDriver {
|
||||
private class ExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ExecuteCall() { this.getFunction() = clickhouse_execute() }
|
||||
|
||||
override DataFlow::Node getSql() { result.asCfgNode() = node.getArg(0) }
|
||||
override DataFlow::Node getSql() { result = this.getArg(0) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ private module SensitiveDataModeling {
|
||||
SensitiveDataClassification classification;
|
||||
|
||||
SensitiveGetCall() {
|
||||
this.getFunction().asCfgNode().(AttrNode).getName() = "get" and
|
||||
this.getFunction().(DataFlow::AttrRef).getAttributeName() = "get" and
|
||||
this.getArg(0) = sensitiveLookupStringConst(classification)
|
||||
}
|
||||
|
||||
|
||||
@@ -401,11 +401,11 @@ private module PrivateDjango {
|
||||
* Gets an instance of the `django.db.models.expressions.RawSQL` class,
|
||||
* that was initiated with the SQL represented by `sql`.
|
||||
*/
|
||||
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t, ControlFlowNode sql) {
|
||||
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t, DataFlow::Node sql) {
|
||||
t.start() and
|
||||
exists(DataFlow::CallCfgNode c | result = c |
|
||||
c = classRef().getACall() and
|
||||
c.getArg(0).asCfgNode() = sql
|
||||
c.getArg(0) = sql
|
||||
)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = instance(t2, sql).track(t2, t))
|
||||
@@ -415,7 +415,7 @@ private module PrivateDjango {
|
||||
* Gets an instance of the `django.db.models.expressions.RawSQL` class,
|
||||
* that was initiated with the SQL represented by `sql`.
|
||||
*/
|
||||
DataFlow::Node instance(ControlFlowNode sql) {
|
||||
DataFlow::Node instance(DataFlow::Node sql) {
|
||||
instance(DataFlow::TypeTracker::end(), sql).flowsTo(result)
|
||||
}
|
||||
}
|
||||
@@ -431,7 +431,7 @@ private module PrivateDjango {
|
||||
* See https://docs.djangoproject.com/en/3.1/ref/models/querysets/#annotate
|
||||
*/
|
||||
private class ObjectsAnnotate extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ControlFlowNode sql;
|
||||
DataFlow::Node sql;
|
||||
|
||||
ObjectsAnnotate() {
|
||||
this = django::db::models::querySetReturningMethod("annotate").getACall() and
|
||||
@@ -440,7 +440,7 @@ private module PrivateDjango {
|
||||
]
|
||||
}
|
||||
|
||||
override DataFlow::Node getSql() { result.asCfgNode() = sql }
|
||||
override DataFlow::Node getSql() { result = sql }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,7 +449,7 @@ private module PrivateDjango {
|
||||
* See https://docs.djangoproject.com/en/3.2/ref/models/querysets/#alias
|
||||
*/
|
||||
private class ObjectsAlias extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ControlFlowNode sql;
|
||||
DataFlow::Node sql;
|
||||
|
||||
ObjectsAlias() {
|
||||
this = django::db::models::querySetReturningMethod("alias").getACall() and
|
||||
@@ -458,7 +458,7 @@ private module PrivateDjango {
|
||||
]
|
||||
}
|
||||
|
||||
override DataFlow::Node getSql() { result.asCfgNode() = sql }
|
||||
override DataFlow::Node getSql() { result = sql }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -631,12 +631,12 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
override DataFlow::Node getMimetypeOrContentTypeArg() {
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("content_type")]
|
||||
result in [this.getArg(1), this.getArgByName("content_type")]
|
||||
}
|
||||
|
||||
override string getMimetypeDefault() { result = "text/html" }
|
||||
@@ -695,11 +695,11 @@ private module PrivateDjango {
|
||||
// note that even though browsers like Chrome usually doesn't fetch the
|
||||
// content of a redirect, it is possible to observe the body (for example,
|
||||
// with cURL).
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("content")]
|
||||
result in [this.getArg(1), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getRedirectLocation() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("redirect_to")]
|
||||
result in [this.getArg(0), this.getArgByName("redirect_to")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -757,11 +757,11 @@ private module PrivateDjango {
|
||||
// note that even though browsers like Chrome usually doesn't fetch the
|
||||
// content of a redirect, it is possible to observe the body (for example,
|
||||
// with cURL).
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("content")]
|
||||
result in [this.getArg(1), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getRedirectLocation() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("redirect_to")]
|
||||
result in [this.getArg(0), this.getArgByName("redirect_to")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -868,7 +868,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -922,7 +922,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -976,7 +976,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1031,7 +1031,7 @@ private module PrivateDjango {
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
// First argument is permitted methods
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("content")]
|
||||
result in [this.getArg(1), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1085,7 +1085,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1139,7 +1139,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1193,7 +1193,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("data")]
|
||||
result in [this.getArg(0), this.getArgByName("data")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1250,7 +1250,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("streaming_content")]
|
||||
result in [this.getArg(0), this.getArgByName("streaming_content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1304,7 +1304,7 @@ private module PrivateDjango {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("streaming_content")]
|
||||
result in [this.getArg(0), this.getArgByName("streaming_content")]
|
||||
}
|
||||
|
||||
// How to support the `headers` argument here?
|
||||
@@ -1349,14 +1349,13 @@ private module PrivateDjango {
|
||||
*
|
||||
* See https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpResponse.write
|
||||
*/
|
||||
class HttpResponseWriteCall extends HTTP::Server::HttpResponse::Range, DataFlow::CfgNode {
|
||||
override CallNode node;
|
||||
class HttpResponseWriteCall extends HTTP::Server::HttpResponse::Range, DataFlow::CallCfgNode {
|
||||
HTTP::Server::HttpResponse::Range instance;
|
||||
|
||||
HttpResponseWriteCall() { node.getFunction() = write(instance).asCfgNode() }
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
|
||||
result in [this.getArg(0), this.getArgByName("content")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getMimetypeOrContentTypeArg() {
|
||||
@@ -1639,12 +1638,10 @@ private module PrivateDjango {
|
||||
DjangoUrlsPathCall() { this = django::urls::path().getACall() }
|
||||
|
||||
override DataFlow::Node getUrlPatternArg() {
|
||||
result.asCfgNode() = [node.getArg(0), node.getArgByName("route")]
|
||||
result in [this.getArg(0), this.getArgByName("route")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getViewArg() {
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("view")]
|
||||
}
|
||||
override DataFlow::Node getViewArg() { result in [this.getArg(1), this.getArgByName("view")] }
|
||||
|
||||
override Parameter getARoutedParameter() {
|
||||
// If we don't know the URL pattern, we simply mark all parameters as a routed
|
||||
@@ -1739,12 +1736,10 @@ private module PrivateDjango {
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrlPatternArg() {
|
||||
result.asCfgNode() = [node.getArg(0), node.getArgByName("route")]
|
||||
result in [this.getArg(0), this.getArgByName("route")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getViewArg() {
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("view")]
|
||||
}
|
||||
override DataFlow::Node getViewArg() { result in [this.getArg(1), this.getArgByName("view")] }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1756,12 +1751,10 @@ private module PrivateDjango {
|
||||
DjangoConfUrlsUrlCall() { this = django::conf::conf_urls::url().getACall() }
|
||||
|
||||
override DataFlow::Node getUrlPatternArg() {
|
||||
result.asCfgNode() = [node.getArg(0), node.getArgByName("regex")]
|
||||
result in [this.getArg(0), this.getArgByName("regex")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getViewArg() {
|
||||
result.asCfgNode() in [node.getArg(1), node.getArgByName("view")]
|
||||
}
|
||||
override DataFlow::Node getViewArg() { result in [this.getArg(1), this.getArgByName("view")] }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1872,7 +1865,7 @@ private module PrivateDjango {
|
||||
* a string identifying a view, or a Django model.
|
||||
*/
|
||||
override DataFlow::Node getRedirectLocation() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("to")]
|
||||
result in [this.getArg(0), this.getArgByName("to")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getBody() { none() }
|
||||
|
||||
@@ -48,7 +48,7 @@ private module FabricV1 {
|
||||
FabricApiLocalRunSudoCall() { this = api().getMember(["local", "run", "sudo"]).getACall() }
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() = [node.getArg(0), node.getArgByName("command")]
|
||||
result = [this.getArg(0), this.getArgByName("command")]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ private module FabricV2 {
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() = [node.getArg(0), node.getArgByName("command")]
|
||||
result = [this.getArg(0), this.getArgByName("command")]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ private module FabricV2 {
|
||||
FabricGroupRunCall() { this = fabric::group::Group::subclassInstanceRunMethod().getACall() }
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() = [node.getArg(0), node.getArgByName("command")]
|
||||
result = [this.getArg(0), this.getArgByName("command")]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ private module Invoke {
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("command")]
|
||||
result in [this.getArg(0), this.getArgByName("command")]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,6 @@ private class ExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ExecuteCall() { this.getFunction() = execute() }
|
||||
|
||||
override DataFlow::Node getSql() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("sql")]
|
||||
result in [this.getArg(0), this.getArgByName("sql")]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,7 @@ private module Stdlib {
|
||||
private class OsPathNormpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
|
||||
OsPathNormpathCall() { this = os::path().getMember("normpath").getACall() }
|
||||
|
||||
DataFlow::Node getPathArg() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("path")]
|
||||
}
|
||||
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
|
||||
}
|
||||
|
||||
/** An additional taint step for calls to `os.path.normpath` */
|
||||
@@ -60,9 +58,7 @@ private module Stdlib {
|
||||
private class OsPathAbspathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
|
||||
OsPathAbspathCall() { this = os::path().getMember("abspath").getACall() }
|
||||
|
||||
DataFlow::Node getPathArg() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("path")]
|
||||
}
|
||||
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
|
||||
}
|
||||
|
||||
/** An additional taint step for calls to `os.path.abspath` */
|
||||
@@ -82,9 +78,7 @@ private module Stdlib {
|
||||
private class OsPathRealpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
|
||||
OsPathRealpathCall() { this = os::path().getMember("realpath").getACall() }
|
||||
|
||||
DataFlow::Node getPathArg() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("path")]
|
||||
}
|
||||
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
|
||||
}
|
||||
|
||||
/** An additional taint step for calls to `os.path.realpath` */
|
||||
@@ -104,7 +98,7 @@ private module Stdlib {
|
||||
private class OsSystemCall extends SystemCommandExecution::Range, DataFlow::CallCfgNode {
|
||||
OsSystemCall() { this = os().getMember("system").getACall() }
|
||||
|
||||
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(0) }
|
||||
override DataFlow::Node getCommand() { result = this.getArg(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +118,10 @@ private module Stdlib {
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() = node.getArg(0)
|
||||
result = this.getArg(0)
|
||||
or
|
||||
not name = "popen" and
|
||||
result.asCfgNode() = node.getArgByName("cmd")
|
||||
result = this.getArgByName("cmd")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +137,7 @@ private module Stdlib {
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(0) }
|
||||
override DataFlow::Node getCommand() { result = this.getArg(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +154,7 @@ private module Stdlib {
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(1) }
|
||||
override DataFlow::Node getCommand() { result = this.getArg(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +164,7 @@ private module Stdlib {
|
||||
private class OsPosixSpawnCall extends SystemCommandExecution::Range, DataFlow::CallCfgNode {
|
||||
OsPosixSpawnCall() { this = os().getMember(["posix_spawn", "posix_spawnp"]).getACall() }
|
||||
|
||||
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(0) }
|
||||
override DataFlow::Node getCommand() { result = this.getArg(0) }
|
||||
}
|
||||
|
||||
/** An additional taint step for calls to `os.path.join` */
|
||||
@@ -204,22 +198,22 @@ private module Stdlib {
|
||||
}
|
||||
|
||||
/** Gets the ControlFlowNode for the `args` argument, if any. */
|
||||
private ControlFlowNode get_args_arg() { result in [node.getArg(0), node.getArgByName("args")] }
|
||||
private DataFlow::Node get_args_arg() { result in [this.getArg(0), this.getArgByName("args")] }
|
||||
|
||||
/** Gets the ControlFlowNode for the `shell` argument, if any. */
|
||||
private ControlFlowNode get_shell_arg() {
|
||||
result in [node.getArg(8), node.getArgByName("shell")]
|
||||
private DataFlow::Node get_shell_arg() {
|
||||
result in [this.getArg(8), this.getArgByName("shell")]
|
||||
}
|
||||
|
||||
private boolean get_shell_arg_value() {
|
||||
not exists(this.get_shell_arg()) and
|
||||
result = false
|
||||
or
|
||||
exists(ControlFlowNode shell_arg | shell_arg = this.get_shell_arg() |
|
||||
result = shell_arg.getNode().(ImmutableLiteral).booleanValue()
|
||||
exists(DataFlow::Node shell_arg | shell_arg = this.get_shell_arg() |
|
||||
result = shell_arg.asCfgNode().getNode().(ImmutableLiteral).booleanValue()
|
||||
or
|
||||
// TODO: Track the "shell" argument to determine possible values
|
||||
not shell_arg.getNode() instanceof ImmutableLiteral and
|
||||
not shell_arg.asCfgNode().getNode() instanceof ImmutableLiteral and
|
||||
(
|
||||
result = true
|
||||
or
|
||||
@@ -229,16 +223,16 @@ private module Stdlib {
|
||||
}
|
||||
|
||||
/** Gets the ControlFlowNode for the `executable` argument, if any. */
|
||||
private ControlFlowNode get_executable_arg() {
|
||||
result in [node.getArg(2), node.getArgByName("executable")]
|
||||
private DataFlow::Node get_executable_arg() {
|
||||
result in [this.getArg(2), this.getArgByName("executable")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
// TODO: Track arguments ("args" and "shell")
|
||||
// TODO: Handle using `args=["sh", "-c", <user-input>]`
|
||||
result.asCfgNode() = this.get_executable_arg()
|
||||
result = this.get_executable_arg()
|
||||
or
|
||||
exists(ControlFlowNode arg_args, boolean shell |
|
||||
exists(DataFlow::Node arg_args, boolean shell |
|
||||
arg_args = get_args_arg() and
|
||||
shell = get_shell_arg_value()
|
||||
|
|
||||
@@ -254,14 +248,14 @@ private module Stdlib {
|
||||
// run, so if we're able to, we only mark the first element as the command
|
||||
// (and not the arguments to the command).
|
||||
//
|
||||
result.asCfgNode() = arg_args.(SequenceNode).getElement(0)
|
||||
result.asCfgNode() = arg_args.asCfgNode().(SequenceNode).getElement(0)
|
||||
or
|
||||
// Either the "args" argument is not a sequence (which is valid) or we where
|
||||
// just not able to figure it out. Simply mark the "args" argument as the
|
||||
// command.
|
||||
//
|
||||
not arg_args instanceof SequenceNode and
|
||||
result.asCfgNode() = arg_args
|
||||
not arg_args.asCfgNode() instanceof SequenceNode and
|
||||
result = arg_args
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -334,9 +328,7 @@ private module Stdlib {
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("cmd")]
|
||||
}
|
||||
override DataFlow::Node getCommand() { result in [this.getArg(0), this.getArgByName("cmd")] }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -352,9 +344,7 @@ private module Stdlib {
|
||||
private class PlatformPopenCall extends SystemCommandExecution::Range, DataFlow::CallCfgNode {
|
||||
PlatformPopenCall() { this = platform().getMember("popen").getACall() }
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("cmd")]
|
||||
}
|
||||
override DataFlow::Node getCommand() { result in [this.getArg(0), this.getArgByName("cmd")] }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -442,7 +432,7 @@ private module Stdlib {
|
||||
this = base64().getMember(name).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAnInput() { result.asCfgNode() = node.getArg(0) }
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
||||
|
||||
override DataFlow::Node getOutput() { result = this }
|
||||
|
||||
@@ -476,7 +466,7 @@ private module Stdlib {
|
||||
|
||||
override predicate mayExecuteInput() { none() }
|
||||
|
||||
override DataFlow::Node getAnInput() { result.asCfgNode() = node.getArg(0) }
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
||||
|
||||
override DataFlow::Node getOutput() { result = this }
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@ private module Tornado {
|
||||
}
|
||||
|
||||
override DataFlow::Node getRedirectLocation() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("url")]
|
||||
result in [this.getArg(0), this.getArgByName("url")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getBody() { none() }
|
||||
@@ -452,9 +452,7 @@ private module Tornado {
|
||||
this.getFunction() = tornado::web::RequestHandler::writeMethod()
|
||||
}
|
||||
|
||||
override DataFlow::Node getBody() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("chunk")]
|
||||
}
|
||||
override DataFlow::Node getBody() { result in [this.getArg(0), this.getArgByName("chunk")] }
|
||||
|
||||
override string getMimetypeDefault() { result = "text/html" }
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ module Werkzeug {
|
||||
or
|
||||
// getlist -> getlist()
|
||||
nodeFrom = werkzeug::datastructures::MultiDict::getlist() and
|
||||
nodeTo.asCfgNode().(CallNode).getFunction() = nodeFrom.asCfgNode()
|
||||
nodeTo.(DataFlow::CallCfgNode).getFunction() = nodeFrom
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user