mirror of
https://github.com/github/codeql.git
synced 2026-05-01 19:55:15 +02:00
Python: client request: getUrl => getAUrlPart
I think `getUrl` is a bit too misleading, since from the name, I would
only ever expect ONE result for one request being made.
`getAUrlPart` captures that there could be multiple results, and that
they might not constitute a whole URl.
Which is the same naming I used when I tried to model this a long time ago
a80860cdc6/python/ql/lib/semmle/python/web/Http.qll (L102-L111)
This commit is contained in:
@@ -829,7 +829,7 @@ module HTTP {
|
||||
* Gets a node that contributes to the URL of the request.
|
||||
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
|
||||
*/
|
||||
DataFlow::Node getUrl() { result = super.getUrl() }
|
||||
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
|
||||
|
||||
/** Gets a string that identifies the framework used for this request. */
|
||||
string getFramework() { result = super.getFramework() }
|
||||
@@ -864,7 +864,7 @@ module HTTP {
|
||||
* Gets a node that contributes to the URL of the request.
|
||||
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
|
||||
*/
|
||||
abstract DataFlow::Node getUrl();
|
||||
abstract DataFlow::Node getAUrlPart();
|
||||
|
||||
/** Gets a string that identifies the framework used for this request. */
|
||||
abstract string getFramework();
|
||||
@@ -888,7 +888,7 @@ module HTTP {
|
||||
private class HttpClientRequestAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
exists(Request req |
|
||||
nodeFrom = req.getUrl() and
|
||||
nodeFrom = req.getAUrlPart() and
|
||||
nodeTo = req.getResponse()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ private module Requests {
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() {
|
||||
override DataFlow::Node getAUrlPart() {
|
||||
result = this.getArgByName("url")
|
||||
or
|
||||
not methodName = "request" and
|
||||
|
||||
@@ -2179,7 +2179,7 @@ private module StdlibPrivate {
|
||||
this.getObject().getALocalSource()
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() {
|
||||
override DataFlow::Node getAUrlPart() {
|
||||
result in [this.getArg(1), this.getArgByName("url")]
|
||||
or
|
||||
this.getObject() = instance(result)
|
||||
|
||||
@@ -480,17 +480,17 @@ class HttpClientRequestTest extends InlineExpectationsTest {
|
||||
HttpClientRequestTest() { this = "HttpClientRequestTest" }
|
||||
|
||||
override string getARelevantTag() {
|
||||
result in ["clientRequestUrl", "clientRequestCertValidationDisabled"]
|
||||
result in ["clientRequestUrlPart", "clientRequestCertValidationDisabled"]
|
||||
}
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(HTTP::Client::Request req, DataFlow::Node url |
|
||||
url = req.getUrl() and
|
||||
url = req.getAUrlPart() and
|
||||
location = url.getLocation() and
|
||||
element = url.toString() and
|
||||
value = prettyNodeForInlineTest(url) and
|
||||
tag = "clientRequestUrl"
|
||||
tag = "clientRequestUrlPart"
|
||||
)
|
||||
or
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
|
||||
@@ -11,7 +11,7 @@ def test_taint(): # $ requestHandler
|
||||
|
||||
# response from a request to a user-controlled URL should be considered
|
||||
# user-controlled as well.
|
||||
resp = requests.get(url) # $ clientRequestUrl=url
|
||||
resp = requests.get(url) # $ clientRequestUrlPart=url
|
||||
|
||||
requests.Response
|
||||
requests.models.Response
|
||||
@@ -50,5 +50,5 @@ def test_taint(): # $ requestHandler
|
||||
# flow source, since this could lead to FPs.
|
||||
# TODO: investigate whether we should consider this a remote flow source.
|
||||
trusted_url = "https://internal-api-that-i-trust.com"
|
||||
resp = requests.get(trusted_url) # $ clientRequestUrl=trusted_url
|
||||
resp = requests.get(trusted_url) # $ clientRequestUrlPart=trusted_url
|
||||
ensure__not_tainted(resp)
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
import requests
|
||||
|
||||
resp = requests.get("url") # $ clientRequestUrl="url"
|
||||
resp = requests.get(url="url") # $ clientRequestUrl="url"
|
||||
resp = requests.get("url") # $ clientRequestUrlPart="url"
|
||||
resp = requests.get(url="url") # $ clientRequestUrlPart="url"
|
||||
|
||||
resp = requests.request("GET", "url") # $ clientRequestUrl="url"
|
||||
resp = requests.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
with requests.Session() as session:
|
||||
resp = session.get("url") # $ clientRequestUrl="url"
|
||||
resp = session.request(method="GET", url="url") # $ clientRequestUrl="url"
|
||||
resp = session.get("url") # $ clientRequestUrlPart="url"
|
||||
resp = session.request(method="GET", url="url") # $ clientRequestUrlPart="url"
|
||||
|
||||
s = requests.Session()
|
||||
resp = s.get("url") # $ clientRequestUrl="url"
|
||||
resp = s.get("url") # $ clientRequestUrlPart="url"
|
||||
|
||||
s = requests.session()
|
||||
resp = s.get("url") # $ clientRequestUrl="url"
|
||||
resp = s.get("url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# test full import path for Session
|
||||
with requests.sessions.Session() as session:
|
||||
resp = session.get("url") # $ clientRequestUrl="url"
|
||||
resp = session.get("url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# Low level access
|
||||
req = requests.Request("GET", "url") # $ MISSING: clientRequestUrl="url"
|
||||
req = requests.Request("GET", "url") # $ MISSING: clientRequestUrlPart="url"
|
||||
resp = s.send(req.prepare())
|
||||
|
||||
# other methods than GET
|
||||
resp = requests.post("url") # $ clientRequestUrl="url"
|
||||
resp = requests.patch("url") # $ clientRequestUrl="url"
|
||||
resp = requests.options("url") # $ clientRequestUrl="url"
|
||||
resp = requests.post("url") # $ clientRequestUrlPart="url"
|
||||
resp = requests.patch("url") # $ clientRequestUrlPart="url"
|
||||
resp = requests.options("url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# ==============================================================================
|
||||
# Disabling certificate validation
|
||||
# ==============================================================================
|
||||
|
||||
resp = requests.get("url", verify=False) # $ clientRequestUrl="url" clientRequestCertValidationDisabled
|
||||
resp = requests.get("url", verify=False) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
|
||||
|
||||
def make_get(verify_arg):
|
||||
resp = requests.get("url", verify=verify_arg) # $ clientRequestUrl="url" clientRequestCertValidationDisabled
|
||||
resp = requests.get("url", verify=verify_arg) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
|
||||
|
||||
make_get(False)
|
||||
|
||||
@@ -43,8 +43,8 @@ make_get(False)
|
||||
with requests.Session() as session:
|
||||
# see https://github.com/psf/requests/blob/39d0fdd9096f7dceccbc8f82e1eda7dd64717a8e/requests/sessions.py#L621
|
||||
session.verify = False
|
||||
resp = session.get("url") # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
|
||||
resp = session.get("url", verify=True) # $ clientRequestUrl="url"
|
||||
resp = session.get("url") # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
|
||||
resp = session.get("url", verify=True) # $ clientRequestUrlPart="url"
|
||||
|
||||
req = requests.Request("GET", "url") # $ MISSING: clientRequestUrl="url"
|
||||
req = requests.Request("GET", "url") # $ MISSING: clientRequestUrlPart="url"
|
||||
resp = session.send(req.prepare()) # $ MISSING: clientRequestCertValidationDisabled
|
||||
|
||||
@@ -11,35 +11,35 @@ if PY3:
|
||||
|
||||
|
||||
# NOTE: the URL may be relative to host, or may be full URL.
|
||||
conn = HTTPConnection("example.com") # $ clientRequestUrl="example.com"
|
||||
conn.request("GET", "/") # $ clientRequestUrl="/"
|
||||
conn = HTTPConnection("example.com") # $ clientRequestUrlPart="example.com"
|
||||
conn.request("GET", "/") # $ clientRequestUrlPart="/"
|
||||
url = "http://example.com/"
|
||||
conn.request("GET", url) # $ clientRequestUrl=url
|
||||
conn.request("GET", url) # $ clientRequestUrlPart=url
|
||||
|
||||
# kwargs
|
||||
conn = HTTPConnection(host="example.com") # $ clientRequestUrl="example.com"
|
||||
conn.request(method="GET", url="/") # $ clientRequestUrl="/"
|
||||
conn = HTTPConnection(host="example.com") # $ clientRequestUrlPart="example.com"
|
||||
conn.request(method="GET", url="/") # $ clientRequestUrlPart="/"
|
||||
|
||||
# using internal method... you shouldn't but you can
|
||||
conn._send_request("GET", "url", body=None, headers={}, encode_chunked=False) # $ clientRequestUrl="url"
|
||||
conn._send_request("GET", "url", body=None, headers={}, encode_chunked=False) # $ clientRequestUrlPart="url"
|
||||
|
||||
# low level sending of request
|
||||
conn.putrequest("GET", "url") # $ clientRequestUrl="url"
|
||||
conn.putrequest("GET", "url") # $ clientRequestUrlPart="url"
|
||||
conn.putheader("X-Foo", "value")
|
||||
conn.endheaders(message_body=None)
|
||||
|
||||
# HTTPS
|
||||
conn = HTTPSConnection("host") # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url"
|
||||
conn = HTTPSConnection("host") # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# six aliases
|
||||
import six
|
||||
|
||||
conn = six.moves.http_client.HTTPConnection("host") # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url"
|
||||
conn = six.moves.http_client.HTTPConnection("host") # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
conn = six.moves.http_client.HTTPSConnection("host") # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url"
|
||||
conn = six.moves.http_client.HTTPSConnection("host") # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# ==============================================================================
|
||||
# Certificate validation disabled
|
||||
@@ -50,8 +50,8 @@ context = ssl._create_default_https_context()
|
||||
assert context.check_hostname == True
|
||||
assert context.verify_mode == ssl.CERT_REQUIRED
|
||||
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url"
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# `_create_default_https_context` is currently just an alias for `create_default_context`
|
||||
# which creates a context for SERVER_AUTH purpose.
|
||||
@@ -59,16 +59,16 @@ context = ssl.create_default_context()
|
||||
assert context.check_hostname == True
|
||||
assert context.verify_mode == ssl.CERT_REQUIRED
|
||||
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url"
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# however, if you supply your own SSLContext, you need to set it manually
|
||||
context = ssl.SSLContext()
|
||||
assert context.check_hostname == False
|
||||
assert context.verify_mode == ssl.CERT_NONE
|
||||
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
|
||||
|
||||
# and if you misunderstood whether to use server/client in the purpose, you will also
|
||||
# get a context without hostname verification.
|
||||
@@ -76,8 +76,8 @@ context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
assert context.check_hostname == False
|
||||
assert context.verify_mode == ssl.CERT_NONE
|
||||
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
|
||||
|
||||
# NOTICE that current documentation says
|
||||
#
|
||||
@@ -90,8 +90,8 @@ context = ssl.SSLContext()
|
||||
context.check_hostname = True
|
||||
assert context.verify_mode == ssl.CERT_REQUIRED
|
||||
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url"
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# only setting verify_mode is not enough, since check_hostname is not enabled
|
||||
|
||||
@@ -99,8 +99,8 @@ context = ssl.SSLContext()
|
||||
context.verify_mode = ssl.CERT_REQUIRED
|
||||
assert context.check_hostname == False
|
||||
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrl="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
|
||||
conn = HTTPSConnection("host", context=context) # $ clientRequestUrlPart="host"
|
||||
conn.request("GET", "url") # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
|
||||
|
||||
# ==============================================================================
|
||||
# taint test
|
||||
@@ -112,8 +112,8 @@ def taint_test():
|
||||
host = request.args['host']
|
||||
url = request.args['url']
|
||||
|
||||
conn = HTTPConnection(host) # $ clientRequestUrl=host
|
||||
conn.request("GET", url) # $ clientRequestUrl=url
|
||||
conn = HTTPConnection(host) # $ clientRequestUrlPart=host
|
||||
conn.request("GET", url) # $ clientRequestUrlPart=url
|
||||
|
||||
resp = conn.getresponse()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user