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:
Rasmus Wriedt Larsen
2021-12-15 21:33:54 +01:00
parent 6f81685f48
commit f8fc583af3
7 changed files with 54 additions and 54 deletions

View File

@@ -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()
)
}

View File

@@ -43,7 +43,7 @@ private module Requests {
)
}
override DataFlow::Node getUrl() {
override DataFlow::Node getAUrlPart() {
result = this.getArgByName("url")
or
not methodName = "request" and

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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()