Skip to content

Commit 7338eaf

Browse files
authored
Merge pull request github#16812 from porcupineyhairs/pyloadSsl
Python: Pycurl SSL Disabled
2 parents ab1b48d + c78aeec commit 7338eaf

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ module Pycurl {
3737
/** Gets a reference to an instance of `pycurl.Curl`. */
3838
private API::Node instance() { result = classRef().getReturn() }
3939

40+
/** Gets a reference to `pycurl.Curl.setopt`. */
41+
private API::Node setopt() { result = instance().getMember("setopt") }
42+
43+
/** Gets a reference to the constant `pycurl.Curl.SSL_VERIFYPEER`. */
44+
private API::Node sslverifypeer() {
45+
result = API::moduleImport("pycurl").getMember("SSL_VERIFYPEER") or
46+
result = instance().getMember("SSL_VERIFYPEER")
47+
}
48+
4049
/**
4150
* When the first parameter value of the `setopt` function is set to `pycurl.URL`,
4251
* the second parameter value is the request resource link.
@@ -45,7 +54,7 @@ module Pycurl {
4554
*/
4655
private class OutgoingRequestCall extends Http::Client::Request::Range, DataFlow::CallCfgNode {
4756
OutgoingRequestCall() {
48-
this = instance().getMember("setopt").getACall() and
57+
this = setopt().getACall() and
4958
this.getArg(0).asCfgNode().(AttrNode).getName() = "URL"
5059
}
5160

@@ -58,9 +67,37 @@ module Pycurl {
5867
override predicate disablesCertificateValidation(
5968
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
6069
) {
61-
// TODO: Look into disabling certificate validation
6270
none()
6371
}
6472
}
73+
74+
/**
75+
* When the first parameter value of the `setopt` function is set to `SSL_VERIFYPEER` or `SSL_VERIFYHOST`,
76+
* the second parameter value disables or enable SSL certifiacte verification.
77+
*
78+
* See http://pycurl.io/docs/latest/curlobject.html#pycurl.Curl.setopt.
79+
*/
80+
private class CurlSslCall extends Http::Client::Request::Range, DataFlow::CallCfgNode {
81+
CurlSslCall() {
82+
this = setopt().getACall() and
83+
this.getArg(0).asCfgNode().(AttrNode).getName() = ["SSL_VERIFYPEER", "SSL_VERIFYHOST"]
84+
}
85+
86+
override DataFlow::Node getAUrlPart() { none() }
87+
88+
override string getFramework() { result = "pycurl.Curl" }
89+
90+
override predicate disablesCertificateValidation(
91+
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
92+
) {
93+
sslverifypeer().getAValueReachableFromSource() = this.getArg(0) and
94+
(
95+
this.getArg(1).asExpr().(IntegerLiteral).getValue() = 0
96+
or
97+
this.getArg(1).asExpr().(BooleanLiteral).booleanValue() = false
98+
) and
99+
(disablingNode = this and argumentOrigin = this.getArg(1))
100+
}
101+
}
65102
}
66103
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Improved modelling for the `pycurl` framework.

0 commit comments

Comments
 (0)