mirror of
https://github.com/github/codeql.git
synced 2026-03-17 04:56:58 +01:00
patch upper-case acronyms to be PascalCase
This commit is contained in:
@@ -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(_)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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) }
|
||||
|
||||
|
||||
@@ -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() |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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) }
|
||||
|
||||
|
||||
@@ -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")] }
|
||||
|
||||
|
||||
@@ -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) }
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user