mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Python: Add initial rest_framework modeling
I had to make the Django and PrivateDjango modeling non-private :O
This commit is contained in:
@@ -155,6 +155,7 @@ Python built-in support
|
||||
Name, Category
|
||||
aiohttp.web, Web framework
|
||||
Django, Web framework
|
||||
djangorestframework, Web framework
|
||||
Flask, Web framework
|
||||
Tornado, Web framework
|
||||
Twisted, Web framework
|
||||
|
||||
@@ -25,6 +25,7 @@ private import semmle.python.frameworks.MySQLdb
|
||||
private import semmle.python.frameworks.Peewee
|
||||
private import semmle.python.frameworks.Psycopg2
|
||||
private import semmle.python.frameworks.PyMySQL
|
||||
private import semmle.python.frameworks.RestFramework
|
||||
private import semmle.python.frameworks.Rsa
|
||||
private import semmle.python.frameworks.RuamelYaml
|
||||
private import semmle.python.frameworks.Simplejson
|
||||
|
||||
@@ -17,10 +17,12 @@ private import semmle.python.frameworks.internal.SelfRefMixin
|
||||
private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides models for the `django` PyPI package.
|
||||
* See https://www.djangoproject.com/.
|
||||
*/
|
||||
private module Django {
|
||||
module Django {
|
||||
/** Provides models for the `django.views` module */
|
||||
module Views {
|
||||
/**
|
||||
@@ -466,10 +468,12 @@ private module Django {
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides models for the `django` PyPI package (that we are not quite ready to publicly expose yet).
|
||||
* See https://www.djangoproject.com/.
|
||||
*/
|
||||
private module PrivateDjango {
|
||||
module PrivateDjango {
|
||||
// ---------------------------------------------------------------------------
|
||||
// django
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
68
python/ql/lib/semmle/python/frameworks/RestFramework.qll
Normal file
68
python/ql/lib/semmle/python/frameworks/RestFramework.qll
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `djangorestframework` PyPI package
|
||||
* (imported as `rest_framework`)
|
||||
*
|
||||
* See
|
||||
* - https://www.django-rest-framework.org/
|
||||
* - https://pypi.org/project/djangorestframework/
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
|
||||
private import semmle.python.frameworks.Django
|
||||
private import semmle.python.frameworks.Stdlib
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides models for the `djangorestframework` PyPI package
|
||||
* (imported as `rest_framework`)
|
||||
*
|
||||
* See
|
||||
* - https://www.django-rest-framework.org/
|
||||
* - https://pypi.org/project/djangorestframework/
|
||||
*/
|
||||
private module RestFramework {
|
||||
/**
|
||||
* An `API::Node` representing the `rest_framework.views.APIView` class or any subclass
|
||||
* that has explicitly been modeled in the CodeQL libraries.
|
||||
*/
|
||||
private class ModeledApiViewClasses extends Django::Views::View::ModeledSubclass {
|
||||
ModeledApiViewClasses() {
|
||||
this = API::moduleImport("rest_framework").getMember("views").getMember("APIView")
|
||||
// TODO: Need to model all known subclasses
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that has a super-type which is a rest_framework APIView class, therefore also
|
||||
* becoming a APIView class.
|
||||
*/
|
||||
class RestFrameworkApiViewClass extends PrivateDjango::DjangoViewClassFromSuperClass {
|
||||
RestFrameworkApiViewClass() {
|
||||
this.getABase() = any(ModeledApiViewClasses c).getASubclass*().getAUse().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() in [
|
||||
// these method names where found by looking through the APIView
|
||||
// implementation in
|
||||
// https://github.com/encode/django-rest-framework/blob/master/rest_framework/views.py#L104
|
||||
"initial", "http_method_not_allowed", "permission_denied", "throttled",
|
||||
"get_authenticate_header", "perform_content_negotiation", "perform_authentication",
|
||||
"check_permissions", "check_object_permissions", "check_throttles", "determine_version",
|
||||
"initialize_request", "finalize_response", "dispatch", "options"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,9 +89,9 @@ def test_taint(request: Request, routed_param): # $ requestHandler routedParamet
|
||||
|
||||
|
||||
class MyClass(APIView):
|
||||
def initial(self, request, *args, **kwargs):
|
||||
def initial(self, request, *args, **kwargs): # $ requestHandler
|
||||
# this method will be called before processing any request
|
||||
ensure_tainted(request) # $ MISSING: tainted
|
||||
ensure_tainted(request) # $ tainted
|
||||
|
||||
def get(self, request: Request, routed_param): # $ requestHandler routedParameter=routed_param
|
||||
ensure_tainted(routed_param) # $ tainted
|
||||
@@ -124,5 +124,5 @@ def function_based_no_route(request: Request, possible_routed_param):
|
||||
|
||||
|
||||
class ClassBasedNoRoute(APIView):
|
||||
def get(self, request: Request, possible_routed_param):
|
||||
ensure_tainted(request, possible_routed_param) # $ MISSING: tainted
|
||||
def get(self, request: Request, possible_routed_param): # $ requestHandler routedParameter=possible_routed_param
|
||||
ensure_tainted(request, possible_routed_param) # $ tainted
|
||||
|
||||
Reference in New Issue
Block a user