mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
Python: Autoformat web.
This commit is contained in:
@@ -4,15 +4,13 @@ import semmle.python.security.strings.External
|
||||
import HttpConstants
|
||||
|
||||
/** Generic taint source from a http request */
|
||||
abstract class HttpRequestTaintSource extends TaintSource {
|
||||
abstract class HttpRequestTaintSource extends TaintSource { }
|
||||
|
||||
}
|
||||
|
||||
/** Taint kind representing the WSGI environment.
|
||||
/**
|
||||
* Taint kind representing the WSGI environment.
|
||||
* As specified in PEP 3333. https://www.python.org/dev/peps/pep-3333/#environ-variables
|
||||
*/
|
||||
class WsgiEnvironment extends TaintKind {
|
||||
|
||||
WsgiEnvironment() { this = "wsgi.environment" }
|
||||
|
||||
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
|
||||
@@ -26,10 +24,12 @@ class WsgiEnvironment extends TaintKind {
|
||||
tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode and
|
||||
tonode.(CallNode).getArg(0).pointsTo(key)
|
||||
or
|
||||
tonode.(SubscriptNode).getObject() = fromnode and tonode.isLoad() and
|
||||
tonode.(SubscriptNode).getObject() = fromnode and
|
||||
tonode.isLoad() and
|
||||
tonode.(SubscriptNode).getIndex().pointsTo(key)
|
||||
|
|
||||
key = Value::forString(text) and result instanceof ExternalStringKind and
|
||||
|
|
||||
key = Value::forString(text) and
|
||||
result instanceof ExternalStringKind and
|
||||
(
|
||||
text = "QUERY_STRING" or
|
||||
text = "PATH_INFO" or
|
||||
@@ -37,96 +37,73 @@ class WsgiEnvironment extends TaintKind {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** A standard morsel object from a HTTP request, a value in a cookie,
|
||||
* typically an instance of `http.cookies.Morsel` */
|
||||
/**
|
||||
* A standard morsel object from a HTTP request, a value in a cookie,
|
||||
* typically an instance of `http.cookies.Morsel`
|
||||
*/
|
||||
class UntrustedMorsel extends TaintKind {
|
||||
|
||||
UntrustedMorsel() {
|
||||
this = "http.Morsel"
|
||||
}
|
||||
|
||||
UntrustedMorsel() { this = "http.Morsel" }
|
||||
|
||||
override TaintKind getTaintOfAttribute(string name) {
|
||||
result instanceof ExternalStringKind and
|
||||
(
|
||||
name = "value"
|
||||
)
|
||||
name = "value"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** A standard cookie object from a HTTP request, typically an instance of `http.cookies.SimpleCookie` */
|
||||
class UntrustedCookie extends TaintKind {
|
||||
|
||||
UntrustedCookie() {
|
||||
this = "http.Cookie"
|
||||
}
|
||||
UntrustedCookie() { this = "http.Cookie" }
|
||||
|
||||
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
|
||||
tonode.(SubscriptNode).getObject() = fromnode and
|
||||
result instanceof UntrustedMorsel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class CookieOperation extends @py_flow_node {
|
||||
|
||||
abstract string toString();
|
||||
|
||||
abstract ControlFlowNode getKey();
|
||||
|
||||
abstract ControlFlowNode getValue();
|
||||
|
||||
}
|
||||
|
||||
abstract class CookieGet extends CookieOperation {}
|
||||
abstract class CookieGet extends CookieOperation { }
|
||||
|
||||
abstract class CookieSet extends CookieOperation {}
|
||||
abstract class CookieSet extends CookieOperation { }
|
||||
|
||||
/** Generic taint sink in a http response */
|
||||
abstract class HttpResponseTaintSink extends TaintSink {
|
||||
|
||||
override predicate sinks(TaintKind kind) {
|
||||
kind instanceof ExternalStringKind
|
||||
}
|
||||
|
||||
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
|
||||
}
|
||||
|
||||
abstract class HttpRedirectTaintSink extends TaintSink {
|
||||
|
||||
override predicate sinks(TaintKind kind) {
|
||||
kind instanceof ExternalStringKind
|
||||
}
|
||||
|
||||
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
|
||||
}
|
||||
|
||||
module Client {
|
||||
|
||||
// TODO: user-input in other than URL:
|
||||
// - `data`, `json` for `requests.post`
|
||||
// - `body` for `HTTPConnection.request`
|
||||
// - headers?
|
||||
|
||||
// TODO: Add more library support
|
||||
// - urllib3 https://github.com/urllib3/urllib3
|
||||
// - httpx https://github.com/encode/httpx
|
||||
|
||||
/**
|
||||
* An outgoing http request
|
||||
*
|
||||
* For example:
|
||||
* conn = HTTPConnection('example.com')
|
||||
conn.request('GET', '/path')
|
||||
*/
|
||||
* An outgoing http request
|
||||
*
|
||||
* For example:
|
||||
* conn = HTTPConnection('example.com')
|
||||
* conn.request('GET', '/path')
|
||||
*/
|
||||
abstract class HttpRequest extends ControlFlowNode {
|
||||
|
||||
/** Get any ControlFlowNode that is used to construct the final URL.
|
||||
*
|
||||
* In the HTTPConnection example, there is a result for both `'example.com'` and for `'/path'`.
|
||||
*/
|
||||
/**
|
||||
* Get any ControlFlowNode that is used to construct the final URL.
|
||||
*
|
||||
* In the HTTPConnection example, there is a result for both `'example.com'` and for `'/path'`.
|
||||
*/
|
||||
abstract ControlFlowNode getAUrlPart();
|
||||
|
||||
abstract string getMethodUpper();
|
||||
@@ -134,14 +111,8 @@ module Client {
|
||||
|
||||
/** Taint sink for the URL-part of an outgoing http request */
|
||||
class HttpRequestUrlTaintSink extends TaintSink {
|
||||
HttpRequestUrlTaintSink() { this = any(HttpRequest r).getAUrlPart() }
|
||||
|
||||
HttpRequestUrlTaintSink() {
|
||||
this = any(HttpRequest r).getAUrlPart()
|
||||
}
|
||||
|
||||
override predicate sinks(TaintKind kind) {
|
||||
kind instanceof ExternalStringKind
|
||||
}
|
||||
|
||||
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
/** Gets an http verb */
|
||||
string httpVerb() {
|
||||
result = "GET" or result = "POST" or
|
||||
result = "PUT" or result = "PATCH" or
|
||||
result = "DELETE" or result = "OPTIONS" or
|
||||
result = "GET" or
|
||||
result = "POST" or
|
||||
result = "PUT" or
|
||||
result = "PATCH" or
|
||||
result = "DELETE" or
|
||||
result = "OPTIONS" or
|
||||
result = "HEAD"
|
||||
}
|
||||
|
||||
/** Gets an http verb, in lower case */
|
||||
string httpVerbLower() {
|
||||
result = httpVerb().toLowerCase()
|
||||
}
|
||||
string httpVerbLower() { result = httpVerb().toLowerCase() }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import python
|
||||
|
||||
import semmle.python.security.strings.Basic
|
||||
|
||||
import semmle.python.web.django.Redirect
|
||||
import semmle.python.web.flask.Redirect
|
||||
import semmle.python.web.tornado.Redirect
|
||||
|
||||
@@ -27,9 +27,9 @@ class DjangoRoute extends CallNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of positional arguments that will be passed to the view.
|
||||
* Will only return a result if there are no named arguments.
|
||||
*/
|
||||
* Get the number of positional arguments that will be passed to the view.
|
||||
* Will only return a result if there are no named arguments.
|
||||
*/
|
||||
int getNumPositionalArguments() {
|
||||
exists(DjangoRouteRegex regex |
|
||||
django_route(this, regex.getAFlowNode(), _) and
|
||||
|
||||
@@ -79,14 +79,13 @@ class DjangoClassBasedViewRequestArgument extends DjangoRequestSource {
|
||||
/** An argument specified in a url routing table */
|
||||
class DjangoRequestParameter extends HttpRequestTaintSource {
|
||||
DjangoRequestParameter() {
|
||||
exists(DjangoRoute route, Function f |
|
||||
f = route.getViewFunction().getScope() |
|
||||
exists(DjangoRoute route, Function f | f = route.getViewFunction().getScope() |
|
||||
this.(ControlFlowNode).getNode() = f.getArgByName(route.getNamedArgument())
|
||||
or
|
||||
exists(int i | i >= 0 |
|
||||
i < route.getNumPositionalArguments() and
|
||||
// +1 because first argument is always the request
|
||||
this.(ControlFlowNode).getNode() = f.getArg(i+1)
|
||||
this.(ControlFlowNode).getNode() = f.getArg(i + 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ ClassValue theFalconAPIClass() { result = Value::named("falcon.API") }
|
||||
|
||||
/** Holds if `route` is routed to `resource` */
|
||||
private predicate api_route(CallNode route_call, ControlFlowNode route, ClassValue resource) {
|
||||
route_call.getFunction().(AttrNode).getObject("add_route").pointsTo().getClass() = theFalconAPIClass() and
|
||||
route_call.getFunction().(AttrNode).getObject("add_route").pointsTo().getClass() =
|
||||
theFalconAPIClass() and
|
||||
route_call.getArg(0) = route and
|
||||
route_call.getArg(1).pointsTo().getClass() = resource
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ predicate isTornadoRequestHandlerInstance(ControlFlowNode node) {
|
||||
node.pointsTo().getClass() = aTornadoRequestHandlerClass()
|
||||
or
|
||||
/*
|
||||
* In some cases, the points-to analysis won't capture all instances we care
|
||||
* about. For these, we use the following syntactic check. First, that
|
||||
* `node` appears inside a method of a subclass of
|
||||
* `tornado.web.RequestHandler`:
|
||||
*/
|
||||
* In some cases, the points-to analysis won't capture all instances we care
|
||||
* about. For these, we use the following syntactic check. First, that
|
||||
* `node` appears inside a method of a subclass of
|
||||
* `tornado.web.RequestHandler`:
|
||||
*/
|
||||
|
||||
node.getScope().getEnclosingScope() = aTornadoRequestHandlerClass().getScope() and
|
||||
/* Secondly, that `node` refers to the `self` argument: */
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import python
|
||||
|
||||
import semmle.python.security.TaintTracking
|
||||
import semmle.python.web.Http
|
||||
|
||||
abstract class BaseWebobRequest extends TaintKind {
|
||||
|
||||
bindingset[this]
|
||||
BaseWebobRequest() { any() }
|
||||
|
||||
@@ -17,9 +15,7 @@ abstract class BaseWebobRequest extends TaintKind {
|
||||
)
|
||||
or
|
||||
result instanceof ExternalStringKind and
|
||||
(
|
||||
name = "body"
|
||||
)
|
||||
name = "body"
|
||||
}
|
||||
|
||||
override TaintKind getTaintOfMethodResult(string name) {
|
||||
@@ -30,22 +26,13 @@ abstract class BaseWebobRequest extends TaintKind {
|
||||
name = "copy_body"
|
||||
)
|
||||
or
|
||||
result instanceof ExternalStringKind and
|
||||
(
|
||||
name = "as_bytes"
|
||||
)
|
||||
result instanceof ExternalStringKind and
|
||||
name = "as_bytes"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WebobRequest extends BaseWebobRequest {
|
||||
WebobRequest() { this = "webob.Request" }
|
||||
|
||||
WebobRequest() {
|
||||
this = "webob.Request"
|
||||
}
|
||||
|
||||
override ClassValue getType() {
|
||||
result = Value::named("webob.request.Request")
|
||||
}
|
||||
|
||||
override ClassValue getType() { result = Value::named("webob.request.Request") }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user