mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
138 lines
5.1 KiB
Plaintext
138 lines
5.1 KiB
Plaintext
private import python
|
|
private import semmle.python.ApiGraphs
|
|
import Ssl
|
|
import PyOpenSSL
|
|
|
|
/**
|
|
* A specific protocol version of SSL or TLS.
|
|
*/
|
|
class ProtocolVersion extends string {
|
|
ProtocolVersion() { this in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] }
|
|
|
|
/** Gets a `ProtocolVersion` that is less than this `ProtocolVersion`, if any. */
|
|
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"
|
|
}
|
|
|
|
/** Holds if this protocol version is known to be insecure. */
|
|
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::Node {
|
|
/** Gets the protocol version or family for this context. */
|
|
abstract string getProtocol();
|
|
}
|
|
|
|
/** The creation of a connection from a context. */
|
|
abstract class ConnectionCreation extends DataFlow::Node {
|
|
/** Gets the context used to create the connection. */
|
|
abstract DataFlow::Node getContext();
|
|
}
|
|
|
|
/** A context is being restricted on which protocols it can accepts. */
|
|
abstract class ProtocolRestriction extends DataFlow::Node {
|
|
/** Gets the context being restricted. */
|
|
abstract DataFlow::Node 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::Node {
|
|
/** Gets the context being relaxed. */
|
|
abstract DataFlow::Node 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() = family }
|
|
|
|
override DataFlow::CfgNode getContext() { result = this }
|
|
|
|
override ProtocolVersion getUnrestriction() {
|
|
// There is only one family, the two names are aliases in OpenSSL.
|
|
// see https://github.com/openssl/openssl/blob/13888e797c5a3193e91d71e5f5a196a2d68d266f/include/openssl/ssl.h.in#L1953-L1955
|
|
family in ["SSLv23", "TLS"] and
|
|
// see https://docs.python.org/3/library/ssl.html#ssl-contexts
|
|
result in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"]
|
|
}
|
|
}
|
|
|
|
/** A model of a SSL/TLS library. */
|
|
abstract class TlsLibrary extends string {
|
|
bindingset[this]
|
|
TlsLibrary() { any() }
|
|
|
|
/** The name of a specific protocol version. */
|
|
abstract string specific_version_name(ProtocolVersion version);
|
|
|
|
/** Gets a name, which is a member of `version_constants`, that can be used to specify the protocol family `family`. */
|
|
abstract string unspecific_version_name(ProtocolFamily family);
|
|
|
|
/** Gets an API node representing the module or class holding the version constants. */
|
|
abstract API::Node version_constants();
|
|
|
|
/** Gets an API node representing a specific protocol version. */
|
|
API::Node specific_version(ProtocolVersion version) {
|
|
result = version_constants().getMember(specific_version_name(version))
|
|
}
|
|
|
|
/** Gets an API node representing the protocol family `family`. */
|
|
API::Node unspecific_version(ProtocolFamily family) {
|
|
result = version_constants().getMember(unspecific_version_name(family))
|
|
}
|
|
|
|
/** Gets a creation of a context with a default protocol. */
|
|
abstract ContextCreation default_context_creation();
|
|
|
|
/** Gets a creation of a context with a specific protocol. */
|
|
abstract ContextCreation specific_context_creation();
|
|
|
|
/** Gets a creation of a context with a specific protocol version, known to be insecure. */
|
|
ContextCreation insecure_context_creation(ProtocolVersion version) {
|
|
result in [specific_context_creation(), default_context_creation()] and
|
|
result.getProtocol() = version and
|
|
version.isInsecure()
|
|
}
|
|
|
|
/** Gets a context that was created using `family`, known to have insecure instances. */
|
|
ContextCreation unspecific_context_creation(ProtocolFamily family) {
|
|
result in [specific_context_creation(), default_context_creation()] and
|
|
result.getProtocol() = family
|
|
}
|
|
|
|
/** Gets a dataflow node representing a connection being created in an insecure manner, not from a context. */
|
|
abstract DataFlow::Node insecure_connection_creation(ProtocolVersion version);
|
|
|
|
/** Gets a dataflow node representing a connection being created from a context. */
|
|
abstract ConnectionCreation connection_creation();
|
|
|
|
/** Gets a dataflow node representing a context being restricted on which protocols it can accepts. */
|
|
abstract ProtocolRestriction protocol_restriction();
|
|
|
|
/** Gets a dataflow node representing a context being relaxed on which protocols it can accepts. */
|
|
abstract ProtocolUnrestriction protocol_unrestriction();
|
|
}
|