Skip to content

Commit f72a1d9

Browse files
committed
Python: Model certificate disabling in aiohttp.client
1 parent 4b07a7b commit f72a1d9

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

python/ql/lib/semmle/python/frameworks/Aiohttp.qll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ private module AiohttpClientModel {
662662
private API::Node instance() { result = classRef().getReturn() }
663663

664664
/** A method call on a ClientSession that sends off a request */
665-
private class OutgoingRequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode {
665+
private class OutgoingRequestCall extends HTTP::Client::Request::Range, API::CallNode {
666666
string methodName;
667667

668668
OutgoingRequestCall() {
@@ -685,8 +685,14 @@ private module AiohttpClientModel {
685685
override predicate disablesCertificateValidation(
686686
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
687687
) {
688-
// TODO: Look into disabling certificate validation
689-
none()
688+
exists(API::Node param | param = this.getKeywordParameter(["ssl", "verify_ssl"]) |
689+
disablingNode = param.getARhs() and
690+
argumentOrigin = param.getAValueReachingRhs() and
691+
// aiohttp.client treats `None` as the default and all other "falsey" values as `False`.
692+
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and
693+
not argumentOrigin.asExpr() instanceof None
694+
)
695+
// TODO: Handling of SSLContext passed as ssl/ssl_context arguments
690696
}
691697
}
692698
}

python/ql/test/library-tests/frameworks/aiohttp/client_request.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import aiohttp
22
import asyncio
3+
import ssl
34

45
s = aiohttp.ClientSession()
56
resp = s.request("method", "url") # $ clientRequestUrlPart="url"
@@ -13,4 +14,20 @@
1314
s = aiohttp.ClientSession()
1415
resp = s.post("url") # $ clientRequestUrlPart="url"
1516
resp = s.patch("url") # $ clientRequestUrlPart="url"
16-
resp = s.options("url") # $ clientRequestUrlPart="url"
17+
resp = s.options("url") # $ clientRequestUrlPart="url"
18+
19+
# disabling of SSL validation
20+
# see https://docs.aiohttp.org/en/stable/client_reference.html#aiohttp.ClientSession.request
21+
s.get("url", ssl=False) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
22+
s.get("url", ssl=0) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
23+
24+
# deprecated since 3.0, but still supported
25+
s.get("url", verify_ssl=False) # $ clientRequestUrlPart="url" clientRequestCertValidationDisabled
26+
27+
# A manually constructed SSLContext does not have safe defaults, so is effectively the
28+
# same as turning off SSL validation
29+
context = ssl.SSLContext()
30+
assert context.check_hostname == False
31+
assert context.verify_mode == ssl.VerifyMode.CERT_NONE
32+
33+
s.get("url", ssl=context) # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled

0 commit comments

Comments
 (0)