Skip to content

Commit 3ff8e01

Browse files
committed
Python: Refactor based on review
- more natural handling of default arguments - do not assume default construction gives a family - simplifies `UnspecificSSLContextCreation`
1 parent 9f91dde commit 3ff8e01

File tree

3 files changed

+29
-26
lines changed

3 files changed

+29
-26
lines changed

python/ql/src/Security/CWE-327/PyOpenSSL.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ class PyOpenSSLContextCreation extends ContextCreation {
99
this = API::moduleImport("OpenSSL").getMember("SSL").getMember("Context").getACall()
1010
}
1111

12-
override DataFlow::CfgNode getProtocol() {
13-
result.getNode() in [node.getArg(0), node.getArgByName("method")]
12+
override string getProtocol() {
13+
exists(ControlFlowNode protocolArg, PyOpenSSL pyo |
14+
protocolArg in [node.getArg(0), node.getArgByName("method")]
15+
|
16+
protocolArg = [pyo.specific_version(result), pyo.unspecific_version(result)].asCfgNode()
17+
)
1418
}
1519
}
1620

python/ql/src/Security/CWE-327/Ssl.qll

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ class SSLContextCreation extends ContextCreation {
77

88
SSLContextCreation() { this = API::moduleImport("ssl").getMember("SSLContext").getACall() }
99

10-
override DataFlow::CfgNode getProtocol() {
11-
result.getNode() in [node.getArg(0), node.getArgByName("protocol")]
10+
override string getProtocol() {
11+
exists(ControlFlowNode protocolArg, Ssl ssl |
12+
protocolArg in [node.getArg(0), node.getArgByName("protocol")]
13+
|
14+
protocolArg = [ssl.specific_version(result), ssl.unspecific_version(result)].asCfgNode()
15+
)
16+
or
17+
not exists(node.getAnArg()) and
18+
result = "TLS"
1219
}
1320
}
1421

@@ -19,7 +26,7 @@ class SSLDefaultContextCreation extends ContextCreation {
1926

2027
// Allowed insecure versions are "TLSv1" and "TLSv1_1"
2128
// see https://docs.python.org/3/library/ssl.html#context-creation
22-
override DataFlow::CfgNode getProtocol() { none() }
29+
override string getProtocol() { result = "TLS" }
2330
}
2431

2532
/** Gets a reference to an `ssl.Context` instance. */
@@ -141,17 +148,10 @@ class UnspecificSSLContextCreation extends SSLContextCreation, UnspecificContext
141148
UnspecificSSLContextCreation() { library = "ssl" }
142149

143150
override ProtocolVersion getUnrestriction() {
144-
// Case: A protocol argument is present.
145151
result = UnspecificContextCreation.super.getUnrestriction() and
146152
// These are turned off by default
147153
// see https://docs.python.org/3/library/ssl.html#ssl-contexts
148154
not result in ["SSLv2", "SSLv3"]
149-
or
150-
// Case: No protocol arguemnt is present.
151-
not exists(this.getProtocol()) and
152-
// The default argument is TLS and the SSL versions are turned off by default since Python 3.6
153-
// see https://docs.python.org/3.6/library/ssl.html#ssl.SSLContext
154-
result in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"]
155155
}
156156
}
157157

@@ -185,8 +185,9 @@ class Ssl extends TlsLibrary {
185185

186186
override DataFlow::CfgNode insecure_connection_creation(ProtocolVersion version) {
187187
result = API::moduleImport("ssl").getMember("wrap_socket").getACall() and
188-
insecure_version(version).asCfgNode() =
189-
result.asCfgNode().(CallNode).getArgByName("ssl_version")
188+
specific_version(version).asCfgNode() =
189+
result.asCfgNode().(CallNode).getArgByName("ssl_version") and
190+
version.isInsecure()
190191
}
191192

192193
override ConnectionCreation connection_creation() { result instanceof WrapSocketCall }

python/ql/src/Security/CWE-327/TlsLibraryModel.qll

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class ProtocolFamily extends string {
3030

3131
/** The creation of a context. */
3232
abstract class ContextCreation extends DataFlow::CfgNode {
33-
/** Gets the requested protocol if any. */
34-
abstract DataFlow::CfgNode getProtocol();
33+
/** Gets the protocol version or family for this context. */
34+
abstract string getProtocol();
3535
}
3636

3737
/** The creation of a connection from a context. */
@@ -66,7 +66,7 @@ abstract class UnspecificContextCreation extends ContextCreation, ProtocolUnrest
6666
TlsLibrary library;
6767
ProtocolFamily family;
6868

69-
UnspecificContextCreation() { this.getProtocol() = library.unspecific_version(family) }
69+
UnspecificContextCreation() { this.getProtocol() = family }
7070

7171
override DataFlow::CfgNode getContext() { result = this }
7272

@@ -92,9 +92,8 @@ abstract class TlsLibrary extends string {
9292
/** The module or class holding the version constants. */
9393
abstract API::Node version_constants();
9494

95-
/** A dataflow node representing a specific protocol version, known to be insecure. */
96-
DataFlow::Node insecure_version(ProtocolVersion version) {
97-
version.isInsecure() and
95+
/** A dataflow node representing a specific protocol version. */
96+
DataFlow::Node specific_version(ProtocolVersion version) {
9897
result = version_constants().getMember(specific_version_name(version)).getAUse()
9998
}
10099

@@ -111,16 +110,15 @@ abstract class TlsLibrary extends string {
111110

112111
/** The creation of a context with a specific protocol version, known to be insecure. */
113112
ContextCreation insecure_context_creation(ProtocolVersion version) {
114-
result = specific_context_creation() and
115-
result.getProtocol() = insecure_version(version)
113+
result in [specific_context_creation(), default_context_creation()] and
114+
result.getProtocol() = version and
115+
version.isInsecure()
116116
}
117117

118118
/** The creation of a context with an unspecific protocol version, say TLS, known to have insecure instances. */
119119
ContextCreation unspecific_context_creation(ProtocolFamily family) {
120-
result = default_context_creation()
121-
or
122-
result = specific_context_creation() and
123-
result.(ContextCreation).getProtocol() = unspecific_version(family)
120+
result in [specific_context_creation(), default_context_creation()] and
121+
result.getProtocol() = family
124122
}
125123

126124
/** A connection is created in an insecure manner, not from a context. */

0 commit comments

Comments
 (0)