Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a893dca

Browse files
committed
Add support for ssl.SSLContext.
1 parent 0a839f8 commit a893dca

5 files changed

Lines changed: 66 additions & 24 deletions

File tree

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,23 @@ FunctionObject ssl_wrap_socket() {
1616
result = any(ModuleObject ssl | ssl.getName() = "ssl").getAttribute("wrap_socket")
1717
}
1818

19-
from CallNode call
19+
ClassObject ssl_Context_class() {
20+
result = any(ModuleObject ssl | ssl.getName() = "ssl").getAttribute("SSLContext")
21+
}
22+
23+
CallNode unsafe_call(string method_name) {
24+
result = ssl_wrap_socket().getACall() and
25+
method_name = "deprecated method ssl.wrap_socket"
26+
or
27+
result = ssl_Context_class().getACall() and
28+
method_name = "ssl.SSLContext"
29+
}
30+
31+
from CallNode call, string method_name
2032
where
21-
call = ssl_wrap_socket().getACall() and
33+
call = unsafe_call(method_name) and
2234
not exists(call.getArgByName("ssl_version"))
23-
select call, "Call to ssl.wrap_socket does not specify a protocol, which may result in an insecure default being used."
35+
select call, "Call to " + method_name + " does not specify a protocol, which may result in an insecure default being used."
2436

2537

2638

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

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
import python
1414

1515
FunctionObject ssl_wrap_socket() {
16-
result = any(ModuleObject ssl | ssl.getName() = "ssl").getAttribute("wrap_socket")
16+
result = the_ssl_module().getAttribute("wrap_socket")
17+
}
18+
19+
ClassObject ssl_Context_class() {
20+
result = the_ssl_module().getAttribute("SSLContext")
1721
}
1822

