mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
Merge pull request #3438 from artem-smotrakov/unsafe-tls
Java: Added a query for unsafe TLS versions
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
public SSLSocket connect(String host, int port)
|
||||
throws NoSuchAlgorithmException, IOException {
|
||||
|
||||
SSLContext context = SSLContext.getInstance("TLSv1.3");
|
||||
return (SSLSocket) context.getSocketFactory().createSocket(host, port);
|
||||
}
|
||||
111
java/ql/src/experimental/Security/CWE/CWE-327/SslLib.qll
Normal file
111
java/ql/src/experimental/Security/CWE/CWE-327/SslLib.qll
Normal file
@@ -0,0 +1,111 @@
|
||||
import java
|
||||
import semmle.code.java.security.Encryption
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow
|
||||
import PathGraph
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe SSL and TLS versions.
|
||||
*/
|
||||
class UnsafeTlsVersionConfig extends TaintTracking::Configuration {
|
||||
UnsafeTlsVersionConfig() { this = "UnsafeTlsVersion::UnsafeTlsVersionConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof UnsafeTlsVersion }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof SslContextGetInstanceSink or
|
||||
sink instanceof CreateSslParametersSink or
|
||||
sink instanceof SslParametersSetProtocolsSink or
|
||||
sink instanceof SetEnabledProtocolsSink
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink that sets protocol versions in `SSLContext`,
|
||||
* i.e `SSLContext.getInstance(protocol)`.
|
||||
*/
|
||||
class SslContextGetInstanceSink extends DataFlow::ExprNode {
|
||||
SslContextGetInstanceSink() {
|
||||
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
|
||||
m.getDeclaringType() instanceof SSLContext and
|
||||
m.hasName("getInstance") and
|
||||
ma.getArgument(0) = asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink that creates `SSLParameters` with specified protocols,
|
||||
* i.e. `new SSLParameters(ciphersuites, protocols)`.
|
||||
*/
|
||||
class CreateSslParametersSink extends DataFlow::ExprNode {
|
||||
CreateSslParametersSink() {
|
||||
exists(ConstructorCall cc | cc.getConstructedType() instanceof SSLParameters |
|
||||
cc.getArgument(1) = asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink that sets protocol versions for `SSLParameters`,
|
||||
* i.e. `parameters.setProtocols(versions)`.
|
||||
*/
|
||||
class SslParametersSetProtocolsSink extends DataFlow::ExprNode {
|
||||
SslParametersSetProtocolsSink() {
|
||||
exists(MethodAccess ma, Method m | m = ma.getMethod() |
|
||||
m.getDeclaringType() instanceof SSLParameters and
|
||||
m.hasName("setProtocols") and
|
||||
ma.getArgument(0) = asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink that sets protocol versions fro `SSLSocket`, `SSLServerSocket` and `SSLEngine`,
|
||||
* i.e. `socket.setEnabledProtocols(versions)` or `engine.setEnabledProtocols(versions)`.
|
||||
*/
|
||||
class SetEnabledProtocolsSink extends DataFlow::ExprNode {
|
||||
SetEnabledProtocolsSink() {
|
||||
exists(MethodAccess ma, Method m, RefType type |
|
||||
m = ma.getMethod() and type = m.getDeclaringType()
|
||||
|
|
||||
(
|
||||
type instanceof SSLSocket or
|
||||
type instanceof SSLServerSocket or
|
||||
type instanceof SSLEngine
|
||||
) and
|
||||
m.hasName("setEnabledProtocols") and
|
||||
ma.getArgument(0) = asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insecure SSL and TLS versions supported by JSSE.
|
||||
*/
|
||||
class UnsafeTlsVersion extends StringLiteral {
|
||||
UnsafeTlsVersion() {
|
||||
getValue() = "SSL" or
|
||||
getValue() = "SSLv2" or
|
||||
getValue() = "SSLv3" or
|
||||
getValue() = "TLS" or
|
||||
getValue() = "TLSv1" or
|
||||
getValue() = "TLSv1.1"
|
||||
}
|
||||
}
|
||||
|
||||
class SSLParameters extends RefType {
|
||||
SSLParameters() { hasQualifiedName("javax.net.ssl", "SSLParameters") }
|
||||
}
|
||||
|
||||
class SSLSocket extends RefType {
|
||||
SSLSocket() { hasQualifiedName("javax.net.ssl", "SSLSocket") }
|
||||
}
|
||||
|
||||
class SSLServerSocket extends RefType {
|
||||
SSLServerSocket() { hasQualifiedName("javax.net.ssl", "SSLServerSocket") }
|
||||
}
|
||||
|
||||
class SSLEngine extends RefType {
|
||||
SSLEngine() { hasQualifiedName("javax.net.ssl", "SSLEngine") }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public SSLSocket connect(String host, int port)
|
||||
throws NoSuchAlgorithmException, IOException {
|
||||
|
||||
SSLContext context = SSLContext.getInstance("SSLv3");
|
||||
return (SSLSocket) context.getSocketFactory().createSocket(host, port);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Transport Layer Security (TLS) provides a number of security features such as
|
||||
confidentiality, integrity, replay prevention and authenticatin.
|
||||
There are several versions of TLS protocols. The latest is TLS 1.3.
|
||||
Unfortunately, older versions were found to be vulnerable to a number of attacks.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>An application should use TLS 1.3. Currenlty, TLS 1.2 is also considered acceptable.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>The following example shows how a socket with an unsafe TLS version may be created:</p>
|
||||
|
||||
<sample src="UnsafeTLSVersion.java" />
|
||||
|
||||
<p>The next example creates a socket with the latest TLS version:</p>
|
||||
|
||||
<sample src="SaferTLSVersion.java" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
Wikipedia:
|
||||
<a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">Transport Layer Security</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html">Transport Layer Protection Cheat Sheet</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Java SE Documentation:
|
||||
<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">Java Secure Socket Extension (JSSE) Reference Guide</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Java SE API Specification:
|
||||
<a href="https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLContext.html">SSLContext</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Java SE API Specification:
|
||||
<a href="https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLParameters.html">SSLParameters</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Java SE API Specification:
|
||||
<a href="https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLSocket.html">SSLSocket</a>
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Unsafe TLS version
|
||||
* @description SSL and older TLS versions are known to be vulnerable.
|
||||
* TLS 1.3 or at least TLS 1.2 should be used.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/unsafe-tls-version
|
||||
* @tags security
|
||||
* external/cwe/cwe-327
|
||||
*/
|
||||
|
||||
import java
|
||||
import SslLib
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, UnsafeTlsVersionConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ is unsafe", source.getNode(),
|
||||
source.getNode().asExpr().(StringLiteral).getValue()
|
||||
Reference in New Issue
Block a user