mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python: Proper models of flask MethodView classes
This commit is contained in:
@@ -256,6 +256,27 @@ private module FlaskModel {
|
||||
/** Gets a reference to the `flask.views.View` class or any subclass. */
|
||||
DataFlow::Node subclassRef() { result = subclassRef(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides models for the `flask.views.MethodView` class and subclasses.
|
||||
*
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/views/#method-based-dispatching.
|
||||
*/
|
||||
module MethodView {
|
||||
/** Gets a reference to the `flask.views.View` class or any subclass. */
|
||||
private DataFlow::Node subclassRef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = views_attr("MethodView")
|
||||
or
|
||||
// subclasses in project code
|
||||
result.asExpr().(ClassExpr).getABase() = subclassRef(t.continue()).asExpr()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = subclassRef(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `flask.views.View` class or any subclass. */
|
||||
DataFlow::Node subclassRef() { result = subclassRef(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +398,19 @@ private module FlaskModel {
|
||||
DataFlow::Node asViewResult() { result = asViewResult(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
class FlaskMethodViewClassDef extends FlaskViewClassDef {
|
||||
FlaskMethodViewClassDef() { this.getABase() = flask::views::MethodView::subclassRef().asExpr() }
|
||||
|
||||
override Function getARequestHandler() {
|
||||
result = super.getARequestHandler()
|
||||
or
|
||||
// TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with
|
||||
// points-to and `.lookup`, which would handle `post = my_post_handler` inside class def
|
||||
result = this.getAMethod() and
|
||||
result.getName() = HTTP::httpVerbLower()
|
||||
}
|
||||
}
|
||||
|
||||
private string werkzeug_rule_re() {
|
||||
// since flask uses werkzeug internally, we are using its routing rules from
|
||||
// https://github.com/pallets/werkzeug/blob/4dc8d6ab840d4b78cbd5789cef91b01e3bde01d5/src/werkzeug/routing.py#L138-L151
|
||||
|
||||
@@ -11,7 +11,7 @@ from flask.views import MethodView
|
||||
|
||||
class MyView(MethodView):
|
||||
|
||||
def get(self, user_id): # $ MISSING: requestHandler
|
||||
def get(self, user_id): # $ requestHandler
|
||||
if user_id is None:
|
||||
# return a list of users
|
||||
pass
|
||||
|
||||
@@ -59,7 +59,7 @@ from flask.views import MethodView
|
||||
|
||||
class UserAPI(MethodView):
|
||||
|
||||
def get(self, user_id): # $ MISSING: requestHandler routedParameter=user_id
|
||||
def get(self, user_id): # $ requestHandler routedParameter=user_id
|
||||
if user_id is None:
|
||||
# return a list of users
|
||||
pass
|
||||
@@ -67,15 +67,15 @@ class UserAPI(MethodView):
|
||||
# expose a single user
|
||||
pass
|
||||
|
||||
def post(self): # $ MISSING: requestHandler
|
||||
def post(self): # $ requestHandler
|
||||
# create a new user
|
||||
pass
|
||||
|
||||
def delete(self, user_id): # $ MISSING: requestHandler routedParameter=user_id
|
||||
def delete(self, user_id): # $ requestHandler routedParameter=user_id
|
||||
# delete a single user
|
||||
pass
|
||||
|
||||
def put(self, user_id): # $ MISSING: requestHandler routedParameter=user_id
|
||||
def put(self, user_id): # $ requestHandler routedParameter=user_id
|
||||
# update a single user
|
||||
pass
|
||||
|
||||
@@ -89,7 +89,7 @@ app.add_url_rule("/users/<int:user_id>", view_func=user_view, methods=["GET", "P
|
||||
class WithoutKnownRoute2(MethodView):
|
||||
# For handler without known route, treat all parameters as routed parameters
|
||||
# (accepting that there might be a few FPs)
|
||||
def get(self, foo, not_routed=42): # $ MISSING: requestHandler routedParameter=foo
|
||||
def get(self, foo, not_routed=42): # $ requestHandler routedParameter=foo SPURIOUS: routedParameter=not_routed
|
||||
pass
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user