mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
143 lines
5.1 KiB
Plaintext
143 lines
5.1 KiB
Plaintext
import python
|
|
import semmle.python.ApiGraphs
|
|
import Ssl
|
|
import PyOpenSSL
|
|
|
|
/**
|
|
* A specific protocol version.
|
|
* We use this to identify a protocol.
|
|
*/
|
|
class ProtocolVersion extends string {
|
|
ProtocolVersion() { this in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] }
|
|
|
|
predicate lessThan(ProtocolVersion version) {
|
|
this = "SSLv2" and version = "SSLv3"
|
|
or
|
|
this = "TLSv1" and version = ["TLSv1_1", "TLSv1_2", "TLSv1_3"]
|
|
or
|
|
this = ["TLSv1", "TLSv1_1"] and version = ["TLSv1_2", "TLSv1_3"]
|
|
or
|
|
this = ["TLSv1", "TLSv1_1", "TLSv1_2"] and version = "TLSv1_3"
|
|
}
|
|
|
|
predicate isInsecure() { this in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1"] }
|
|
}
|
|
|
|
/** An unspecific protocol version */
|
|
class ProtocolFamily extends string {
|
|
ProtocolFamily() { this in ["SSLv23", "TLS"] }
|
|
}
|
|
|
|
/** The creation of a context. */
|
|
abstract class ContextCreation extends DataFlow::CfgNode {
|
|
/** Gets the requested protocol if any. */
|
|
abstract DataFlow::CfgNode getProtocol();
|
|
}
|
|
|
|
/** The creation of a connection from a context. */
|
|
abstract class ConnectionCreation extends DataFlow::CfgNode {
|
|
/** Gets the context used to create the connection. */
|
|
abstract DataFlow::CfgNode getContext();
|
|
}
|
|
|
|
/** A context is being restricted on which protocols it can accepts. */
|
|
abstract class ProtocolRestriction extends DataFlow::CfgNode {
|
|
/** Gets the context being restricted. */
|
|
abstract DataFlow::CfgNode getContext();
|
|
|
|
/** Gets the protocol version being disallowed. */
|
|
abstract ProtocolVersion getRestriction();
|
|
}
|
|
|
|
/** A context is being relaxed on which protocols it can accepts. */
|
|
abstract class ProtocolUnrestriction extends DataFlow::CfgNode {
|
|
/** Gets the context being relaxed. */
|
|
abstract DataFlow::CfgNode getContext();
|
|
|
|
/** Gets the protocol version being allowed. */
|
|
abstract ProtocolVersion getUnrestriction();
|
|
}
|
|
|
|
/**
|
|
* A context is being created with a range of allowed protocols.
|
|
* This also serves as unrestricting these protocols.
|
|
*/
|
|
abstract class UnspecificContextCreation extends ContextCreation, ProtocolUnrestriction {
|
|
TlsLibrary library;
|
|
ProtocolFamily family;
|
|
|
|
UnspecificContextCreation() { this.getProtocol() = library.unspecific_version(family) }
|
|
|
|
override DataFlow::CfgNode getContext() { result = this }
|
|
|
|
override ProtocolVersion getUnrestriction() {
|
|
// see https://www.openssl.org/docs/man1.1.0/man3/TLS_method.html
|
|
family = "TLS" and
|
|
result in ["SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"]
|
|
or
|
|
// This can negotiate a TLS 1.3 connection (!)
|
|
// see
|
|
// - https://docs.python.org/3/library/ssl.html#ssl-contexts
|
|
// - https://www.openssl.org/docs/man1.0.2/man3/TLSv1_method.html
|
|
family = "SSLv23" and
|
|
result in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"]
|
|
}
|
|
}
|
|
|
|
/** A model of a TLS library. */
|
|
abstract class TlsLibrary extends string {
|
|
TlsLibrary() { this in ["ssl", "pyOpenSSL"] }
|
|
|
|
/** The name of a specific protocol version. */
|
|
abstract string specific_version_name(ProtocolVersion version);
|
|
|
|
/** The name of an unspecific protocol version, say TLS, known to have insecure instances. */
|
|
abstract string unspecific_version_name(ProtocolFamily family);
|
|
|
|
/** The module or class holding the version constants. */
|
|
abstract API::Node version_constants();
|
|
|
|
/** A dataflow node representing a specific protocol version, known to be insecure. */
|
|
DataFlow::Node insecure_version(ProtocolVersion version) {
|
|
version.isInsecure() and
|
|
result = version_constants().getMember(specific_version_name(version)).getAUse()
|
|
}
|
|
|
|
/** A dataflow node representing an unspecific protocol version, say TLS, known to have insecure instances. */
|
|
DataFlow::Node unspecific_version(ProtocolFamily family) {
|
|
result = version_constants().getMember(unspecific_version_name(family)).getAUse()
|
|
}
|
|
|
|
/** The creation of a context with a deafult protocol. */
|
|
abstract ContextCreation default_context_creation();
|
|
|
|
/** The creation of a context with a specific protocol. */
|
|
abstract ContextCreation specific_context_creation();
|
|
|
|
/** The creation of a context with a specific protocol version, known to be insecure. */
|
|
ContextCreation insecure_context_creation(ProtocolVersion version) {
|
|
result = specific_context_creation() and
|
|
result.getProtocol() = insecure_version(version)
|
|
}
|
|
|
|
/** The creation of a context with an unspecific protocol version, say TLS, known to have insecure instances. */
|
|
DataFlow::CfgNode unspecific_context_creation(ProtocolFamily family) {
|
|
result = default_context_creation()
|
|
or
|
|
result = specific_context_creation() and
|
|
result.(ContextCreation).getProtocol() = unspecific_version(family)
|
|
}
|
|
|
|
/** A connection is created in an insecure manner, not from a context. */
|
|
abstract DataFlow::CfgNode insecure_connection_creation(ProtocolVersion version);
|
|
|
|
/** A connection is created from a context. */
|
|
abstract ConnectionCreation connection_creation();
|
|
|
|
/** A context is being restricted on which protocols it can accepts. */
|
|
abstract ProtocolRestriction protocol_restriction();
|
|
|
|
/** A context is being relaxed on which protocols it can accepts. */
|
|
abstract ProtocolUnrestriction protocol_unrestriction();
|
|
}
|