Skip to content

Commit bab6f37

Browse files
Java: Added a query for unsafe TLS versions
- Added experimental/Security/CWE/CWE-327/UnsafeTlsVersion.ql - Added SslLib.qll - Added a qhelp file with examples - Added tests in java/ql/test/experimental/Security/CWE/CWE-327
1 parent c54f8d8 commit bab6f37

File tree

8 files changed

+478
-0
lines changed

8 files changed

+478
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public SSLSocket connect(String host, int port)
2+
throws NoSuchAlgorithmException, IOException {
3+
4+
SSLContext context = SSLContext.getInstance("TLSv1.3");
5+
return (SSLSocket) context.getSocketFactory().createSocket(host, port);
6+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import java
2+
import semmle.code.java.security.Encryption
3+
import semmle.code.java.dataflow.TaintTracking
4+
import DataFlow
5+
import PathGraph
6+
7+
/**
8+
* A taint-tracking configuration for unsafe SSL and TLS versions.
9+
*/
10+
class UnsafeTlsVersionConfig extends TaintTracking::Configuration {
11+
UnsafeTlsVersionConfig() { this = "UnsafeTlsVersion::UnsafeTlsVersionConfig" }
12+
13+
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof UnsafeTlsVersion }
14+
15+
override predicate isSink(DataFlow::Node sink) {
16+
sink instanceof SslContextGetInstanceSink or
17+
sink instanceof CreateSslParametersSink or
18+
sink instanceof SslParametersSetProtocolsSink or
19+
sink instanceof SetEnabledProtocolsSink
20+
}
21+
}
22+
23+
/**
24+
* A sink that sets protocol versions in `SSLContext`,
25+
* i.e `SSLContext.getInstance(protocol)`.
26+
*/
27+
class SslContextGetInstanceSink extends DataFlow::ExprNode {
28+
SslContextGetInstanceSink() {
29+
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
30+
m.getDeclaringType() instanceof SSLContext and
31+
m.hasName("getInstance") and
32+
ma.getArgument(0) = asExpr()
33+
)
34+
}
35+
}
36+
37+
/**
38+
* A sink that creates `SSLParameters` with specified protocols,
39+
* i.e. `new SSLParameters(ciphersuites, protocols)`.
40+
*/
41+
class CreateSslParametersSink extends DataFlow::ExprNode {
42+
CreateSslParametersSink() {
43+
exists(ConstructorCall cc | cc.getConstructedType() instanceof SSLParameters |
44+
cc.getArgument(1) = asExpr()
45+
)
46+
}
47+
}
48+
49+
/**
50+
* A sink that sets protocol versions for `SSLParameters`,
51+
* i.e. `parameters.setProtocols(versions)`.
52+
*/
53+
class SslParametersSetProtocolsSink extends DataFlow::ExprNode {
54+
SslParametersSetProtocolsSink() {
55+
exists(MethodAccess ma, Method m | m = ma.getMethod() |
56+
m.getDeclaringType() instanceof SSLParameters and
57+
m.hasName("setProtocols") and
58+
ma.getArgument(0) = asExpr()
59+
)
60+
}
61+
}
62+
63+
/**
64+
* A sink that sets protocol versions fro `SSLSocket`, `SSLServerSocket` and `SSLEngine`,
65+
* i.e. `socket.setEnabledProtocols(versions)` or `engine.setEnabledProtocols(versions)`.
66+
*/
67+
class SetEnabledProtocolsSink extends DataFlow::ExprNode {
68+
SetEnabledProtocolsSink() {
69+
exists(MethodAccess ma, Method m, RefType type |
70+
m = ma.getMethod() and type = m.getDeclaringType()
71+
|
72+
(
73+
type instanceof SSLSocket or
74+
type instanceof SSLServerSocket or
75+
type instanceof SSLEngine
76+
) and
77+
m.hasName("setEnabledProtocols") and
78+
ma.getArgument(0) = asExpr()
79+
)
80+
}
81+
}
82+
83+
/**
84+
* Insecure SSL and TLS versions supported by JSSE.
85+
*/
86+
class UnsafeTlsVersion extends StringLiteral {
87+
UnsafeTlsVersion() {
88+
getValue() = "SSL" or
89+
getValue() = "SSLv2" or
90+
getValue() = "SSLv3" or
91+
getValue() = "TLS" or
92+
getValue() = "TLSv1" or
93+
getValue() = "TLSv1.1"
94+
}
95+
}
96+
97+
class SSLParameters extends RefType {
98+
SSLParameters() { hasQualifiedName("javax.net.ssl", "SSLParameters") }
99+
}
100+
101+
class SSLSocket extends RefType {
102+
SSLSocket() { hasQualifiedName("javax.net.ssl", "SSLSocket") }
103+
}
104+
105+
class SSLServerSocket extends RefType {
106+
SSLServerSocket() { hasQualifiedName("javax.net.ssl", "SSLServerSocket") }
107+
}
108+
109+
class SSLEngine extends RefType {
110+
SSLEngine() { hasQualifiedName("javax.net.ssl", "SSLEngine") }
111+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public SSLSocket connect(String host, int port)
2+
throws NoSuchAlgorithmException, IOException {
3+
4+
SSLContext context = SSLContext.getInstance("SSLv3");
5+
return (SSLSocket) context.getSocketFactory().createSocket(host, port);
6+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
4+
<overview>
5+
<p>Transport Layer Security (TLS) provides a number of security features such as
6+
confidentiality, integrity, replay prevention and authenticatin.
7+
There are several versions of TLS protocols. The latest is TLS 1.3.
8+
Unfortunately, older versions were found to be vulnerable to a number of attacks.</p>
9+
10+
</overview>
11+
<recommendation>
12+
13+
<p>An application should use TLS 1.3. Currenlty, TLS 1.2 is also considered acceptable.</p>
14+
15+
</recommendation>
16+
<example>
17+
18+
<p>The following example shows how a socket with an unsafe TLS version may be created:</p>
19+
20+
<sample src="UnsafeTLSVersion.java" />
21+
22+
<p>The next example creates a socket with the latest TLS version:</p>
23+
24+
<sample src="SaferTLSVersion.java" />
25+
26+
</example>
27+
<references>
28+
29+
<li>
30+
Wikipedia:
31+
<a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">Transport Layer Security</a>
32+
</li>
33+
34+
<li>
35+
OWASP:
36+
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html">Transport Layer Protection Cheat Sheet</a>
37+
</li>
38+
39+
<li>
40+
Java SE Documentation:
41+
<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">Java Secure Socket Extension (JSSE) Reference Guide</a>
42+
</li>
43+
44+
<li>
45+
Java SE API Specification:
46+
<a href="https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLContext.html">SSLContext</a>
47+
</li>
48+
49+
<li>
50+
Java SE API Specification:
51+
<a href="https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLParameters.html">SSLParameters</a>
52+
</li>
53+
54+
<li>
55+
Java SE API Specification:
56+
<a href="https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLSocket.html">SSLSocket</a>
57+
</li>
58+
59+
</references>
60+
</qhelp>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @name Unsafe TLS version
3+
* @description SSL and older TLS versions are known to be vulnerable.
4+
* TLS 1.3 or at least TLS 1.2 should be used.
5+
* @kind path-problem
6+
* @problem.severity error
7+
* @precision high
8+
* @id java/unsafe-tls-version
9+
* @tags security
10+
* external/cwe/cwe-327
11+
*/
12+
13+
import java
14+
import SslLib
15+
import DataFlow::PathGraph
16+
17+
from DataFlow::PathNode source, DataFlow::PathNode sink, UnsafeTlsVersionConfig conf
18+
where conf.hasFlowPath(source, sink)
19+
select sink.getNode(), source, sink, "$@ is unsafe", source.getNode(),
20+
source.getNode().asExpr().(StringLiteral).getValue()

0 commit comments

Comments
 (0)