diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index 73c016ed927..ed0c7e6f22e 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -12,6 +12,7 @@ private import semmle.python.ApiGraphs private import semmle.python.regex private import semmle.python.frameworks.Stdlib private import semmle.python.frameworks.internal.InstanceTaintStepsHelper +private import semmle.python.frameworks.data.ModelsAsData /** * INTERNAL: Do not use. @@ -87,7 +88,11 @@ module Tornado { */ module RequestHandler { /** Gets a reference to the `tornado.web.RequestHandler` class or any subclass. */ - API::Node subclassRef() { result = web().getMember("RequestHandler").getASubclass*() } + API::Node subclassRef() { + result = web().getMember("RequestHandler").getASubclass*() + or + result = ModelOutput::getATypeNode("tornado.web.RequestHandler~Subclass").getASubclass*() + } /** A RequestHandler class (most likely in project code). */ class RequestHandlerClass extends Class { diff --git a/python/ql/src/meta/ClassHierarchy/Find.ql b/python/ql/src/meta/ClassHierarchy/Find.ql index 176091d0f5a..9fc62b68c1e 100644 --- a/python/ql/src/meta/ClassHierarchy/Find.ql +++ b/python/ql/src/meta/ClassHierarchy/Find.ql @@ -11,6 +11,7 @@ import semmle.python.frameworks.internal.SubclassFinder::NotExposed private import semmle.python.frameworks.Flask private import semmle.python.frameworks.FastApi private import semmle.python.frameworks.Django +private import semmle.python.frameworks.Tornado import semmle.python.frameworks.data.internal.ApiGraphModelsExtensions as Extensions class FlaskViewClasses extends FindSubclassesSpec { @@ -57,6 +58,14 @@ class DjangoField extends FindSubclassesSpec { } } +class TornadoRequestHandler extends FindSubclassesSpec { + TornadoRequestHandler() { this = "tornado.web.RequestHandler~Subclass" } + + override API::Node getAlreadyModeledClass() { + result = Tornado::TornadoModule::Web::RequestHandler::subclassRef() + } +} + bindingset[fullyQualified] predicate fullyQualifiedToYamlFormat(string fullyQualified, string type2, string path) { exists(int firstDot | firstDot = fullyQualified.indexOf(".", 0, 0) |