Skip to content

Commit 46973f4

Browse files
committed
Support from ssl import PROTOCOL_....
1 parent e8a41f7 commit 46973f4

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

python/ql/src/Security/CWE-327/InsecureProtocol.ql

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ private ModuleObject the_pyOpenSSL_module() {
4040
result = any(ModuleObject m | m.getName() = "pyOpenSSL.SSL")
4141
}
4242

43+
/* A syntactic check for cases where points-to analysis cannot infer the presence of
44+
* a protocol constant, e.g. if it has been removed in later versions of the `ssl`
45+
* library.
46+
*/
47+
predicate probable_insecure_ssl_constant(CallNode call, string insecure_version) {
48+
exists(ControlFlowNode arg | arg = call.getArgByName("ssl_version") |
49+
arg.(AttrNode).getObject(insecure_version).refersTo(the_ssl_module())
50+
or
51+
arg.(NameNode).getId() = insecure_version and
52+
exists(Import imp |
53+
imp.getAnImportedModuleName() = "ssl" and
54+
imp.getAName().getAsname().(Name).getId() = insecure_version
55+
)
56+
)
57+
}
58+
4359
predicate unsafe_ssl_wrap_socket_call(CallNode call, string method_name, string insecure_version) {
4460
(
4561
call = ssl_wrap_socket().getACall() and
@@ -54,10 +70,7 @@ predicate unsafe_ssl_wrap_socket_call(CallNode call, string method_name, string
5470
(
5571
call.getArgByName("ssl_version").refersTo(the_ssl_module().getAttribute(insecure_version))
5672
or
57-
// syntactic match, in case the version in question has been deprecated
58-
exists(ControlFlowNode arg | arg = call.getArgByName("ssl_version") |
59-
arg.(AttrNode).getObject(insecure_version).refersTo(the_ssl_module())
60-
)
73+
probable_insecure_ssl_constant(call, insecure_version)
6174
)
6275
}
6376

python/ql/test/query-tests/Security/CWE-327/InsecureProtocol.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@
99
| InsecureProtocol.py:16:1:16:29 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv3_METHOD specified in call to pyOpenSSL.SSL.Context. |
1010
| InsecureProtocol.py:17:1:17:29 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version TLSv1_METHOD specified in call to pyOpenSSL.SSL.Context. |
1111
| InsecureProtocol.py:32:1:32:19 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv2_METHOD specified in call to pyOpenSSL.SSL.Context. |
12+
| InsecureProtocol.py:48:1:48:43 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version PROTOCOL_SSLv2 specified in call to deprecated method ssl.wrap_socket. |
13+
| InsecureProtocol.py:49:1:49:38 | ControlFlowNode for SSLContext() | Insecure SSL/TLS protocol version PROTOCOL_SSLv2 specified in call to ssl.SSLContext. |

python/ql/test/query-tests/Security/CWE-327/InsecureProtocol.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,11 @@
4040
# possibly insecure default
4141
ssl.wrap_socket()
4242
context = SSLContext()
43+
44+
# importing the protocol constant directly
45+
46+
from ssl import PROTOCOL_SSLv2
47+
48+
ssl.wrap_socket(ssl_version=PROTOCOL_SSLv2)
49+
SSLContext(ssl_version=PROTOCOL_SSLv2)
50+

0 commit comments

Comments
 (0)