-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathTlsLibraryModel.qll
More file actions
142 lines (114 loc) · 5.09 KB
/
TlsLibraryModel.qll
File metadata and controls
142 lines (114 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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();
}