mirror of
https://github.com/github/codeql.git
synced 2025-12-21 03:06:31 +01:00
Add instance taint steps for requests
This commit is contained in:
@@ -11,6 +11,7 @@ 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.internal.InstanceTaintStepsHelper
|
||||
private import semmle.python.frameworks.data.ModelsAsData
|
||||
|
||||
/**
|
||||
@@ -84,4 +85,47 @@ module Pyramid {
|
||||
DataFlow::Node getViewArg() { result = [this.getArg(0), this.getArgByName("view")] }
|
||||
}
|
||||
}
|
||||
|
||||
module Request {
|
||||
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
|
||||
|
||||
/** Gets a reference to an instance of `pyramid.request.Request`. */
|
||||
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result instanceof InstanceSource
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to an instance of `pyramid.request.Request`. */
|
||||
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
|
||||
|
||||
private class RequestParameter extends InstanceSource, DataFlow::ParameterNode {
|
||||
RequestParameter() { this.getParameter() = any(View::ViewCallable vc).getRequestParameter() }
|
||||
}
|
||||
|
||||
private class InstanceTaintSteps extends InstanceTaintStepsHelper {
|
||||
InstanceTaintSteps() { this = "pyramid.request.Request" }
|
||||
|
||||
override DataFlow::Node getInstance() { result = instance() }
|
||||
|
||||
override string getAttributeName() {
|
||||
result in [
|
||||
"accept", "accept_charset", "accept_encoding", "accept_language", "application_url",
|
||||
"as_bytes", "authorization", "body", "body_file", "body_file_raw", "body_file_seekable",
|
||||
"cache_control", "client_addr", "content_type", "cookies", "domain", "headers", "host",
|
||||
"host_port", "host_url", "GET", "if_match", "if_none_match", "if_range",
|
||||
"if_none_match", "json", "json_body", "params", "path", "path_info", "path_qs",
|
||||
"path_url", "POST", "pragma", "query_string", "range", "referer", "referrer", "text",
|
||||
"url", "urlargs", "urlvars", "user_agent"
|
||||
]
|
||||
}
|
||||
|
||||
override string getMethodName() {
|
||||
result in ["as_bytes", "copy", "copy_body", "copy_get", "path_info_peek", "path_info_pop"]
|
||||
}
|
||||
|
||||
override string getAsyncMethodName() { none() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,66 @@ 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
|
||||
request, # $ tainted
|
||||
|
||||
request.accept, # $ tainted
|
||||
request.accept_charset, # $ tainted
|
||||
request.accept_encoding, # $ tainted
|
||||
request.accept_language, # $ tainted
|
||||
request.authorization, # $ tainted
|
||||
request.cache_control, # $ tainted
|
||||
request.client_addr, # $ tainted
|
||||
request.content_type, # $ tainted
|
||||
request.domain, # $ tainted
|
||||
request.host, # $ tainted
|
||||
request.host_port, # $ tainted
|
||||
request.host_url, # $ tainted
|
||||
request.if_match, # $ tainted
|
||||
request.if_none_match, # $ tainted
|
||||
request.if_range, # $ tainted
|
||||
request.pragma, # $ tainted
|
||||
request.range, # $ tainted
|
||||
request.referer, # $ tainted
|
||||
request.referrer, # $ tainted
|
||||
request.user_agent, # $ tainted
|
||||
|
||||
request.as_bytes, # $ tainted
|
||||
|
||||
request.body, # $ tainted
|
||||
request.body_file, # $ tainted
|
||||
request.body_file_raw, # $ tainted
|
||||
request.body_file_seekable,# $ tainted
|
||||
request.body_file.read(), # $ MISSING:tainted
|
||||
|
||||
request.json, # $ tainted
|
||||
request.json_body, # $ tainted
|
||||
request.json['a']['b'][0]['c'], # $ tainted
|
||||
|
||||
request.text, # $ tainted
|
||||
|
||||
request.path, # $ tainted
|
||||
request.path_info, # $ tainted
|
||||
request.path_info_peek(), # $ tainted
|
||||
request.path_info_pop(), # $ tainted
|
||||
request.path_qs, # $ tainted
|
||||
request.path_url, # $ tainted
|
||||
request.query_string, # $ tainted
|
||||
|
||||
request.url, # $ tainted
|
||||
request.urlargs, # $ tainted
|
||||
request.urlvars, # $ tainted
|
||||
|
||||
request.GET['a'], # $ tainted
|
||||
request.POST['b'], # $ tainted
|
||||
request.cookies['c'], # $ tainted
|
||||
request.params['d'], # $ tainted
|
||||
request.headers['X-My-Header'], # $ tainted
|
||||
request.GET.values(), # $ tainted
|
||||
|
||||
request.copy(), # $ tainted
|
||||
request.copy_body(), # $ tainted
|
||||
request.copy_get(), # $ tainted
|
||||
request.copy().GET['a'] # $ MISSING:tainted
|
||||
)
|
||||
|
||||
def test2(request):
|
||||
|
||||
Reference in New Issue
Block a user