Add pyramid models

This commit is contained in:
Joe Farebrother
2024-04-22 13:27:18 +01:00
parent 75b1e14098
commit 88e3227ed0
5 changed files with 115 additions and 0 deletions

View File

@@ -56,6 +56,7 @@ private import semmle.python.frameworks.PyMongo
private import semmle.python.frameworks.Pymssql
private import semmle.python.frameworks.PyMySQL
private import semmle.python.frameworks.Pyodbc
private import semmle.python.frameworks.Pyramid
private import semmle.python.frameworks.Requests
private import semmle.python.frameworks.RestFramework
private import semmle.python.frameworks.Rsa

View File

@@ -0,0 +1,87 @@
/**
* Provides classes modeling security-relevant aspects of the `pyramid` PyPI package.
* See https://docs.pylonsproject.org/projects/pyramid/.
*/
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.dataflow.new.FlowSummary
private import semmle.python.frameworks.internal.PoorMansFunctionResolution
private import semmle.python.frameworks.data.ModelsAsData
/**
* Provides models for the `pyramid` PyPI package.
* See https://docs.pylonsproject.org/projects/pyramid/.
*/
module Pyramid {
// TODO: qldoc
module View {
/**
* A callable that could be used as a pyramid view callable.
*/
private class PotentialViewCallable extends Function {
PotentialViewCallable() {
this.getPositionalParameterCount() = 1 and
this.getArgName(0) = "request"
or
this.getPositionalParameterCount() = 2 and
this.getArgName(0) = "context" and
this.getArgName(1) = "request"
}
/** Gets the `request` parameter of this view callable. */
Parameter getRequestParameter() { result = this.getArgByName("request") }
}
abstract class ViewCallable extends PotentialViewCallable, Http::Server::RequestHandler::Range {
override Parameter getARoutedParameter() { result = this.getRequestParameter() }
override string getFramework() { result = "Pyramid" }
}
private class ViewCallableFromDecorator extends ViewCallable {
ViewCallableFromDecorator() {
this.getADecorator() =
API::moduleImport("pyramid")
.getMember("view")
.getMember("view_config")
.getACall()
.asExpr()
}
}
private class ViewCallableFromConfigurator extends ViewCallable {
ViewCallableFromConfigurator() {
any(Configurator::AddViewCall c).getViewArg() = poorMansFunctionTracker(this)
}
}
}
module Configurator {
/** Gets a reference to the class `pyramid.config.Configurator`. */
API::Node classRef() {
result = API::moduleImport("pyramid").getMember("config").getMember("Configurator")
}
/** Gets a reference to an instance of `pyramid.config.Configurator`. */
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result = classRef().getACall()
or
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
}
/** Gets a reference to an instance of `pyramid.config.Configurator`. */
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
class AddViewCall extends DataFlow::MethodCallNode {
AddViewCall() { this.calls(instance(), "add_view") }
DataFlow::Node getViewArg() { result = [this.getArg(0), this.getArgByName("view")] }
}
}
}

View File

@@ -0,0 +1,4 @@
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
failures

View File

@@ -0,0 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

@@ -0,0 +1,21 @@
from pyramid.view import view_config
from pyramid.config import Configurator
@view_config(route_name="test1")
def test1(request):
ensure_tainted(
request, # $ tainted
request.body, # $ MISSING:tainted
request.GET['a'] # $ MISSING:tainted
)
def test2(request):
ensure_tainted(request) # $ tainted
@view_config(route_name="test1")
def test3(context, request):
ensure_tainted(request) # $ tainted
if __name__ == "__main__":
with Configurator() as config:
config.add_view(test2, route_name="test2")