patch upper-case acronyms to be PascalCase

This commit is contained in:
Erik Krogh Kristensen
2022-03-11 11:10:33 +01:00
parent e3a15792fa
commit 69353bb014
422 changed files with 3532 additions and 2244 deletions

View File

@@ -40,13 +40,16 @@ private import semmle.python.objects.ObjectInternal
/**
* A callable that is considered a "safe" external API from a security perspective.
*/
class SafeExternalAPI extends Unit {
class SafeExternalApi extends Unit {
/** Gets a callable that is considered a "safe" external API from a security perspective. */
abstract DataFlowPrivate::DataFlowCallable getSafeCallable();
}
/** DEPRECATED: Alias for SafeExternalApi */
deprecated class SafeExternalAPI = SafeExternalApi;
/** The default set of "safe" external APIs. */
private class DefaultSafeExternalAPI extends SafeExternalAPI {
private class DefaultSafeExternalApi extends SafeExternalApi {
override DataFlowPrivate::DataFlowCallable getSafeCallable() {
exists(CallableValue cv | cv = result.getCallableValue() |
cv = Value::named(["len", "isinstance", "getattr", "hasattr"])
@@ -61,15 +64,15 @@ private class DefaultSafeExternalAPI extends SafeExternalAPI {
}
/** A node representing data being passed to an external API through a call. */
class ExternalAPIDataNode extends DataFlow::Node {
class ExternalApiDataNode extends DataFlow::Node {
DataFlowPrivate::DataFlowCall call;
DataFlowPrivate::DataFlowCallable callable;
int i;
ExternalAPIDataNode() {
ExternalApiDataNode() {
exists(call.getLocation().getFile().getRelativePath()) and
callable = call.getCallable() and
not any(SafeExternalAPI safe).getSafeCallable() = callable and
not any(SafeExternalApi safe).getSafeCallable() = callable and
exists(Value cv | cv = callable.getCallableValue() |
cv.isAbsent()
or
@@ -98,38 +101,47 @@ class ExternalAPIDataNode extends DataFlow::Node {
DataFlowPrivate::DataFlowCallable getCallable() { result = callable }
}
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */
class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration {
UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" }
/** DEPRECATED: Alias for ExternalApiDataNode */
deprecated class ExternalAPIDataNode = ExternalApiDataNode;
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode }
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
}
/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */
deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig;
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalAPIDataNode extends ExternalAPIDataNode {
UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) }
class UntrustedExternalApiDataNode extends ExternalApiDataNode {
UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, this) }
/** Gets a source of untrusted data which is passed to this external API data node. */
DataFlow::Node getAnUntrustedSource() {
any(UntrustedDataToExternalAPIConfig c).hasFlow(result, this)
any(UntrustedDataToExternalApiConfig c).hasFlow(result, this)
}
}
private newtype TExternalAPI =
TExternalAPIParameter(DataFlowPrivate::DataFlowCallable callable, int index) {
exists(UntrustedExternalAPIDataNode n |
/** DEPRECATED: Alias for UntrustedExternalApiDataNode */
deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
private newtype TExternalApi =
TExternalApiParameter(DataFlowPrivate::DataFlowCallable callable, int index) {
exists(UntrustedExternalApiDataNode n |
callable = n.getCallable() and
index = n.getIndex()
)
}
/** An external API which is used with untrusted data. */
class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
class ExternalApiUsedWithUntrustedData extends TExternalApi {
/** Gets a possibly untrusted use of this external API. */
UntrustedExternalAPIDataNode getUntrustedDataNode() {
this = TExternalAPIParameter(result.getCallable(), result.getIndex())
UntrustedExternalApiDataNode getUntrustedDataNode() {
this = TExternalApiParameter(result.getCallable(), result.getIndex())
}
/** Gets the number of untrusted sources used with this external API. */
@@ -143,7 +155,7 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
DataFlowPrivate::DataFlowCallable callable, int index, string callableString,
string indexString
|
this = TExternalAPIParameter(callable, index) and
this = TExternalApiParameter(callable, index) and
indexString = "param " + index and
exists(CallableValue cv | cv = callable.getCallableValue() |
callableString =
@@ -167,6 +179,9 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
}
}
/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */
deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData;
/** Gets the fully qualified name for the `BuiltinFunctionValue` bfv. */
private string pretty_builtin_function_value(BuiltinFunctionValue bfv) {
exists(Builtin b | b = bfv.(BuiltinFunctionObjectInternal).getBuiltin() |

View File

@@ -11,7 +11,7 @@
import python
import ExternalAPIs
from ExternalAPIUsedWithUntrustedData externalAPI
select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses,
externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
from ExternalApiUsedWithUntrustedData externalApi
select externalApi, count(externalApi.getUntrustedDataNode()) as numberOfUses,
externalApi.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
numberOfUntrustedSources desc

View File

@@ -14,11 +14,11 @@ import ExternalAPIs
import DataFlow::PathGraph
from
UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink,
ExternalAPIUsedWithUntrustedData externalAPI
UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink,
ExternalApiUsedWithUntrustedData externalApi
where
sink.getNode() = externalAPI.getUntrustedDataNode() and
sink.getNode() = externalApi.getUntrustedDataNode() and
config.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"Call to " + externalAPI.toString() + " with untrusted data from $@.", source.getNode(),
"Call to " + externalApi.toString() + " with untrusted data from $@.", source.getNode(),
source.toString()

View File

@@ -17,7 +17,7 @@ import python
import semmle.python.security.dataflow.ReflectedXSS
import DataFlow::PathGraph
from ReflectedXSS::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
from ReflectedXss::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
source.getNode(), "a user-provided value"

View File

@@ -16,6 +16,6 @@
import semmle.python.security.BadTagFilterQuery
from HTMLMatchingRegExp regexp, string msg
from HtmlMatchingRegExp regexp, string msg
where msg = min(string m | isBadRegexpFilter(regexp, m) | m order by m.length(), m) // there might be multiple, we arbitrarily pick the shortest one
select regexp, msg

View File

@@ -13,7 +13,7 @@ import python
import experimental.semmle.python.Concepts
import semmle.python.dataflow.new.DataFlow
predicate authenticatesImproperly(LDAPBind ldapBind) {
predicate authenticatesImproperly(LdapBind ldapBind) {
(
DataFlow::localFlow(DataFlow::exprNode(any(None noneName)), ldapBind.getPassword()) or
not exists(ldapBind.getPassword())
@@ -25,6 +25,6 @@ predicate authenticatesImproperly(LDAPBind ldapBind) {
)
}
from LDAPBind ldapBind
from LdapBind ldapBind
where authenticatesImproperly(ldapBind)
select ldapBind, "The following LDAP bind operation is executed without authentication"

View File

@@ -12,7 +12,7 @@ import python
import experimental.semmle.python.Concepts
import experimental.semmle.python.frameworks.JWT
from JWTEncoding jwtEncoding, string affectedComponent
from JwtEncoding jwtEncoding, string affectedComponent
where
affectedComponent = "algorithm" and
isEmptyOrNone(jwtEncoding.getAlgorithm())

View File

@@ -12,6 +12,6 @@
import python
import experimental.semmle.python.Concepts
from JWTDecoding jwtDecoding
from JwtDecoding jwtDecoding
where not jwtDecoding.verifiesSignature()
select jwtDecoding.getPayload(), "is not verified with a cryptographic secret or public key."

View File

@@ -14,7 +14,7 @@ import python
import DataFlow::PathGraph
import experimental.semmle.python.security.LDAPInsecureAuth
from LDAPInsecureAuthConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
from LdapInsecureAuthConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ is authenticated insecurely.", sink.getNode(),
"This LDAP host"

View File

@@ -13,7 +13,7 @@ import python
import experimental.semmle.python.security.injection.NoSQLInjection
import DataFlow::PathGraph
from NoSQLInjection::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
from NoSqlInjection::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink, "$@ NoSQL query contains an unsanitized $@", sink, "This", source,
"user-provided value"

View File

@@ -15,7 +15,7 @@ private import semmle.python.dataflow.new.TaintTracking
private import experimental.semmle.python.Frameworks
/** Provides classes for modeling LDAP query execution-related APIs. */
module LDAPQuery {
module LdapQuery {
/**
* A data-flow node that collects methods executing a LDAP query.
*
@@ -30,16 +30,19 @@ module LDAPQuery {
}
}
/** DEPRECATED: Alias for LdapQuery */
deprecated module LDAPQuery = LdapQuery;
/**
* A data-flow node that collect methods executing a LDAP query.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `LDAPQuery::Range` instead.
*/
class LDAPQuery extends DataFlow::Node {
LDAPQuery::Range range;
class LdapQuery extends DataFlow::Node {
LdapQuery::Range range;
LDAPQuery() { this = range }
LdapQuery() { this = range }
/**
* Gets the argument containing the executed expression.
@@ -47,8 +50,11 @@ class LDAPQuery extends DataFlow::Node {
DataFlow::Node getQuery() { result = range.getQuery() }
}
/** DEPRECATED: Alias for LdapQuery */
deprecated class LDAPQuery = LdapQuery;
/** Provides classes for modeling LDAP components escape-related APIs. */
module LDAPEscape {
module LdapEscape {
/**
* A data-flow node that collects functions escaping LDAP components.
*
@@ -63,16 +69,19 @@ module LDAPEscape {
}
}
/** DEPRECATED: Alias for LdapEscape */
deprecated module LDAPEscape = LdapEscape;
/**
* A data-flow node that collects functions escaping LDAP components.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `LDAPEscape::Range` instead.
*/
class LDAPEscape extends DataFlow::Node {
LDAPEscape::Range range;
class LdapEscape extends DataFlow::Node {
LdapEscape::Range range;
LDAPEscape() { this = range }
LdapEscape() { this = range }
/**
* Gets the argument containing the escaped expression.
@@ -80,8 +89,11 @@ class LDAPEscape extends DataFlow::Node {
DataFlow::Node getAnInput() { result = range.getAnInput() }
}
/** DEPRECATED: Alias for LdapEscape */
deprecated class LDAPEscape = LdapEscape;
/** Provides classes for modeling LDAP bind-related APIs. */
module LDAPBind {
module LdapBind {
/**
* A data-flow node that collects methods binding a LDAP connection.
*
@@ -106,16 +118,19 @@ module LDAPBind {
}
}
/** DEPRECATED: Alias for LdapBind */
deprecated module LDAPBind = LdapBind;
/**
* A data-flow node that collects methods binding a LDAP connection.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `LDAPBind::Range` instead.
*/
class LDAPBind extends DataFlow::Node {
LDAPBind::Range range;
class LdapBind extends DataFlow::Node {
LdapBind::Range range;
LDAPBind() { this = range }
LdapBind() { this = range }
/**
* Gets the argument containing the binding host.
@@ -133,8 +148,11 @@ class LDAPBind extends DataFlow::Node {
predicate useSSL() { range.useSSL() }
}
/** DEPRECATED: Alias for LdapBind */
deprecated class LDAPBind = LdapBind;
/** Provides classes for modeling SQL sanitization libraries. */
module SQLEscape {
module SqlEscape {
/**
* A data-flow node that collects functions that escape SQL statements.
*
@@ -149,16 +167,19 @@ module SQLEscape {
}
}
/** DEPRECATED: Alias for SqlEscape */
deprecated module SQLEscape = SqlEscape;
/**
* A data-flow node that collects functions escaping SQL statements.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `SQLEscape::Range` instead.
*/
class SQLEscape extends DataFlow::Node {
SQLEscape::Range range;
class SqlEscape extends DataFlow::Node {
SqlEscape::Range range;
SQLEscape() { this = range }
SqlEscape() { this = range }
/**
* Gets the argument containing the raw SQL statement.
@@ -166,8 +187,11 @@ class SQLEscape extends DataFlow::Node {
DataFlow::Node getAnInput() { result = range.getAnInput() }
}
/** Provides a class for modeling NoSQL execution APIs. */
module NoSQLQuery {
/** DEPRECATED: Alias for SqlEscape */
deprecated class SQLEscape = SqlEscape;
/** Provides a class for modeling NoSql execution APIs. */
module NoSqlQuery {
/**
* A data-flow node that executes NoSQL queries.
*
@@ -175,28 +199,34 @@ module NoSQLQuery {
* extend `NoSQLQuery` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the argument that specifies the NoSQL query to be executed. */
/** Gets the argument that specifies the NoSql query to be executed. */
abstract DataFlow::Node getQuery();
}
}
/** DEPRECATED: Alias for NoSqlQuery */
deprecated module NoSQLQuery = NoSqlQuery;
/**
* A data-flow node that executes NoSQL queries.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `NoSQLQuery::Range` instead.
*/
class NoSQLQuery extends DataFlow::Node {
NoSQLQuery::Range range;
class NoSqlQuery extends DataFlow::Node {
NoSqlQuery::Range range;
NoSQLQuery() { this = range }
NoSqlQuery() { this = range }
/** Gets the argument that specifies the NoSQL query to be executed. */
/** Gets the argument that specifies the NoSql query to be executed. */
DataFlow::Node getQuery() { result = range.getQuery() }
}
/** Provides classes for modeling NoSQL sanitization-related APIs. */
module NoSQLSanitizer {
/** DEPRECATED: Alias for NoSqlQuery */
deprecated class NoSQLQuery = NoSqlQuery;
/** Provides classes for modeling NoSql sanitization-related APIs. */
module NoSqlSanitizer {
/**
* A data-flow node that collects functions sanitizing NoSQL queries.
*
@@ -204,26 +234,32 @@ module NoSQLSanitizer {
* extend `NoSQLSanitizer` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the argument that specifies the NoSQL query to be sanitized. */
/** Gets the argument that specifies the NoSql query to be sanitized. */
abstract DataFlow::Node getAnInput();
}
}
/** DEPRECATED: Alias for NoSqlSanitizer */
deprecated module NoSQLSanitizer = NoSqlSanitizer;
/**
* A data-flow node that collects functions sanitizing NoSQL queries.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `NoSQLSanitizer::Range` instead.
*/
class NoSQLSanitizer extends DataFlow::Node {
NoSQLSanitizer::Range range;
class NoSqlSanitizer extends DataFlow::Node {
NoSqlSanitizer::Range range;
NoSQLSanitizer() { this = range }
NoSqlSanitizer() { this = range }
/** Gets the argument that specifies the NoSQL query to be sanitized. */
/** Gets the argument that specifies the NoSql query to be sanitized. */
DataFlow::Node getAnInput() { result = range.getAnInput() }
}
/** DEPRECATED: Alias for NoSqlSanitizer */
deprecated class NoSQLSanitizer = NoSqlSanitizer;
/** Provides classes for modeling HTTP Header APIs. */
module HeaderDeclaration {
/**
@@ -268,7 +304,7 @@ class HeaderDeclaration extends DataFlow::Node {
}
/** Provides classes for modeling JWT encoding-related APIs. */
module JWTEncoding {
module JwtEncoding {
/**
* A data-flow node that collects methods encoding a JWT token.
*
@@ -298,13 +334,16 @@ module JWTEncoding {
}
}
/** DEPRECATED: Alias for JwtEncoding */
deprecated module JWTEncoding = JwtEncoding;
/**
* A data-flow node that collects methods encoding a JWT token.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `JWTEncoding::Range` instead.
*/
class JWTEncoding extends DataFlow::Node instanceof JWTEncoding::Range {
class JwtEncoding extends DataFlow::Node instanceof JwtEncoding::Range {
/**
* Gets the argument containing the payload.
*/
@@ -326,8 +365,11 @@ class JWTEncoding extends DataFlow::Node instanceof JWTEncoding::Range {
string getAlgorithmString() { result = super.getAlgorithmString() }
}
/** DEPRECATED: Alias for JwtEncoding */
deprecated class JWTEncoding = JwtEncoding;
/** Provides classes for modeling JWT decoding-related APIs. */
module JWTDecoding {
module JwtDecoding {
/**
* A data-flow node that collects methods decoding a JWT token.
*
@@ -367,13 +409,16 @@ module JWTDecoding {
}
}
/** DEPRECATED: Alias for JwtDecoding */
deprecated module JWTDecoding = JwtDecoding;
/**
* A data-flow node that collects methods encoding a JWT token.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `JWTDecoding::Range` instead.
*/
class JWTDecoding extends DataFlow::Node instanceof JWTDecoding::Range {
class JwtDecoding extends DataFlow::Node instanceof JwtDecoding::Range {
/**
* Gets the argument containing the payload.
*/
@@ -404,3 +449,6 @@ class JWTDecoding extends DataFlow::Node instanceof JWTDecoding::Range {
*/
predicate verifiesSignature() { super.verifiesSignature() }
}
/** DEPRECATED: Alias for JwtDecoding */
deprecated class JWTDecoding = JwtDecoding;

View File

@@ -60,7 +60,7 @@ private module LDAP {
*
* See `LDAP2QueryMethods`
*/
private class LDAP2Query extends DataFlow::CallCfgNode, LDAPQuery::Range {
private class LDAP2Query extends DataFlow::CallCfgNode, LdapQuery::Range {
LDAP2Query() { this.getFunction() = ldapQuery() }
override DataFlow::Node getQuery() {
@@ -98,7 +98,7 @@ private module LDAP {
*
* See `LDAP2BindMethods`
*/
private class LDAP2Bind extends DataFlow::CallCfgNode, LDAPBind::Range {
private class LDAP2Bind extends DataFlow::CallCfgNode, LdapBind::Range {
LDAP2Bind() { this.getFunction() = ldapBind() }
override DataFlow::Node getPassword() {
@@ -149,7 +149,7 @@ private module LDAP {
*
* See https://github.com/python-ldap/python-ldap/blob/7ce471e238cdd9a4dd8d17baccd1c9e05e6f894a/Lib/ldap/dn.py#L17
*/
private class LDAP2EscapeDNCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
private class LDAP2EscapeDNCall extends DataFlow::CallCfgNode, LdapEscape::Range {
LDAP2EscapeDNCall() { this = ldap().getMember("dn").getMember("escape_dn_chars").getACall() }
override DataFlow::Node getAnInput() { result = this.getArg(0) }
@@ -160,7 +160,7 @@ private module LDAP {
*
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap-filter.html#ldap.filter.escape_filter_chars
*/
private class LDAP2EscapeFilterCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
private class LDAP2EscapeFilterCall extends DataFlow::CallCfgNode, LdapEscape::Range {
LDAP2EscapeFilterCall() {
this = ldap().getMember("filter").getMember("escape_filter_chars").getACall()
}
@@ -190,7 +190,7 @@ private module LDAP {
/**
* A class to find `ldap3` methods executing a query.
*/
private class LDAP3Query extends DataFlow::CallCfgNode, LDAPQuery::Range {
private class LDAP3Query extends DataFlow::CallCfgNode, LdapQuery::Range {
LDAP3Query() {
this.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() =
ldap3Connection().getACall() and
@@ -203,7 +203,7 @@ private module LDAP {
/**
* A class to find `ldap3` methods binding a connection.
*/
class LDAP3Bind extends DataFlow::CallCfgNode, LDAPBind::Range {
class LDAP3Bind extends DataFlow::CallCfgNode, LdapBind::Range {
LDAP3Bind() { this = ldap3Connection().getACall() }
override DataFlow::Node getPassword() {
@@ -241,7 +241,7 @@ private module LDAP {
*
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/dn.py#L390
*/
private class LDAP3EscapeDNCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
private class LDAP3EscapeDNCall extends DataFlow::CallCfgNode, LdapEscape::Range {
LDAP3EscapeDNCall() { this = ldap3Utils().getMember("dn").getMember("escape_rdn").getACall() }
override DataFlow::Node getAnInput() { result = this.getArg(0) }
@@ -252,7 +252,7 @@ private module LDAP {
*
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/conv.py#L91
*/
private class LDAP3EscapeFilterCall extends DataFlow::CallCfgNode, LDAPEscape::Range {
private class LDAP3EscapeFilterCall extends DataFlow::CallCfgNode, LdapEscape::Range {
LDAP3EscapeFilterCall() {
this = ldap3Utils().getMember("conv").getMember("escape_filter_chars").getACall()
}

View File

@@ -10,7 +10,7 @@ private import semmle.python.dataflow.new.RemoteFlowSources
private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
private module NoSQL {
private module NoSql {
// API Nodes returning `Mongo` instances.
/** Gets a reference to `pymongo.MongoClient` */
private API::Node pyMongo() {
@@ -153,7 +153,7 @@ private module NoSQL {
*
* `mongo.db.user.find({'name': safe_search})` would be a collection method call, and so the result.
*/
private class MongoCollectionCall extends DataFlow::CallCfgNode, NoSQLQuery::Range {
private class MongoCollectionCall extends DataFlow::CallCfgNode, NoSqlQuery::Range {
MongoCollectionCall() { this.getFunction() = mongoCollectionMethod() }
override DataFlow::Node getQuery() { result = this.getArg(0) }
@@ -174,7 +174,7 @@ private module NoSQL {
*
* `Movie.objects(__raw__=json_search)` would be the result.
*/
private class MongoEngineObjectsCall extends DataFlow::CallCfgNode, NoSQLQuery::Range {
private class MongoEngineObjectsCall extends DataFlow::CallCfgNode, NoSqlQuery::Range {
MongoEngineObjectsCall() {
this =
[mongoEngine(), flask_MongoEngine()]
@@ -188,7 +188,7 @@ private module NoSQL {
}
/** Gets a reference to `mongosanitizer.sanitizer.sanitize` */
private class MongoSanitizerCall extends DataFlow::CallCfgNode, NoSQLSanitizer::Range {
private class MongoSanitizerCall extends DataFlow::CallCfgNode, NoSqlSanitizer::Range {
MongoSanitizerCall() {
this =
API::moduleImport("mongosanitizer").getMember("sanitizer").getMember("sanitize").getACall()
@@ -202,7 +202,7 @@ private module NoSQL {
* If at any time ObjectId can't parse it's input (like when a tainted dict in passed in),
* then ObjectId will throw an error preventing the query from running.
*/
private class BsonObjectIdCall extends DataFlow::CallCfgNode, NoSQLSanitizer::Range {
private class BsonObjectIdCall extends DataFlow::CallCfgNode, NoSqlSanitizer::Range {
BsonObjectIdCall() {
this =
API::moduleImport(["bson", "bson.objectid", "bson.json_util"])

View File

@@ -5,7 +5,7 @@ private import experimental.semmle.python.frameworks.JWT
private module Authlib {
/** Gets a reference to `authlib.jose.(jwt|JsonWebToken)` */
private API::Node authlibJWT() {
private API::Node authlibJwt() {
result in [
API::moduleImport("authlib").getMember("jose").getMember("jwt"),
API::moduleImport("authlib").getMember("jose").getMember("JsonWebToken").getReturn()
@@ -13,10 +13,10 @@ private module Authlib {
}
/** Gets a reference to `jwt.encode` */
private API::Node authlibJWTEncode() { result = authlibJWT().getMember("encode") }
private API::Node authlibJwtEncode() { result = authlibJwt().getMember("encode") }
/** Gets a reference to `jwt.decode` */
private API::Node authlibJWTDecode() { result = authlibJWT().getMember("decode") }
private API::Node authlibJwtDecode() { result = authlibJwt().getMember("decode") }
/**
* Gets a call to `authlib.jose.(jwt|JsonWebToken).encode`.
@@ -33,8 +33,8 @@ private module Authlib {
* * `getAlgorithm()`'s result would be `"HS256"`.
* * `getAlgorithmstring()`'s result would be `HS256`.
*/
private class AuthlibJWTEncodeCall extends DataFlow::CallCfgNode, JWTEncoding::Range {
AuthlibJWTEncodeCall() { this = authlibJWTEncode().getACall() }
private class AuthlibJwtEncodeCall extends DataFlow::CallCfgNode, JwtEncoding::Range {
AuthlibJwtEncodeCall() { this = authlibJwtEncode().getACall() }
override DataFlow::Node getPayload() { result = this.getArg(1) }
@@ -69,8 +69,8 @@ private module Authlib {
* * `getPayload()`'s result would be `token`.
* * `getKey()`'s result would be `key`.
*/
private class AuthlibJWTDecodeCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
AuthlibJWTDecodeCall() { this = authlibJWTDecode().getACall() }
private class AuthlibJwtDecodeCall extends DataFlow::CallCfgNode, JwtDecoding::Range {
AuthlibJwtDecodeCall() { this = authlibJwtDecode().getACall() }
override DataFlow::Node getPayload() { result = this.getArg(0) }

View File

@@ -3,7 +3,7 @@ private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
private import experimental.semmle.python.frameworks.JWT
private module PyJWT {
private module PyJwt {
/** Gets a reference to `jwt.encode` */
private API::Node pyjwtEncode() { result = API::moduleImport("jwt").getMember("encode") }
@@ -25,8 +25,8 @@ private module PyJWT {
* * `getAlgorithm()`'s result would be `"HS256"`.
* * `getAlgorithmstring()`'s result would be `HS256`.
*/
private class PyJWTEncodeCall extends DataFlow::CallCfgNode, JWTEncoding::Range {
PyJWTEncodeCall() { this = pyjwtEncode().getACall() }
private class PyJwtEncodeCall extends DataFlow::CallCfgNode, JwtEncoding::Range {
PyJwtEncodeCall() { this = pyjwtEncode().getACall() }
override DataFlow::Node getPayload() {
result in [this.getArg(0), this.getArgByName("payload")]
@@ -63,8 +63,8 @@ private module PyJWT {
* * `getOptions()`'s result would be `{"verify_signature": True}`.
* * `verifiesSignature()` predicate would succeed.
*/
private class PyJWTDecodeCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
PyJWTDecodeCall() { this = pyjwtDecode().getACall() }
private class PyJwtDecodeCall extends DataFlow::CallCfgNode, JwtDecoding::Range {
PyJwtDecodeCall() { this = pyjwtDecode().getACall() }
override DataFlow::Node getPayload() { result in [this.getArg(0), this.getArgByName("jwt")] }

View File

@@ -5,13 +5,13 @@ private import experimental.semmle.python.frameworks.JWT
private module PythonJose {
/** Gets a reference to `jwt` */
private API::Node joseJWT() { result = API::moduleImport("jose").getMember("jwt") }
private API::Node joseJwt() { result = API::moduleImport("jose").getMember("jwt") }
/** Gets a reference to `jwt.encode` */
private API::Node joseJWTEncode() { result = joseJWT().getMember("encode") }
private API::Node joseJwtEncode() { result = joseJwt().getMember("encode") }
/** Gets a reference to `jwt.decode` */
private API::Node joseJWTDecode() { result = joseJWT().getMember("decode") }
private API::Node joseJwtDecode() { result = joseJwt().getMember("decode") }
/**
* Gets a call to `jwt.encode`.
@@ -28,8 +28,8 @@ private module PythonJose {
* * `getAlgorithm()`'s result would be `"HS256"`.
* * `getAlgorithmstring()`'s result would be `HS256`.
*/
private class JoseJWTEncodeCall extends DataFlow::CallCfgNode, JWTEncoding::Range {
JoseJWTEncodeCall() { this = joseJWTEncode().getACall() }
private class JoseJwtEncodeCall extends DataFlow::CallCfgNode, JwtEncoding::Range {
JoseJwtEncodeCall() { this = joseJwtEncode().getACall() }
override DataFlow::Node getPayload() { result = this.getArg(0) }
@@ -64,8 +64,8 @@ private module PythonJose {
* * `getOptions()`'s result would be none.
* * `verifiesSignature()` predicate would succeed.
*/
private class JoseJWTDecodeCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
JoseJWTDecodeCall() { this = joseJWTDecode().getACall() }
private class JoseJwtDecodeCall extends DataFlow::CallCfgNode, JwtDecoding::Range {
JoseJwtDecodeCall() { this = joseJwtDecode().getACall() }
override DataFlow::Node getPayload() { result = this.getArg(0) }

View File

@@ -2,7 +2,7 @@ private import python
private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
private module Python_JWT {
private module Python_Jwt {
/**
* Gets a call to `python_jwt.process_jwt`.
*
@@ -21,7 +21,7 @@ private module Python_JWT {
* * `getOptions()`'s result would be `none()`.
* * `verifiesSignature()` predicate would succeed.
*/
private class PythonJwtProcessCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
private class PythonJwtProcessCall extends DataFlow::CallCfgNode, JwtDecoding::Range {
PythonJwtProcessCall() {
this = API::moduleImport("python_jwt").getMember("process_jwt").getACall()
}

View File

@@ -18,8 +18,8 @@ string getPrivateHostRegex() {
}
// "ldap://somethingon.theinternet.com"
class LDAPFullHost extends StrConst {
LDAPFullHost() {
class LdapFullHost extends StrConst {
LdapFullHost() {
exists(string s |
s = this.getText() and
s.regexpMatch(getFullHostRegex()) and
@@ -29,27 +29,39 @@ class LDAPFullHost extends StrConst {
}
}
class LDAPSchema extends StrConst {
LDAPSchema() { this.getText().regexpMatch(getSchemaRegex()) }
/** DEPRECATED: Alias for LdapFullHost */
deprecated class LDAPFullHost = LdapFullHost;
class LdapSchema extends StrConst {
LdapSchema() { this.getText().regexpMatch(getSchemaRegex()) }
}
class LDAPPrivateHost extends StrConst {
LDAPPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) }
/** DEPRECATED: Alias for LdapSchema */
deprecated class LDAPSchema = LdapSchema;
class LdapPrivateHost extends StrConst {
LdapPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) }
}
predicate concatAndCompareAgainstFullHostRegex(LDAPSchema schema, StrConst host) {
not host instanceof LDAPPrivateHost and
/** DEPRECATED: Alias for LdapPrivateHost */
deprecated class LDAPPrivateHost = LdapPrivateHost;
predicate concatAndCompareAgainstFullHostRegex(LdapSchema schema, StrConst host) {
not host instanceof LdapPrivateHost and
(schema.getText() + host.getText()).regexpMatch(getFullHostRegex())
}
// "ldap://" + "somethingon.theinternet.com"
class LDAPBothStrings extends BinaryExpr {
LDAPBothStrings() { concatAndCompareAgainstFullHostRegex(this.getLeft(), this.getRight()) }
class LdapBothStrings extends BinaryExpr {
LdapBothStrings() { concatAndCompareAgainstFullHostRegex(this.getLeft(), this.getRight()) }
}
/** DEPRECATED: Alias for LdapBothStrings */
deprecated class LDAPBothStrings = LdapBothStrings;
// schema + host
class LDAPBothVar extends BinaryExpr {
LDAPBothVar() {
class LdapBothVar extends BinaryExpr {
LdapBothVar() {
exists(SsaVariable schemaVar, SsaVariable hostVar |
this.getLeft() = schemaVar.getVariable().getALoad() and // getAUse is incompatible with Expr
this.getRight() = hostVar.getVariable().getALoad() and
@@ -61,9 +73,12 @@ class LDAPBothVar extends BinaryExpr {
}
}
/** DEPRECATED: Alias for LdapBothVar */
deprecated class LDAPBothVar = LdapBothVar;
// schema + "somethingon.theinternet.com"
class LDAPVarString extends BinaryExpr {
LDAPVarString() {
class LdapVarString extends BinaryExpr {
LdapVarString() {
exists(SsaVariable schemaVar |
this.getLeft() = schemaVar.getVariable().getALoad() and
concatAndCompareAgainstFullHostRegex(schemaVar
@@ -74,9 +89,12 @@ class LDAPVarString extends BinaryExpr {
}
}
/** DEPRECATED: Alias for LdapVarString */
deprecated class LDAPVarString = LdapVarString;
// "ldap://" + host
class LDAPStringVar extends BinaryExpr {
LDAPStringVar() {
class LdapStringVar extends BinaryExpr {
LdapStringVar() {
exists(SsaVariable hostVar |
this.getRight() = hostVar.getVariable().getALoad() and
concatAndCompareAgainstFullHostRegex(this.getLeft(),
@@ -85,22 +103,28 @@ class LDAPStringVar extends BinaryExpr {
}
}
/** DEPRECATED: Alias for LdapStringVar */
deprecated class LDAPStringVar = LdapStringVar;
/**
* A taint-tracking configuration for detecting LDAP insecure authentications.
*/
class LDAPInsecureAuthConfig extends TaintTracking::Configuration {
LDAPInsecureAuthConfig() { this = "LDAPInsecureAuthConfig" }
class LdapInsecureAuthConfig extends TaintTracking::Configuration {
LdapInsecureAuthConfig() { this = "LDAPInsecureAuthConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource or
source.asExpr() instanceof LDAPFullHost or
source.asExpr() instanceof LDAPBothStrings or
source.asExpr() instanceof LDAPBothVar or
source.asExpr() instanceof LDAPVarString or
source.asExpr() instanceof LDAPStringVar
source.asExpr() instanceof LdapFullHost or
source.asExpr() instanceof LdapBothStrings or
source.asExpr() instanceof LdapBothVar or
source.asExpr() instanceof LdapVarString or
source.asExpr() instanceof LdapStringVar
}
override predicate isSink(DataFlow::Node sink) {
exists(LDAPBind ldapBind | not ldapBind.useSSL() and sink = ldapBind.getHost())
exists(LdapBind ldapBind | not ldapBind.useSSL() and sink = ldapBind.getHost())
}
}
/** DEPRECATED: Alias for LdapInsecureAuthConfig */
deprecated class LDAPInsecureAuthConfig = LdapInsecureAuthConfig;

View File

@@ -5,7 +5,7 @@ import semmle.python.dataflow.new.RemoteFlowSources
import experimental.semmle.python.Concepts
import semmle.python.Concepts
module NoSQLInjection {
module NoSqlInjection {
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "NoSQLInjection" }
@@ -15,7 +15,7 @@ module NoSQLInjection {
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
sink = any(NoSQLQuery noSQLQuery).getQuery() and
sink = any(NoSqlQuery noSqlQuery).getQuery() and
state instanceof ConvertedToDict
}
@@ -38,7 +38,7 @@ module NoSQLInjection {
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer = any(NoSQLSanitizer noSQLSanitizer).getAnInput()
sanitizer = any(NoSqlSanitizer noSqlSanitizer).getAnInput()
}
}
@@ -52,3 +52,6 @@ module NoSQLInjection {
ConvertedToDict() { this = "ConvertedToDict" }
}
}
/** DEPRECATED: Alias for NoSqlInjection */
deprecated module NoSQLInjection = NoSqlInjection;

View File

@@ -25,7 +25,7 @@ module XSLTInjection {
ExternalXmlStringKind() { this = "etree.XML string" }
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
etreeXML(fromnode, tonode) and result instanceof ExternalXmlKind
etreeXml(fromnode, tonode) and result instanceof ExternalXmlKind
or
etreeFromStringList(fromnode, tonode) and result instanceof ExternalXmlKind
or
@@ -40,7 +40,7 @@ module XSLTInjection {
ExternalXmlKind() { this = "lxml etree xml" }
}
private predicate etreeXML(ControlFlowNode fromnode, CallNode tonode) {
private predicate etreeXml(ControlFlowNode fromnode, CallNode tonode) {
// etree.XML("<xmlContent>")
exists(CallNode call | call.getFunction().(AttrNode).getObject("XML").pointsTo(etree()) |
call.getArg(0) = fromnode and