1923
string insecure_version_name() {
@@ -33,28 +37,43 @@ private ModuleObject the_ssl_module() {
3337
}
3438

3539
private ModuleObject the_pyOpenSSL_module() {
36-
result = any(ModuleObject m | m.getName() = "pyOpenSSL").getAttribute("SSL")
40+
result = any(ModuleObject m | m.getName() = "pyOpenSSL.SSL")
3741
}
3842

39-
predicate unsafe_ssl_wrap_method_call(CallNode call) {
40-
call = ssl_wrap_socket().getACall() and
41-
exists(ControlFlowNode arg | arg = call.getArgByName("ssl_version") |
42-
arg.(AttrNode).getObject(insecure_version_name()).refersTo(the_ssl_module())
43+
predicate unsafe_ssl_wrap_socket_call(CallNode call, string method_name, string insecure_version) {
44+
(
45+
call = ssl_wrap_socket().getACall() and
46+
method_name = "deprecated method ssl.wrap_socket"
47+
or
48+
call = ssl_Context_class().getACall() and
49+
method_name = "ssl.SSLContext"
50+
)
51+
and
52+
insecure_version = insecure_version_name()
53+
and
54+
(
55+
call.getArgByName("ssl_version").refersTo(the_ssl_module().getAttribute(insecure_version))
56+
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+
)
4361
)
4462
}
4563

4664
ClassObject the_pyOpenSSL_Context_class() {
4765
result = any(ModuleObject m | m.getName() = "pyOpenSSL.SSL").getAttribute("Context")
4866
}
4967

50-
predicate unsafe_pyOpenSSL_Context_call(CallNode call) {
68+
predicate unsafe_pyOpenSSL_Context_call(CallNode call, string insecure_version) {
5169
call = the_pyOpenSSL_Context_class().getACall() and
52-
call.getArgByName("method").refersTo(the_pyOpenSSL_module().getAttribute(insecure_version_name()))
70+
insecure_version = insecure_version_name() and
71+
call.getArgByName("method").refersTo(the_pyOpenSSL_module().getAttribute(insecure_version))
5372
}
5473

55-
from CallNode call, string method_name
74+
from CallNode call, string method_name, string insecure_version
5675
where
57-
unsafe_ssl_wrap_method_call(call) and method_name = "ssl.wrap_socket"
76+
unsafe_ssl_wrap_socket_call(call, method_name, insecure_version)
5877
or
59-
unsafe_pyOpenSSL_Context_call(call) and method_name = "pyOpenSSL.SSL.Context"
60-
select call, "Insecure SSL/TLS protocol version specified in call to " + method_name + "."
78+
unsafe_pyOpenSSL_Context_call(call, insecure_version) and method_name = "pyOpenSSL.SSL.Context"
79+
select call, "Insecure SSL/TLS protocol version " + insecure_version + " specified in call to " + method_name + "."
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
| InsecureProtocol.py:35:1:35:17 | ControlFlowNode for Attribute() | Call to ssl.wrap_socket does not specify a protocol, which may result in an insecure default being used. |
1+
| InsecureProtocol.py:41:1:41:17 | ControlFlowNode for Attribute() | Call to deprecated method ssl.wrap_socket does not specify a protocol, which may result in an insecure default being used. |
2+
| InsecureProtocol.py:42:11:42:22 | ControlFlowNode for SSLContext() | Call to ssl.SSLContext does not specify a protocol, which may result in an insecure default being used. |
Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
| InsecureProtocol.py:5:1:5:47 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to ssl.wrap_socket. |
2-
| InsecureProtocol.py:6:1:6:47 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to ssl.wrap_socket. |
3-
| InsecureProtocol.py:7:1:7:47 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to ssl.wrap_socket. |
4-
| InsecureProtocol.py:9:1:9:36 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to pyOpenSSL.SSL.Context. |
5-
| InsecureProtocol.py:10:1:10:37 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to pyOpenSSL.SSL.Context. |
6-
| InsecureProtocol.py:11:1:11:36 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to pyOpenSSL.SSL.Context. |
7-
| InsecureProtocol.py:12:1:12:36 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to pyOpenSSL.SSL.Context. |
8-
| InsecureProtocol.py:27:1:27:26 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version specified in call to pyOpenSSL.SSL.Context. |
1+
| InsecureProtocol.py:6:1:6:47 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version PROTOCOL_SSLv2 specified in call to deprecated method ssl.wrap_socket. |
2+
| InsecureProtocol.py:7:1:7:47 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version PROTOCOL_SSLv3 specified in call to deprecated method ssl.wrap_socket. |
3+
| InsecureProtocol.py:8:1:8:47 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version PROTOCOL_TLSv1 specified in call to deprecated method ssl.wrap_socket. |
4+
| InsecureProtocol.py:10:1:10:42 | ControlFlowNode for SSLContext() | Insecure SSL/TLS protocol version PROTOCOL_SSLv2 specified in call to ssl.SSLContext. |
5+
| InsecureProtocol.py:11:1:11:42 | ControlFlowNode for SSLContext() | Insecure SSL/TLS protocol version PROTOCOL_SSLv3 specified in call to ssl.SSLContext. |
6+
| InsecureProtocol.py:12:1:12:42 | ControlFlowNode for SSLContext() | Insecure SSL/TLS protocol version PROTOCOL_TLSv1 specified in call to ssl.SSLContext. |
7+
| InsecureProtocol.py:14:1:14:36 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv2_METHOD specified in call to pyOpenSSL.SSL.Context. |
8+
| InsecureProtocol.py:15:1:15:37 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv23_METHOD specified in call to pyOpenSSL.SSL.Context. |
9+
| InsecureProtocol.py:16:1:16:36 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv3_METHOD specified in call to pyOpenSSL.SSL.Context. |
10+
| InsecureProtocol.py:17:1:17:36 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version TLSv1_METHOD specified in call to pyOpenSSL.SSL.Context. |
11+
| InsecureProtocol.py:32:1:32:26 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv2_METHOD specified in call to pyOpenSSL.SSL.Context. |

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import ssl
22
from pyOpenSSL import SSL
3+
from ssl import SSLContext
34

45
# true positives
56
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv2)
67
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3)
78
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1)
89

10+
SSLContext(ssl_version=ssl.PROTOCOL_SSLv2)
11+
SSLContext(ssl_version=ssl.PROTOCOL_SSLv3)
12+
SSLContext(ssl_version=ssl.PROTOCOL_TLSv1)
13+
914
SSL.Context(method=SSL.SSLv2_METHOD)
1015
SSL.Context(method=SSL.SSLv23_METHOD)
1116
SSL.Context(method=SSL.SSLv3_METHOD)
@@ -29,7 +34,9 @@
2934
# secure versions
3035

3136
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1_1)
37+
SSLContext(ssl_version=ssl.PROTOCOL_TLSv1_1)
3238
SSL.Context(method=SSL.TLSv1_1_METHOD)
3339

3440
# possibly insecure default
3541
ssl.wrap_socket()
42+
context = SSLContext()

0 commit comments

Comments
 (0)