Skip to content

Commit

Permalink
Python: Pycurl SSL Disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
porcupineyhairs committed Sep 2, 2024
1 parent ffab199 commit e2dd126
Showing 1 changed file with 43 additions and 2 deletions.
45 changes: 43 additions & 2 deletions python/ql/lib/semmle/python/frameworks/Pycurl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ module Pycurl {
/** Gets a reference to an instance of `pycurl.Curl`. */
private API::Node instance() { result = classRef().getReturn() }

/** Gets a reference to an instance of `pycurl.Curl.setopt`. */
private API::Node setopt() { result = instance().getMember("setopt") }

/** Gets a reference to an instance of `pycurl.Curl.SSL_VERIFYPEER`. */
private API::Node sslverifypeer() {
result = API::moduleImport("pycurl").getMember("SSL_VERIFYPEER") or
result = instance().getMember("SSL_VERIFYPEER")
}

/**
* When the first parameter value of the `setopt` function is set to `pycurl.URL`,
* the second parameter value is the request resource link.
Expand All @@ -45,7 +54,7 @@ module Pycurl {
*/
private class OutgoingRequestCall extends Http::Client::Request::Range, DataFlow::CallCfgNode {
OutgoingRequestCall() {
this = instance().getMember("setopt").getACall() and
this = setopt().getACall() and
this.getArg(0).asCfgNode().(AttrNode).getName() = "URL"
}

Expand All @@ -58,9 +67,41 @@ module Pycurl {
override predicate disablesCertificateValidation(
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
// TODO: Look into disabling certificate validation
none()
}
}

/**
* When the first parameter value of the `setopt` function is set to `SSL_VERIFYPEER` or `SSL_VERIFYHOST`,
* the second parameter value disables or enable SSL certifiacte verification.
*
* See http://pycurl.io/docs/latest/curlobject.html#pycurl.Curl.setopt.
*/
private class CurlSslCall extends Http::Client::Request::Range, DataFlow::CallCfgNode {
CurlSslCall() {
this = setopt().getACall() and
this.getArg(0).asCfgNode().(AttrNode).getName() = ["SSL_VERIFYPEER", "SSL_VERIFYHOST"]
}

override DataFlow::Node getAUrlPart() { none() }

override string getFramework() { result = "pycurl.Curl" }

override predicate disablesCertificateValidation(
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
exists(API::CallNode c |
c = setopt().getACall() and
sslverifypeer().getAValueReachableFromSource() = c.getArg(0) and
(
exists(IntegerLiteral i | i.getValue() = 0 and c.getArg(1).asExpr() = i)
or
exists(BooleanLiteral b | b.booleanValue() = false)
)
|
disablingNode = c and argumentOrigin = c.getArg(1)
)
}
}
}
}

0 comments on commit e2dd126

Please sign in to comment.