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

@@ -610,8 +610,8 @@ module PrivateDjango {
/** Provides models for the `django.db.models.expressions` module. */
module expressions {
/** Provides models for the `django.db.models.expressions.RawSQL` class. */
module RawSQL {
/** Provides models for the `django.db.models.expressions.RawSql` class. */
module RawSql {
/**
* Gets an reference to the `django.db.models.expressions.RawSQL` class.
*/
@@ -644,6 +644,9 @@ module PrivateDjango {
instance(DataFlow::TypeTracker::end(), sql).flowsTo(result)
}
}
/** DEPRECATED: Alias for RawSql */
deprecated module RawSQL = RawSql;
}
}
}
@@ -660,7 +663,7 @@ module PrivateDjango {
ObjectsAnnotate() {
this = django::db::models::querySetReturningMethod("annotate").getACall() and
django::db::models::expressions::RawSQL::instance(sql) in [
django::db::models::expressions::RawSql::instance(sql) in [
this.getArg(_), this.getArgByName(_)
]
}
@@ -678,7 +681,7 @@ module PrivateDjango {
ObjectsAlias() {
this = django::db::models::querySetReturningMethod("alias").getACall() and
django::db::models::expressions::RawSQL::instance(sql) in [
django::db::models::expressions::RawSql::instance(sql) in [
this.getArg(_), this.getArgByName(_)
]
}

View File

@@ -30,13 +30,16 @@ private module FastApi {
*
* See https://fastapi.tiangolo.com/tutorial/bigger-applications/.
*/
module APIRouter {
/** Gets a reference to an instance of `fastapi.APIRouter`. */
module ApiRouter {
/** Gets a reference to an instance of `fastapi.ApiRouter`. */
API::Node instance() {
result = API::moduleImport("fastapi").getMember("APIRouter").getASubclass*().getReturn()
}
}
/** DEPRECATED: Alias for ApiRouter */
deprecated module APIRouter = ApiRouter;
// ---------------------------------------------------------------------------
// routing modeling
// ---------------------------------------------------------------------------
@@ -54,7 +57,7 @@ private module FastApi {
|
this = App::instance().getMember(routeAddingMethod).getACall()
or
this = APIRouter::instance().getMember(routeAddingMethod).getACall()
this = ApiRouter::instance().getMember(routeAddingMethod).getACall()
)
}

View File

@@ -14,7 +14,7 @@ private import semmle.python.frameworks.PEP249
* Provides models for the `PyMySQL` PyPI package.
* See https://pypi.org/project/PyMySQL/
*/
private module PyMySQL {
private module PyMySql {
/**
* A model of PyMySQL as a module that implements PEP 249, providing ways to execute SQL statements
* against a database.

View File

@@ -329,8 +329,8 @@ private module RestFramework {
*
* See https://www.django-rest-framework.org/api-guide/exceptions/#api-reference
*/
module APIException {
/** A direct instantiation of `rest_framework.exceptions.APIException` or subclass. */
module ApiException {
/** A direct instantiation of `rest_framework.exceptions.ApiException` or subclass. */
private class ClassInstantiation extends HTTP::Server::HttpResponse::Range,
DataFlow::CallCfgNode {
string className;
@@ -366,4 +366,7 @@ private module RestFramework {
override string getMimetypeDefault() { none() }
}
}
/** DEPRECATED: Alias for ApiException */
deprecated module APIException = ApiException;
}

View File

@@ -137,7 +137,7 @@ module SqlAlchemy {
*
* See https://docs.sqlalchemy.org/en/14/core/connections.html#dbapi-connections.
*/
module DBAPIConnection {
module DBApiConnection {
/**
* A source of instances of DB-API Connections, extend this class to model new instances.
*
@@ -149,8 +149,8 @@ module SqlAlchemy {
*/
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
private class DBAPIConnectionSources extends InstanceSource, PEP249::Connection::InstanceSource {
DBAPIConnectionSources() {
private class DBApiConnectionSources extends InstanceSource, PEP249::Connection::InstanceSource {
DBApiConnectionSources() {
this.(DataFlow::MethodCallNode).calls(Engine::instance(), "raw_connection")
or
this.(DataFlow::AttrRead).accesses(Connection::instance(), "connection")
@@ -169,6 +169,9 @@ module SqlAlchemy {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
}
/** DEPRECATED: Alias for DBApiConnection */
deprecated module DBAPIConnection = DBApiConnection;
/**
* Provides models for the `sqlalchemy.orm.Session` class
*

View File

@@ -90,7 +90,7 @@ module Stdlib {
* https://github.com/python/cpython/blob/64f54b7ccd49764b0304e076bfd79b5482988f53/Lib/http/client.py#L175
* and https://docs.python.org/3.9/library/email.compat32-message.html#email.message.Message
*/
module HTTPMessage {
module HttpMessage {
/**
* A source of instances of `http.client.HTTPMessage`, extend this class to model new instances.
*
@@ -102,7 +102,7 @@ module Stdlib {
*/
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** Gets a reference to an instance of `http.client.HTTPMessage`. */
/** Gets a reference to an instance of `http.client.HttpMessage`. */
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
@@ -110,7 +110,7 @@ module Stdlib {
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
}
/** Gets a reference to an instance of `http.client.HTTPMessage`. */
/** Gets a reference to an instance of `http.client.HttpMessage`. */
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/**
@@ -129,6 +129,9 @@ module Stdlib {
}
}
/** DEPRECATED: Alias for HttpMessage */
deprecated module HTTPMessage = HttpMessage;
/**
* Provides models for the `http.cookies.Morsel` class
*
@@ -1783,42 +1786,63 @@ private module StdlibPrivate {
// ---------------------------------------------------------------------------
// BaseHTTPServer (Python 2 only)
// ---------------------------------------------------------------------------
/** Gets a reference to the `BaseHTTPServer` module. */
API::Node baseHTTPServer() { result = API::moduleImport("BaseHTTPServer") }
/** Gets a reference to the `BaseHttpServer` module. */
API::Node baseHttpServer() { result = API::moduleImport("BaseHTTPServer") }
/** Provides models for the `BaseHTTPServer` module. */
module BaseHTTPServer {
/** DEPRECATED: Alias for baseHttpServer */
deprecated API::Node baseHTTPServer() { result = baseHttpServer() }
/** Provides models for the `BaseHttpServer` module. */
module BaseHttpServer {
/**
* Provides models for the `BaseHTTPServer.BaseHTTPRequestHandler` class (Python 2 only).
*/
module BaseHTTPRequestHandler {
/** Gets a reference to the `BaseHTTPServer.BaseHTTPRequestHandler` class. */
API::Node classRef() { result = baseHTTPServer().getMember("BaseHTTPRequestHandler") }
module BaseHttpRequestHandler {
/** Gets a reference to the `BaseHttpServer.BaseHttpRequestHandler` class. */
API::Node classRef() { result = baseHttpServer().getMember("BaseHTTPRequestHandler") }
}
/** DEPRECATED: Alias for BaseHttpRequestHandler */
deprecated module BaseHTTPRequestHandler = BaseHttpRequestHandler;
}
/** DEPRECATED: Alias for BaseHttpServer */
deprecated module BaseHTTPServer = BaseHttpServer;
// ---------------------------------------------------------------------------
// SimpleHTTPServer (Python 2 only)
// ---------------------------------------------------------------------------
/** Gets a reference to the `SimpleHTTPServer` module. */
API::Node simpleHTTPServer() { result = API::moduleImport("SimpleHTTPServer") }
/** Gets a reference to the `SimpleHttpServer` module. */
API::Node simpleHttpServer() { result = API::moduleImport("SimpleHTTPServer") }
/** Provides models for the `SimpleHTTPServer` module. */
module SimpleHTTPServer {
/** DEPRECATED: Alias for simpleHttpServer */
deprecated API::Node simpleHTTPServer() { result = simpleHttpServer() }
/** Provides models for the `SimpleHttpServer` module. */
module SimpleHttpServer {
/**
* Provides models for the `SimpleHTTPServer.SimpleHTTPRequestHandler` class (Python 2 only).
*/
module SimpleHTTPRequestHandler {
/** Gets a reference to the `SimpleHTTPServer.SimpleHTTPRequestHandler` class. */
API::Node classRef() { result = simpleHTTPServer().getMember("SimpleHTTPRequestHandler") }
module SimpleHttpRequestHandler {
/** Gets a reference to the `SimpleHttpServer.SimpleHttpRequestHandler` class. */
API::Node classRef() { result = simpleHttpServer().getMember("SimpleHTTPRequestHandler") }
}
/** DEPRECATED: Alias for SimpleHttpRequestHandler */
deprecated module SimpleHTTPRequestHandler = SimpleHttpRequestHandler;
}
/** DEPRECATED: Alias for SimpleHttpServer */
deprecated module SimpleHTTPServer = SimpleHttpServer;
// ---------------------------------------------------------------------------
// CGIHTTPServer (Python 2 only)
// ---------------------------------------------------------------------------
/** Gets a reference to the `CGIHTTPServer` module. */
API::Node cgiHTTPServer() { result = API::moduleImport("CGIHTTPServer") }
API::Node cgiHttpServer() { result = API::moduleImport("CGIHTTPServer") }
/** DEPRECATED: Alias for cgiHttpServer */
deprecated API::Node cgiHTTPServer() { result = cgiHttpServer() }
/** Provides models for the `CGIHTTPServer` module. */
module CGIHTTPServer {
@@ -1827,7 +1851,7 @@ private module StdlibPrivate {
*/
module CGIHTTPRequestHandler {
/** Gets a reference to the `CGIHTTPServer.CGIHTTPRequestHandler` class. */
API::Node classRef() { result = cgiHTTPServer().getMember("CGIHTTPRequestHandler") }
API::Node classRef() { result = cgiHttpServer().getMember("CGIHTTPRequestHandler") }
}
}
@@ -1852,21 +1876,27 @@ private module StdlibPrivate {
*
* See https://docs.python.org/3.9/library/http.server.html#http.server.BaseHTTPRequestHandler.
*/
module BaseHTTPRequestHandler {
/** Gets a reference to the `http.server.BaseHTTPRequestHandler` class. */
module BaseHttpRequestHandler {
/** Gets a reference to the `http.server.BaseHttpRequestHandler` class. */
API::Node classRef() { result = server().getMember("BaseHTTPRequestHandler") }
}
/** DEPRECATED: Alias for BaseHttpRequestHandler */
deprecated module BaseHTTPRequestHandler = BaseHttpRequestHandler;
/**
* Provides models for the `http.server.SimpleHTTPRequestHandler` class (Python 3 only).
*
* See https://docs.python.org/3.9/library/http.server.html#http.server.SimpleHTTPRequestHandler.
*/
module SimpleHTTPRequestHandler {
/** Gets a reference to the `http.server.SimpleHTTPRequestHandler` class. */
module SimpleHttpRequestHandler {
/** Gets a reference to the `http.server.SimpleHttpRequestHandler` class. */
API::Node classRef() { result = server().getMember("SimpleHTTPRequestHandler") }
}
/** DEPRECATED: Alias for SimpleHttpRequestHandler */
deprecated module SimpleHTTPRequestHandler = SimpleHttpRequestHandler;
/**
* Provides models for the `http.server.CGIHTTPRequestHandler` class (Python 3 only).
*
@@ -1886,27 +1916,30 @@ private module StdlibPrivate {
* - https://docs.python.org/3.9/library/http.server.html#http.server.BaseHTTPRequestHandler
* - https://docs.python.org/2.7/library/basehttpserver.html#BaseHTTPServer.BaseHTTPRequestHandler
*/
private module HTTPRequestHandler {
/** Gets a reference to the `BaseHTTPRequestHandler` class or any subclass. */
private module HttpRequestHandler {
/** Gets a reference to the `BaseHttpRequestHandler` class or any subclass. */
API::Node subclassRef() {
result =
[
// Python 2
BaseHTTPServer::BaseHTTPRequestHandler::classRef(),
SimpleHTTPServer::SimpleHTTPRequestHandler::classRef(),
BaseHttpServer::BaseHttpRequestHandler::classRef(),
SimpleHttpServer::SimpleHttpRequestHandler::classRef(),
CGIHTTPServer::CGIHTTPRequestHandler::classRef(),
// Python 3
http::server::BaseHTTPRequestHandler::classRef(),
http::server::SimpleHTTPRequestHandler::classRef(),
http::server::BaseHttpRequestHandler::classRef(),
http::server::SimpleHttpRequestHandler::classRef(),
http::server::CGIHTTPRequestHandler::classRef()
].getASubclass*()
}
/** A HTTPRequestHandler class definition (most likely in project code). */
class HTTPRequestHandlerClassDef extends Class {
HTTPRequestHandlerClassDef() { this.getParent() = subclassRef().getAUse().asExpr() }
/** A HttpRequestHandler class definition (most likely in project code). */
class HttpRequestHandlerClassDef extends Class {
HttpRequestHandlerClassDef() { this.getParent() = subclassRef().getAUse().asExpr() }
}
/** DEPRECATED: Alias for HttpRequestHandlerClassDef */
deprecated class HTTPRequestHandlerClassDef = HttpRequestHandlerClassDef;
/**
* A source of instances of the `BaseHTTPRequestHandler` class or any subclass, extend this class to model new instances.
*
@@ -1918,16 +1951,16 @@ private module StdlibPrivate {
*/
abstract class InstanceSource extends DataFlow::Node { }
/** The `self` parameter in a method on the `BaseHTTPRequestHandler` class or any subclass. */
/** The `self` parameter in a method on the `BaseHttpRequestHandler` class or any subclass. */
private class SelfParam extends InstanceSource, RemoteFlowSource::Range, DataFlow::ParameterNode {
SelfParam() {
exists(HTTPRequestHandlerClassDef cls | cls.getAMethod().getArg(0) = this.getParameter())
exists(HttpRequestHandlerClassDef cls | cls.getAMethod().getArg(0) = this.getParameter())
}
override string getSourceType() { result = "stdlib HTTPRequestHandler" }
}
/** Gets a reference to an instance of the `BaseHTTPRequestHandler` class or any subclass. */
/** Gets a reference to an instance of the `BaseHttpRequestHandler` class or any subclass. */
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
@@ -1935,7 +1968,7 @@ private module StdlibPrivate {
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
}
/** Gets a reference to an instance of the `BaseHTTPRequestHandler` class or any subclass. */
/** Gets a reference to an instance of the `BaseHttpRequestHandler` class or any subclass. */
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
private class AdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
@@ -1956,16 +1989,16 @@ private module StdlibPrivate {
}
}
/** An `HTTPMessage` instance that originates from a `BaseHTTPRequestHandler` instance. */
private class BaseHTTPRequestHandlerHeadersInstances extends Stdlib::HTTPMessage::InstanceSource {
BaseHTTPRequestHandlerHeadersInstances() {
/** An `HttpMessage` instance that originates from a `BaseHttpRequestHandler` instance. */
private class BaseHttpRequestHandlerHeadersInstances extends Stdlib::HttpMessage::InstanceSource {
BaseHttpRequestHandlerHeadersInstances() {
this.(DataFlow::AttrRead).accesses(instance(), "headers")
}
}
/** A file-like object that originates from a `BaseHTTPRequestHandler` instance. */
private class BaseHTTPRequestHandlerFileLikeObjectInstances extends Stdlib::FileLikeObject::InstanceSource {
BaseHTTPRequestHandlerFileLikeObjectInstances() {
/** A file-like object that originates from a `BaseHttpRequestHandler` instance. */
private class BaseHttpRequestHandlerFileLikeObjectInstances extends Stdlib::FileLikeObject::InstanceSource {
BaseHttpRequestHandlerFileLikeObjectInstances() {
this.(DataFlow::AttrRead).accesses(instance(), "rfile")
}
}
@@ -1977,7 +2010,7 @@ private module StdlibPrivate {
*/
private class RequestHandlerFunc extends HTTP::Server::RequestHandler::Range {
RequestHandlerFunc() {
this = any(HTTPRequestHandlerClassDef cls).getAMethod() and
this = any(HttpRequestHandlerClassDef cls).getAMethod() and
this.getName() = "do_" + HTTP::httpVerb()
}
@@ -2155,8 +2188,8 @@ private module StdlibPrivate {
* - https://docs.python.org/2.7/library/httplib.html#httplib.HTTPConnection
* - https://docs.python.org/2.7/library/httplib.html#httplib.HTTPSConnection
*/
module HTTPConnection {
/** Gets a reference to the `http.client.HTTPConnection` class. */
module HttpConnection {
/** Gets a reference to the `http.client.HttpConnection` class. */
private API::Node classRef() {
exists(string className | className in ["HTTPConnection", "HTTPSConnection"] |
// Python 3
@@ -2184,7 +2217,7 @@ private module StdlibPrivate {
abstract DataFlow::Node getHostArgument();
}
/** A direct instantiation of `http.client.HTTPConnection`. */
/** A direct instantiation of `http.client.HttpConnection`. */
private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode {
ClassInstantiation() { this = classRef().getACall() }
@@ -2212,7 +2245,7 @@ private module StdlibPrivate {
instance(DataFlow::TypeTracker::end(), hostArg).flowsTo(result)
}
/** A method call on a HTTPConnection that sends off a request */
/** A method call on a HttpConnection that sends off a request */
private class RequestCall extends HTTP::Client::Request::Range, DataFlow::MethodCallNode {
RequestCall() { this.calls(instance(_), ["request", "_send_request", "putrequest"]) }
@@ -2238,7 +2271,7 @@ private module StdlibPrivate {
/** A call to the `getresponse` method. */
private class HttpConnectionGetResponseCall extends DataFlow::MethodCallNode,
HTTPResponse::InstanceSource {
HttpResponse::InstanceSource {
HttpConnectionGetResponseCall() { this.calls(instance(_), "getresponse") }
}
@@ -2269,6 +2302,9 @@ private module StdlibPrivate {
}
}
/** DEPRECATED: Alias for HttpConnection */
deprecated module HTTPConnection = HttpConnection;
/**
* Provides models for the `http.client.HTTPResponse` class
*
@@ -2276,8 +2312,8 @@ private module StdlibPrivate {
* - https://docs.python.org/3.10/library/http.client.html#httpresponse-objects
* - https://docs.python.org/3/library/http.client.html#http.client.HTTPResponse.
*/
module HTTPResponse {
/** Gets a reference to the `http.client.HTTPResponse` class. */
module HttpResponse {
/** Gets a reference to the `http.client.HttpResponse` class. */
private API::Node classRef() {
result = API::moduleImport("http").getMember("client").getMember("HTTPResponse")
}
@@ -2296,12 +2332,12 @@ private module StdlibPrivate {
abstract class InstanceSource extends Stdlib::FileLikeObject::InstanceSource,
DataFlow::LocalSourceNode { }
/** A direct instantiation of `http.client.HTTPResponse`. */
/** A direct instantiation of `http.client.HttpResponse`. */
private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode {
ClassInstantiation() { this = classRef().getACall() }
}
/** Gets a reference to an instance of `http.client.HTTPResponse`. */
/** Gets a reference to an instance of `http.client.HttpResponse`. */
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
@@ -2309,7 +2345,7 @@ private module StdlibPrivate {
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
}
/** Gets a reference to an instance of `http.client.HTTPResponse`. */
/** Gets a reference to an instance of `http.client.HttpResponse`. */
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/**
@@ -2327,9 +2363,9 @@ private module StdlibPrivate {
override string getAsyncMethodName() { none() }
}
/** An attribute read that is a HTTPMessage instance. */
private class HTTPMessageInstances extends Stdlib::HTTPMessage::InstanceSource {
HTTPMessageInstances() {
/** An attribute read that is a HttpMessage instance. */
private class HttpMessageInstances extends Stdlib::HttpMessage::InstanceSource {
HttpMessageInstances() {
this.(DataFlow::AttrRead).accesses(instance(), ["headers", "msg"])
or
this.(DataFlow::MethodCallNode).calls(instance(), "info")
@@ -2337,6 +2373,9 @@ private module StdlibPrivate {
}
}
/** DEPRECATED: Alias for HttpResponse */
deprecated module HTTPResponse = HttpResponse;
// ---------------------------------------------------------------------------
// sqlite3
// ---------------------------------------------------------------------------

View File

@@ -23,7 +23,7 @@ private module Tornado {
*
* See https://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPHeaders.
*/
module HTTPHeaders {
module HttpHeaders {
/**
* A source of instances of `tornado.httputil.HTTPHeaders`, extend this class to model new instances.
*
@@ -35,7 +35,7 @@ private module Tornado {
*/
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** Gets a reference to an instance of `tornado.httputil.HTTPHeaders`. */
/** Gets a reference to an instance of `tornado.httputil.HttpHeaders`. */
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
@@ -43,7 +43,7 @@ private module Tornado {
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
}
/** Gets a reference to an instance of `tornado.httputil.HTTPHeaders`. */
/** Gets a reference to an instance of `tornado.httputil.HttpHeaders`. */
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/**
@@ -62,6 +62,9 @@ private module Tornado {
}
}
/** DEPRECATED: Alias for HttpHeaders */
deprecated module HTTPHeaders = HttpHeaders;
// ---------------------------------------------------------------------------
// tornado
// ---------------------------------------------------------------------------
@@ -323,9 +326,9 @@ private module Tornado {
override string getAsyncMethodName() { none() }
}
/** An `HTTPHeaders` instance that originates from a Tornado request. */
private class TornadoRequestHTTPHeadersInstances extends HTTPHeaders::InstanceSource {
TornadoRequestHTTPHeadersInstances() {
/** An `HttpHeaders` instance that originates from a Tornado request. */
private class TornadoRequestHttpHeadersInstances extends HttpHeaders::InstanceSource {
TornadoRequestHttpHeadersInstances() {
this.(DataFlow::AttrRead).accesses(instance(), "headers")
}
}

View File

@@ -34,7 +34,7 @@ private module NotExposed {
concat(string newModelFullyQualified |
newModel(any(MySpec spec), newModelFullyQualified, _, _, _)
|
fullyQualifiedToAPIGraphPath(newModelFullyQualified), " or this = API::"
fullyQualifiedToApiGraphPath(newModelFullyQualified), " or this = API::"
)
}
@@ -69,10 +69,15 @@ private module NotExposed {
//
//
bindingset[fullyQaulified]
string fullyQualifiedToAPIGraphPath(string fullyQaulified) {
string fullyQualifiedToApiGraphPath(string fullyQaulified) {
result = "moduleImport(\"" + fullyQaulified.replaceAll(".", "\").getMember(\"") + "\")"
}
/** DEPRECATED: Alias for fullyQualifiedToApiGraphPath */
deprecated string fullyQualifiedToAPIGraphPath(string fullyQaulified) {
result = fullyQualifiedToApiGraphPath(fullyQaulified)
}
bindingset[this]
abstract class FindSubclassesSpec extends string {
abstract API::Node getAlreadyModeledClass();
@@ -99,13 +104,13 @@ private module NotExposed {
or
exists(string newSubclassName |
newModel(spec, newSubclassName, _, _, _) and
result.getPath() = fullyQualifiedToAPIGraphPath(newSubclassName)
result.getPath() = fullyQualifiedToApiGraphPath(newSubclassName)
)
}
bindingset[fullyQualifiedName]
predicate alreadyModeled(FindSubclassesSpec spec, string fullyQualifiedName) {
fullyQualifiedToAPIGraphPath(fullyQualifiedName) = spec.getAlreadyModeledClass().getPath()
fullyQualifiedToApiGraphPath(fullyQualifiedName) = spec.getAlreadyModeledClass().getPath()
}
predicate isNonTestProjectCode(AstNode ast) {

View File

@@ -176,8 +176,8 @@ private module RegexpMatching {
}
/** A class to test whether a regular expression matches certain HTML tags. */
class HTMLMatchingRegExp extends RegexpMatching::MatchedRegExp {
HTMLMatchingRegExp() {
class HtmlMatchingRegExp extends RegexpMatching::MatchedRegExp {
HtmlMatchingRegExp() {
// the regexp must mention "<" and ">" explicitly.
forall(string angleBracket | angleBracket = ["<", ">"] |
any(RegExpConstant term | term.getValue().matches("%" + angleBracket + "%")).getRootTerm() =
@@ -204,12 +204,15 @@ class HTMLMatchingRegExp extends RegexpMatching::MatchedRegExp {
}
}
/** DEPRECATED: Alias for HtmlMatchingRegExp */
deprecated class HTMLMatchingRegExp = HtmlMatchingRegExp;
/**
* Holds if `regexp` matches some HTML tags, but misses some HTML tags that it should match.
*
* When adding a new case to this predicate, make sure the test string used in `matches(..)` calls are present in `HTMLMatchingRegExp::test` / `HTMLMatchingRegExp::testWithGroups`.
*/
predicate isBadRegexpFilter(HTMLMatchingRegExp regexp, string msg) {
predicate isBadRegexpFilter(HtmlMatchingRegExp regexp, string msg) {
// CVE-2021-33829 - matching both "<!-- foo -->" and "<!-- foo --!>", but in different capture groups
regexp.matches("<!-- foo -->") and
regexp.matches("<!-- foo --!>") and

View File

@@ -13,8 +13,8 @@ import semmle.python.dataflow.new.TaintTracking
/**
* Provides a taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities.
*/
module ReflectedXSS {
import ReflectedXSSCustomizations::ReflectedXSS
module ReflectedXss {
import ReflectedXSSCustomizations::ReflectedXss
/**
* A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities.
@@ -34,9 +34,12 @@ module ReflectedXSS {
}
}
/** DEPRECATED: Alias for ReflectedXss */
deprecated module ReflectedXSS = ReflectedXss;
/**
* DEPRECATED: Don't extend this class for customization, since this will lead to bad
* performance, instead use the new `ReflectedXSSCustomizations.qll` file, and extend
* its' classes.
*/
deprecated class ReflectedXssConfiguration = ReflectedXSS::Configuration;
deprecated class ReflectedXssConfiguration = ReflectedXss::Configuration;

View File

@@ -15,7 +15,7 @@ private import semmle.python.dataflow.new.BarrierGuards
* "reflected server-side cross-site scripting"
* vulnerabilities, as well as extension points for adding your own.
*/
module ReflectedXSS {
module ReflectedXss {
/**
* A data flow source for "reflected server-side cross-site scripting" vulnerabilities.
*/
@@ -74,3 +74,6 @@ module ReflectedXSS {
*/
class StringConstCompareAsSanitizerGuard extends SanitizerGuard, StringConstCompare { }
}
/** DEPRECATED: Alias for ReflectedXss */
deprecated module ReflectedXSS = ReflectedXss;

View File

@@ -39,4 +39,7 @@ module SqlInjection {
* performance, instead use the new `SqlInjectionCustomizations.qll` file, and extend
* its' classes.
*/
deprecated class SQLInjectionConfiguration = SqlInjection::Configuration;
deprecated class SqlInjectionConfiguration = SqlInjection::Configuration;
/** DEPRECATED: Alias for SqlInjectionConfiguration */
deprecated class SQLInjectionConfiguration = SqlInjectionConfiguration;

View File

@@ -8,7 +8,7 @@ import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
/** Source of BaseHTTPRequestHandler instances. */
/** Source of BaseHttpRequestHandler instances. */
deprecated class StdLibRequestSource extends HttpRequestTaintSource {
StdLibRequestSource() {
exists(ClassValue cls |
@@ -23,7 +23,7 @@ deprecated class StdLibRequestSource extends HttpRequestTaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof BaseHTTPRequestHandlerKind }
}
/** TaintKind for an instance of BaseHTTPRequestHandler. */
/** TaintKind for an instance of BaseHttpRequestHandler. */
deprecated class BaseHTTPRequestHandlerKind extends TaintKind {
BaseHTTPRequestHandlerKind() { this = "BaseHTTPRequestHandlerKind" }
@@ -39,7 +39,7 @@ deprecated class BaseHTTPRequestHandlerKind extends TaintKind {
}
}
/** TaintKind for headers (instance of HTTPMessage). */
/** TaintKind for headers (instance of HttpMessage). */
deprecated class HTTPMessageKind extends ExternalStringDictKind {
override TaintKind getTaintOfMethodResult(string name) {
result = super.getTaintOfMethodResult(name)

View File

@@ -18,7 +18,7 @@ deprecated private predicate is_wfile(AttrNode wfile) {
)
}
/** Sink for `h.wfile.write` where `h` is an instance of BaseHTTPRequestHandler. */
/** Sink for `h.wfile.write` where `h` is an instance of BaseHttpRequestHandler. */
deprecated class StdLibWFileWriteSink extends HttpResponseTaintSink {
StdLibWFileWriteSink() {
exists(CallNode call |
@@ -30,7 +30,7 @@ deprecated class StdLibWFileWriteSink extends HttpResponseTaintSink {
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
/** Sink for `h.wfile.writelines` where `h` is an instance of BaseHTTPRequestHandler. */
/** Sink for `h.wfile.writelines` where `h` is an instance of BaseHttpRequestHandler. */
deprecated class StdLibWFileWritelinesSink extends HttpResponseTaintSink {
StdLibWFileWritelinesSink() {
exists(CallNode call |

View File

@@ -4,11 +4,11 @@
import semmle.files.FileSystem
private class TXMLLocatable =
private class TXmlLocatable =
@xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters;
/** An XML element that has a location. */
class XMLLocatable extends @xmllocatable, TXMLLocatable {
class XMLLocatable extends @xmllocatable, TXmlLocatable {
/** Gets the source location for this element. */
Location getLocation() { xmllocations(this, result) }

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

View File

@@ -1,73 +1,106 @@
import python
abstract class XMLBytecodeExpr extends XMLElement { }
abstract class XmlBytecodeExpr extends XMLElement { }
class XMLBytecodeConst extends XMLBytecodeExpr {
XMLBytecodeConst() { this.hasName("BytecodeConst") }
/** DEPRECATED: Alias for XmlBytecodeExpr */
deprecated class XMLBytecodeExpr = XmlBytecodeExpr;
class XmlBytecodeConst extends XmlBytecodeExpr {
XmlBytecodeConst() { this.hasName("BytecodeConst") }
string get_value_data_raw() { result = this.getAChild("value").getTextValue() }
}
class XMLBytecodeVariableName extends XMLBytecodeExpr {
XMLBytecodeVariableName() { this.hasName("BytecodeVariableName") }
/** DEPRECATED: Alias for XmlBytecodeConst */
deprecated class XMLBytecodeConst = XmlBytecodeConst;
class XmlBytecodeVariableName extends XmlBytecodeExpr {
XmlBytecodeVariableName() { this.hasName("BytecodeVariableName") }
string get_name_data() { result = this.getAChild("name").getTextValue() }
}
class XMLBytecodeAttribute extends XMLBytecodeExpr {
XMLBytecodeAttribute() { this.hasName("BytecodeAttribute") }
/** DEPRECATED: Alias for XmlBytecodeVariableName */
deprecated class XMLBytecodeVariableName = XmlBytecodeVariableName;
class XmlBytecodeAttribute extends XmlBytecodeExpr {
XmlBytecodeAttribute() { this.hasName("BytecodeAttribute") }
string get_attr_name_data() { result = this.getAChild("attr_name").getTextValue() }
XMLBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") }
XmlBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") }
}
class XMLBytecodeSubscript extends XMLBytecodeExpr {
XMLBytecodeSubscript() { this.hasName("BytecodeSubscript") }
/** DEPRECATED: Alias for XmlBytecodeAttribute */
deprecated class XMLBytecodeAttribute = XmlBytecodeAttribute;
XMLBytecodeExpr get_key_data() { result.getParent() = this.getAChild("key") }
class XmlBytecodeSubscript extends XmlBytecodeExpr {
XmlBytecodeSubscript() { this.hasName("BytecodeSubscript") }
XMLBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") }
XmlBytecodeExpr get_key_data() { result.getParent() = this.getAChild("key") }
XmlBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") }
}
class XMLBytecodeTuple extends XMLBytecodeExpr {
XMLBytecodeTuple() { this.hasName("BytecodeTuple") }
/** DEPRECATED: Alias for XmlBytecodeSubscript */
deprecated class XMLBytecodeSubscript = XmlBytecodeSubscript;
XMLBytecodeExpr get_elements_data(int index) {
class XmlBytecodeTuple extends XmlBytecodeExpr {
XmlBytecodeTuple() { this.hasName("BytecodeTuple") }
XmlBytecodeExpr get_elements_data(int index) {
result = this.getAChild("elements").getChild(index)
}
}
class XMLBytecodeList extends XMLBytecodeExpr {
XMLBytecodeList() { this.hasName("BytecodeList") }
/** DEPRECATED: Alias for XmlBytecodeTuple */
deprecated class XMLBytecodeTuple = XmlBytecodeTuple;
XMLBytecodeExpr get_elements_data(int index) {
class XmlBytecodeList extends XmlBytecodeExpr {
XmlBytecodeList() { this.hasName("BytecodeList") }
XmlBytecodeExpr get_elements_data(int index) {
result = this.getAChild("elements").getChild(index)
}
}
class XMLBytecodeCall extends XMLBytecodeExpr {
XMLBytecodeCall() { this.hasName("BytecodeCall") }
/** DEPRECATED: Alias for XmlBytecodeList */
deprecated class XMLBytecodeList = XmlBytecodeList;
XMLBytecodeExpr get_function_data() { result.getParent() = this.getAChild("function") }
class XmlBytecodeCall extends XmlBytecodeExpr {
XmlBytecodeCall() { this.hasName("BytecodeCall") }
XmlBytecodeExpr get_function_data() { result.getParent() = this.getAChild("function") }
}
class XMLBytecodeUnknown extends XMLBytecodeExpr {
XMLBytecodeUnknown() { this.hasName("BytecodeUnknown") }
/** DEPRECATED: Alias for XmlBytecodeCall */
deprecated class XMLBytecodeCall = XmlBytecodeCall;
class XmlBytecodeUnknown extends XmlBytecodeExpr {
XmlBytecodeUnknown() { this.hasName("BytecodeUnknown") }
string get_opname_data() { result = this.getAChild("opname").getTextValue() }
}
class XMLBytecodeMakeFunction extends XMLBytecodeExpr {
XMLBytecodeMakeFunction() { this.hasName("BytecodeMakeFunction") }
/** DEPRECATED: Alias for XmlBytecodeUnknown */
deprecated class XMLBytecodeUnknown = XmlBytecodeUnknown;
XMLBytecodeExpr get_qualified_name_data() {
class XmlBytecodeMakeFunction extends XmlBytecodeExpr {
XmlBytecodeMakeFunction() { this.hasName("BytecodeMakeFunction") }
XmlBytecodeExpr get_qualified_name_data() {
result.getParent() = this.getAChild("qualified_name")
}
}
class XMLSomethingInvolvingScaryBytecodeJump extends XMLBytecodeExpr {
XMLSomethingInvolvingScaryBytecodeJump() { this.hasName("SomethingInvolvingScaryBytecodeJump") }
/** DEPRECATED: Alias for XmlBytecodeMakeFunction */
deprecated class XMLBytecodeMakeFunction = XmlBytecodeMakeFunction;
class XmlSomethingInvolvingScaryBytecodeJump extends XmlBytecodeExpr {
XmlSomethingInvolvingScaryBytecodeJump() { this.hasName("SomethingInvolvingScaryBytecodeJump") }
string get_opname_data() { result = this.getAChild("opname").getTextValue() }
}
/** DEPRECATED: Alias for XmlSomethingInvolvingScaryBytecodeJump */
deprecated class XMLSomethingInvolvingScaryBytecodeJump = XmlSomethingInvolvingScaryBytecodeJump;

View File

@@ -4,30 +4,36 @@ import semmle.python.objects.Callables
import lib.BytecodeExpr
/** The XML data for a recorded call (includes all data). */
class XMLRecordedCall extends XMLElement {
XMLRecordedCall() { this.hasName("recorded_call") }
class XmlRecordedCall extends XMLElement {
XmlRecordedCall() { this.hasName("recorded_call") }
/** Gets the XML data for the call. */
XMLCall getXMLCall() { result.getParent() = this }
XmlCall getXmlCall() { result.getParent() = this }
/** DEPRECATED: Alias for getXmlCall */
deprecated XMLCall getXMLCall() { result = getXmlCall() }
/** Gets a call matching the recorded information. */
Call getACall() { result = this.getXMLCall().getACall() }
Call getACall() { result = this.getXmlCall().getACall() }
/** Gets the XML data for the callee. */
XMLCallee getXMLCallee() { result.getParent() = this }
XmlCallee getXmlCallee() { result.getParent() = this }
/** DEPRECATED: Alias for getXmlCallee */
deprecated XMLCallee getXMLCallee() { result = getXmlCallee() }
/** Gets a python function matching the recorded information of the callee. */
Function getAPythonCallee() { result = this.getXMLCallee().(XMLPythonCallee).getACallee() }
Function getAPythonCallee() { result = this.getXmlCallee().(XmlPythonCallee).getACallee() }
/** Gets a builtin function matching the recorded information of the callee. */
Builtin getABuiltinCallee() { result = this.getXMLCallee().(XMLExternalCallee).getACallee() }
Builtin getABuiltinCallee() { result = this.getXmlCallee().(XmlExternalCallee).getACallee() }
/** Get a different `XMLRecordedCall` with the same result-set for `getACall`. */
XMLRecordedCall getOtherWithSameSetOfCalls() {
/** Get a different `XmlRecordedCall` with the same result-set for `getACall`. */
XmlRecordedCall getOtherWithSameSetOfCalls() {
// `rc` is for a different bytecode instruction on same line
not result.getXMLCall().get_inst_index_data() = this.getXMLCall().get_inst_index_data() and
result.getXMLCall().get_filename_data() = this.getXMLCall().get_filename_data() and
result.getXMLCall().get_linenum_data() = this.getXMLCall().get_linenum_data() and
not result.getXmlCall().get_inst_index_data() = this.getXmlCall().get_inst_index_data() and
result.getXmlCall().get_filename_data() = this.getXmlCall().get_filename_data() and
result.getXmlCall().get_linenum_data() = this.getXmlCall().get_linenum_data() and
// set of calls are equal
forall(Call call | call = this.getACall() or call = result.getACall() |
call = this.getACall() and call = result.getACall()
@@ -37,23 +43,26 @@ class XMLRecordedCall extends XMLElement {
override string toString() {
exists(string path |
path =
any(File file | file.getAbsolutePath() = this.getXMLCall().get_filename_data())
any(File file | file.getAbsolutePath() = this.getXmlCall().get_filename_data())
.getRelativePath()
or
not exists(File file |
file.getAbsolutePath() = this.getXMLCall().get_filename_data() and
file.getAbsolutePath() = this.getXmlCall().get_filename_data() and
exists(file.getRelativePath())
) and
path = this.getXMLCall().get_filename_data()
path = this.getXmlCall().get_filename_data()
|
result = this.getName() + ": " + path + ":" + this.getXMLCall().get_linenum_data()
result = this.getName() + ": " + path + ":" + this.getXmlCall().get_linenum_data()
)
}
}
/** DEPRECATED: Alias for XmlRecordedCall */
deprecated class XMLRecordedCall = XmlRecordedCall;
/** The XML data for the call part a recorded call. */
class XMLCall extends XMLElement {
XMLCall() { this.hasName("Call") }
class XmlCall extends XMLElement {
XmlCall() { this.hasName("Call") }
string get_filename_data() { result = this.getAChild("filename").getTextValue() }
@@ -68,8 +77,8 @@ class XMLCall extends XMLElement {
}
/** Holds if `expr` can be fully matched with `bytecode`. */
private predicate matchBytecodeExpr(Expr expr, XMLBytecodeExpr bytecode) {
exists(Call parent_call, XMLBytecodeCall parent_bytecode_call |
private predicate matchBytecodeExpr(Expr expr, XmlBytecodeExpr bytecode) {
exists(Call parent_call, XmlBytecodeCall parent_bytecode_call |
parent_call
.getLocation()
.hasLocationInfo(this.get_filename_data(), this.get_linenum_data(), _, _, _) and
@@ -78,13 +87,13 @@ class XMLCall extends XMLElement {
parent_bytecode_call.getAChild*() = bytecode
) and
(
expr.(Name).getId() = bytecode.(XMLBytecodeVariableName).get_name_data()
expr.(Name).getId() = bytecode.(XmlBytecodeVariableName).get_name_data()
or
expr.(Attribute).getName() = bytecode.(XMLBytecodeAttribute).get_attr_name_data() and
expr.(Attribute).getName() = bytecode.(XmlBytecodeAttribute).get_attr_name_data() and
matchBytecodeExpr(expr.(Attribute).getObject(),
bytecode.(XMLBytecodeAttribute).get_object_data())
bytecode.(XmlBytecodeAttribute).get_object_data())
or
matchBytecodeExpr(expr.(Call).getFunc(), bytecode.(XMLBytecodeCall).get_function_data())
matchBytecodeExpr(expr.(Call).getFunc(), bytecode.(XmlBytecodeCall).get_function_data())
//
// I considered allowing a partial match as well. That is, if the bytecode
// expression information only tells us `<unknown>.foo()`, and we find an AST
@@ -101,12 +110,18 @@ class XMLCall extends XMLElement {
}
}
/** DEPRECATED: Alias for XmlCall */
deprecated class XMLCall = XmlCall;
/** The XML data for the callee part a recorded call. */
abstract class XMLCallee extends XMLElement { }
abstract class XmlCallee extends XMLElement { }
/** DEPRECATED: Alias for XmlCallee */
deprecated class XMLCallee = XmlCallee;
/** The XML data for the callee part a recorded call, when the callee is a Python function. */
class XMLPythonCallee extends XMLCallee {
XMLPythonCallee() { this.hasName("PythonCallee") }
class XmlPythonCallee extends XmlCallee {
XmlPythonCallee() { this.hasName("PythonCallee") }
string get_filename_data() { result = this.getAChild("filename").getTextValue() }
@@ -125,9 +140,12 @@ class XMLPythonCallee extends XMLCallee {
}
}
/** DEPRECATED: Alias for XmlPythonCallee */
deprecated class XMLPythonCallee = XmlPythonCallee;
/** The XML data for the callee part a recorded call, when the callee is a C function or builtin. */
class XMLExternalCallee extends XMLCallee {
XMLExternalCallee() { this.hasName("ExternalCallee") }
class XmlExternalCallee extends XmlCallee {
XmlExternalCallee() { this.hasName("ExternalCallee") }
string get_module_data() { result = this.getAChild("module").getTextValue() }
@@ -143,6 +161,9 @@ class XMLExternalCallee extends XMLCallee {
}
}
/** DEPRECATED: Alias for XmlExternalCallee */
deprecated class XMLExternalCallee = XmlExternalCallee;
/**
* Helper predicate. If parent = `builtins` and qualname = `list.append`, it will
* return the result of `builtins.list.append`.class
@@ -164,7 +185,7 @@ private Builtin traverse_qualname(Builtin parent, string qualname) {
/**
* A recorded call where we can identify both the `call` and the `callee` uniquely.
*/
class IdentifiedRecordedCall extends XMLRecordedCall {
class IdentifiedRecordedCall extends XmlRecordedCall {
IdentifiedRecordedCall() {
strictcount(this.getACall()) = 1 and
(
@@ -182,7 +203,7 @@ class IdentifiedRecordedCall extends XMLRecordedCall {
// is not recorded, we would still mark the other two recorded calls as valid
// (which is not following the rules above). + 1 to count `this` as well.
strictcount(this.getACall()) = strictcount(this.getOtherWithSameSetOfCalls()) + 1 and
forex(XMLRecordedCall rc | rc = this.getOtherWithSameSetOfCalls() |
forex(XmlRecordedCall rc | rc = this.getOtherWithSameSetOfCalls() |
unique(Function f | f = this.getAPythonCallee()) =
unique(Function f | f = rc.getAPythonCallee())
or
@@ -214,7 +235,7 @@ class IdentifiedRecordedCall extends XMLRecordedCall {
/**
* A recorded call where we cannot identify both the `call` and the `callee` uniquely.
*/
class UnidentifiedRecordedCall extends XMLRecordedCall {
class UnidentifiedRecordedCall extends XmlRecordedCall {
UnidentifiedRecordedCall() { not this instanceof IdentifiedRecordedCall }
}
@@ -222,10 +243,10 @@ class UnidentifiedRecordedCall extends XMLRecordedCall {
* A Recorded call made from outside the project folder. These can be ignored when evaluating
* call-graph quality.
*/
class IgnoredRecordedCall extends XMLRecordedCall {
class IgnoredRecordedCall extends XmlRecordedCall {
IgnoredRecordedCall() {
not exists(
any(File file | file.getAbsolutePath() = this.getXMLCall().get_filename_data())
any(File file | file.getAbsolutePath() = this.getXmlCall().get_filename_data())
.getRelativePath()
)
}
@@ -238,28 +259,28 @@ module PointsToBasedCallGraph {
Value calleeValue;
ResolvableRecordedCall() {
exists(Call call, XMLCallee xmlCallee |
exists(Call call, XmlCallee xmlCallee |
call = this.getACall() and
calleeValue.getACall() = call.getAFlowNode() and
xmlCallee = this.getXMLCallee() and
xmlCallee = this.getXmlCallee() and
(
xmlCallee instanceof XMLPythonCallee and
xmlCallee instanceof XmlPythonCallee and
(
// normal function
calleeValue.(PythonFunctionValue).getScope() = xmlCallee.(XMLPythonCallee).getACallee()
calleeValue.(PythonFunctionValue).getScope() = xmlCallee.(XmlPythonCallee).getACallee()
or
// class instantiation -- points-to says the call goes to the class
calleeValue.(ClassValue).lookup("__init__").(PythonFunctionValue).getScope() =
xmlCallee.(XMLPythonCallee).getACallee()
xmlCallee.(XmlPythonCallee).getACallee()
)
or
xmlCallee instanceof XMLExternalCallee and
xmlCallee instanceof XmlExternalCallee and
calleeValue.(BuiltinFunctionObjectInternal).getBuiltin() =
xmlCallee.(XMLExternalCallee).getACallee()
xmlCallee.(XmlExternalCallee).getACallee()
or
xmlCallee instanceof XMLExternalCallee and
xmlCallee instanceof XmlExternalCallee and
calleeValue.(BuiltinMethodObjectInternal).getBuiltin() =
xmlCallee.(XMLExternalCallee).getACallee()
xmlCallee.(XmlExternalCallee).getACallee()
)
)
}

View File

@@ -7,7 +7,7 @@ import lib.RecordedCalls
from string text, float number, float ratio
where
exists(int all_rcs | all_rcs = count(XMLRecordedCall rc) and ratio = number / all_rcs |
exists(int all_rcs | all_rcs = count(XmlRecordedCall rc) and ratio = number / all_rcs |
text = "XMLRecordedCall" and number = all_rcs
or
text = "IdentifiedRecordedCall" and number = count(IdentifiedRecordedCall rc)

View File

@@ -3,7 +3,7 @@ import lib.RecordedCalls
// column i is just used for sorting
from string text, float number, float ratio, int i
where
exists(int all_rcs | all_rcs = count(XMLRecordedCall rc) and ratio = number / all_rcs |
exists(int all_rcs | all_rcs = count(XmlRecordedCall rc) and ratio = number / all_rcs |
text = "XMLRecordedCall" and number = all_rcs and i = 0
or
text = "IgnoredRecordedCall" and number = count(IgnoredRecordedCall rc) and i = 1
@@ -17,7 +17,7 @@ where
i = 10
or
exists(int all_not_ignored_rcs |
all_not_ignored_rcs = count(XMLRecordedCall rc | not rc instanceof IgnoredRecordedCall) and
all_not_ignored_rcs = count(XmlRecordedCall rc | not rc instanceof IgnoredRecordedCall) and
ratio = number / all_not_ignored_rcs
|
text = "IdentifiedRecordedCall" and

View File

@@ -4,6 +4,6 @@ import lib.RecordedCalls
// Could be useful for deciding which new opcodes to support
from string op_name, int c
where
exists(XMLBytecodeUnknown unknown | unknown.get_opname_data() = op_name) and
c = count(XMLBytecodeUnknown unknown | unknown.get_opname_data() = op_name | 1)
exists(XmlBytecodeUnknown unknown | unknown.get_opname_data() = op_name) and
c = count(XmlBytecodeUnknown unknown | unknown.get_opname_data() = op_name | 1)
select op_name, c order by c