mirror of
https://github.com/github/codeql.git
synced 2025-12-22 11:46:32 +01:00
Python: Model certificate disabling in httpx
This commit is contained in:
@@ -23,7 +23,7 @@ private module HttpxModel {
|
||||
*
|
||||
* See https://www.python-httpx.org/api/
|
||||
*/
|
||||
private class RequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode {
|
||||
private class RequestCall extends HTTP::Client::Request::Range, API::CallNode {
|
||||
string methodName;
|
||||
|
||||
RequestCall() {
|
||||
@@ -44,8 +44,11 @@ private module HttpxModel {
|
||||
override predicate disablesCertificateValidation(
|
||||
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
|
||||
) {
|
||||
// TODO: Look into disabling certificate validation
|
||||
none()
|
||||
disablingNode = this.getKeywordParameter("verify").getARhs() and
|
||||
argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and
|
||||
// unlike `requests`, httpx treats `None` as turning off verify (and not as the default)
|
||||
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false
|
||||
// TODO: Handling of insecure SSLContext passed to verify argument
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +63,13 @@ private module HttpxModel {
|
||||
result = API::moduleImport("httpx").getMember(["Client", "AsyncClient"])
|
||||
}
|
||||
|
||||
/** Get a reference to an `httpx.Client` or `httpx.AsyncClient` instance. */
|
||||
private API::Node instance() { result = classRef().getReturn() }
|
||||
|
||||
/** A method call on a Client that sends off a request */
|
||||
private class OutgoingRequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode {
|
||||
string methodName;
|
||||
|
||||
OutgoingRequestCall() {
|
||||
methodName in [HTTP::httpVerbLower(), "request", "stream"] and
|
||||
this = instance().getMember(methodName).getACall()
|
||||
this = classRef().getReturn().getMember(methodName).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAUrlPart() {
|
||||
@@ -85,8 +85,16 @@ private module HttpxModel {
|
||||
override predicate disablesCertificateValidation(
|
||||
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
|
||||
) {
|
||||
// TODO: Look into disabling certificate validation
|
||||
none()
|
||||
exists(API::CallNode constructor |
|
||||
constructor = classRef().getACall() and
|
||||
this = constructor.getReturn().getMember(methodName).getACall()
|
||||
|
|
||||
disablingNode = constructor.getKeywordParameter("verify").getARhs() and
|
||||
argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingRhs() and
|
||||
// unlike `requests`, httpx treats `None` as turning off verify (and not as the default)
|
||||
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false
|
||||
// TODO: Handling of insecure SSLContext passed to verify argument
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import httpx
|
||||
import ssl
|
||||
|
||||
httpx.get("url") # $ clientRequestUrlPart="url"
|
||||
httpx.post("url") # $ clientRequestUrlPart="url"
|
||||
@@ -23,3 +24,22 @@ async def async_test():
|
||||
response = await client.options("url") # $ clientRequestUrlPart="url"
|
||||
response = await client.request("method", url="url") # $ clientRequestUrlPart="url"
|
||||
response = await client.stream("method", url="url") # $ clientRequestUrlPart="url"
|
||||
|
||||
# ==============================================================================
|
||||
# Disabling certificate validation
|
||||
# ==============================================================================
|
||||
|
||||
httpx.get("url", verify=False) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
|
||||
httpx.get("url", verify=0) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
|
||||
httpx.get("url", verify=None) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
|
||||
|
||||
# A manually constructed SSLContext does not have safe defaults, so is effectively the
|
||||
# same as turning off SSL validation
|
||||
context = ssl.SSLContext()
|
||||
assert context.check_hostname == False
|
||||
assert context.verify_mode == ssl.VerifyMode.CERT_NONE
|
||||
|
||||
httpx.get("url", verify=context) # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
|
||||
|
||||
client = httpx.Client(verify=False)
|
||||
client.get("url") # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
|
||||
|
||||
Reference in New Issue
Block a user