mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python: Port insecure default protocol
- use API graphs - update .qlhelp-file - limit to versions below 3.4 - move tests to its own directory to only test on old version
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
|
||||
<p>
|
||||
Ensure that a modern, strong protocol is used. All versions of SSL,
|
||||
and TLS 1.0 are known to be vulnerable to attacks. Using TLS 1.1 or
|
||||
and TLS 1.0 and 1.1 are known to be vulnerable to attacks. Using TLS 1.2 or
|
||||
above is strongly recommended. If no explicit
|
||||
<code>ssl_version</code> is specified, the default
|
||||
<code>PROTOCOL_TLS</code> is chosen. This protocol is insecure and
|
||||
@@ -34,13 +34,15 @@
|
||||
<p>
|
||||
Both of the cases above should be updated to use a secure protocol
|
||||
instead, for instance by specifying
|
||||
<code>ssl_version=PROTOCOL_TLSv1_1</code> as a keyword argument.
|
||||
<code>ssl_version=PROTOCOL_TLSv1_2</code> as a keyword argument.
|
||||
</p>
|
||||
<p>
|
||||
Note that <code>ssl.wrap_socket</code> has been deprecated in
|
||||
Python 3.7. A preferred alternative is to use
|
||||
<code>ssl.SSLContext</code>, which is supported in Python 2.7.9 and
|
||||
3.2 and later versions.
|
||||
3.2 and later versions or the convenience function
|
||||
<code>ssl.create_default_context</code>, which is supported in Python
|
||||
3.4 and later versions.
|
||||
</p>
|
||||
</example>
|
||||
|
||||
@@ -48,6 +50,8 @@
|
||||
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security"> Transport Layer Security</a>.</li>
|
||||
<li>Python 3 documentation: <a href="https://docs.python.org/3/library/ssl.html#ssl.SSLContext"> class ssl.SSLContext</a>.</li>
|
||||
<li>Python 3 documentation: <a href="https://docs.python.org/3/library/ssl.html#ssl.wrap_socket"> ssl.wrap_socket</a>.</li>
|
||||
<li>Python 3 documentation: <a href="https://docs.python.org/3/library/ssl.html#functions-constants-and-exceptions"> notes on context creation</a>.</li>
|
||||
<li>Python 3 documentation: <a href="https://docs.python.org/3/library/ssl.html#ssl-security"> notes on security considerations</a>.</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
|
||||
@@ -11,20 +11,19 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
|
||||
FunctionValue ssl_wrap_socket() { result = Value::named("ssl.wrap_socket") }
|
||||
|
||||
ClassValue ssl_Context_class() { result = Value::named("ssl.SSLContext") }
|
||||
import semmle.python.ApiGraphs
|
||||
|
||||
CallNode unsafe_call(string method_name) {
|
||||
result = ssl_wrap_socket().getACall() and
|
||||
result = API::moduleImport("ssl").getMember("wrap_socket").getACall().asCfgNode() and
|
||||
not exists(result.getArgByName("ssl_version")) and
|
||||
method_name = "deprecated method ssl.wrap_socket"
|
||||
or
|
||||
result = ssl_Context_class().getACall() and
|
||||
result = API::moduleImport("ssl").getMember("SSLContext").getACall().asCfgNode() and
|
||||
not exists(result.getArgByName("protocol")) and
|
||||
not exists(result.getArg(0)) and
|
||||
method_name = "ssl.SSLContext"
|
||||
method_name = "ssl.SSLContext" and
|
||||
// in version 3.4, flags were introduced to modify cotexts created with default values
|
||||
(major_version() < 3 or minor_version() < 4)
|
||||
}
|
||||
|
||||
from CallNode call, string method_name
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import ssl
|
||||
from pyOpenSSL import SSL
|
||||
from ssl import SSLContext
|
||||
|
||||
# true positives
|
||||
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv2)
|
||||
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3)
|
||||
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1)
|
||||
|
||||
SSLContext(protocol=ssl.PROTOCOL_SSLv2)
|
||||
SSLContext(protocol=ssl.PROTOCOL_SSLv3)
|
||||
SSLContext(protocol=ssl.PROTOCOL_TLSv1)
|
||||
|
||||
SSL.Context(SSL.SSLv2_METHOD)
|
||||
SSL.Context(SSL.SSLv23_METHOD)
|
||||
SSL.Context(SSL.SSLv3_METHOD)
|
||||
SSL.Context(SSL.TLSv1_METHOD)
|
||||
|
||||
# not relevant
|
||||
wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3)
|
||||
wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1)
|
||||
wrap_socket(ssl_version=ssl.PROTOCOL_SSLv2)
|
||||
|
||||
Context(SSL.SSLv3_METHOD)
|
||||
Context(SSL.TLSv1_METHOD)
|
||||
Context(SSL.SSLv2_METHOD)
|
||||
Context(SSL.SSLv23_METHOD)
|
||||
|
||||
# true positive using flow
|
||||
|
||||
METHOD = SSL.SSLv2_METHOD
|
||||
SSL.Context(METHOD)
|
||||
|
||||
# secure versions
|
||||
|
||||
ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1_1)
|
||||
SSLContext(protocol=ssl.PROTOCOL_TLSv1_1)
|
||||
SSL.Context(SSL.TLSv1_1_METHOD)
|
||||
|
||||
# possibly insecure default
|
||||
ssl.wrap_socket()
|
||||
context = SSLContext()
|
||||
|
||||
# importing the protocol constant directly
|
||||
|
||||
from ssl import PROTOCOL_SSLv2
|
||||
|
||||
ssl.wrap_socket(ssl_version=PROTOCOL_SSLv2)
|
||||
SSLContext(protocol=PROTOCOL_SSLv2)
|
||||
|
||||
# FP for insecure default
|
||||
ssl.SSLContext(ssl.SSLv23_METHOD)
|
||||
1
python/ql/test/query-tests/Security/CWE-327/py2/options
Normal file
1
python/ql/test/query-tests/Security/CWE-327/py2/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --lang=2 -p ../lib/ --max-import-depth=3
|
||||
Reference in New Issue
Block a user