Skip to content

Commit ac79866

Browse files
Merge pull request #9982 from joefarebrother/rsa-without-oaep
Java: Add query for RSA without OAEP
2 parents a3f27d4 + e8f027d commit ac79866

File tree

8 files changed

+108
-0
lines changed

8 files changed

+108
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/** Definitions for the RSA without OAEP query */
2+
3+
import java
4+
import Encryption
5+
import semmle.code.java.dataflow.DataFlow
6+
7+
/** A configuration for finding RSA ciphers initialized without using OAEP padding. */
8+
class RsaWithoutOaepConfig extends DataFlow::Configuration {
9+
RsaWithoutOaepConfig() { this = "RsaWithoutOaepConfig" }
10+
11+
override predicate isSource(DataFlow::Node src) {
12+
exists(CompileTimeConstantExpr specExpr, string spec |
13+
specExpr.getStringValue() = spec and
14+
specExpr = src.asExpr() and
15+
spec.matches("RSA/%") and
16+
not spec.matches("%OAEP%")
17+
)
18+
}
19+
20+
override predicate isSink(DataFlow::Node sink) {
21+
exists(CryptoAlgoSpec cr | sink.asExpr() = cr.getAlgoSpec())
22+
}
23+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// BAD: No padding scheme is used
2+
Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding");
3+
...
4+
5+
//GOOD: OAEP padding is used
6+
Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
7+
...
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
4+
<overview>
5+
<p>Cryptographic algorithms often use padding schemes to make the plaintext less predictable. The OAEP (Optimal Asymmetric Encryption Padding) scheme should be used with RSA encryption.
6+
Using an outdated padding scheme such as PKCS1, or no padding at all, can weaken the encryption by making it vulnerable to a padding oracle attack.
7+
</p>
8+
</overview>
9+
10+
<recommendation>
11+
<p>Use the OAEP scheme when using RSA encryption.</p>
12+
</recommendation>
13+
14+
<example>
15+
<p>In the following example, the BAD case shows no padding being used, whereas the GOOD case shows an OAEP scheme being used.</p>
16+
<sample src="RsaWithoutOaep.java" />
17+
</example>
18+
19+
<references>
20+
<li>
21+
<a href="https://github.com/MobSF/owasp-mstg/blob/master/Document/0x04g-Testing-Cryptography.md#padding-oracle-attacks-due-to-weaker-padding-or-block-operation-implementations">Mobile Security Testing Guide</a>.
22+
</li>
23+
<li>
24+
<a href="https://robertheaton.com/2013/07/29/padding-oracle-attack/">The Padding Oracle Attack</a>.
25+
</li>
26+
</references>
27+
</qhelp>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @name Use of RSA algorithm without OAEP
3+
* @description Using RSA encryption without OAEP padding can result in a padding oracle attack, leading to a weaker encryption.
4+
* @kind path-problem
5+
* @problem.severity warning
6+
* @security-severity 7.5
7+
* @precision high
8+
* @id java/rsa-without-oaep
9+
* @tags security
10+
* external/cwe/cwe-780
11+
*/
12+
13+
import java
14+
import semmle.code.java.security.RsaWithoutOaepQuery
15+
import DataFlow::PathGraph
16+
17+
from RsaWithoutOaepConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
18+
where conf.hasFlowPath(source, sink)
19+
select source, source, sink,
20+
"This specification is used to initialize an RSA cipher without OAEP padding $@.", sink, "here"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: newQuery
3+
---
4+
* A new query "Use of RSA algorithm without OAEP" (`java/rsa-without-oaep`) has been added. This query finds uses of RSA encryption that don't use the OAEP scheme.

java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import javax.crypto.Cipher;
2+
3+
class RsaWithoutOaep {
4+
public void test() throws Exception {
5+
Cipher rsaBad = Cipher.getInstance("RSA/ECB/NoPadding"); // $hasTaintFlow
6+
7+
Cipher rsaGood = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
8+
}
9+
10+
public Cipher getCipher(String spec) throws Exception {
11+
return Cipher.getInstance(spec); // $hasTaintFlow
12+
}
13+
14+
public void test2() throws Exception {
15+
Cipher rsa = getCipher("RSA/ECB/NoPadding");
16+
}
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import java
2+
import TestUtilities.InlineExpectationsTest
3+
import TestUtilities.InlineFlowTest
4+
import semmle.code.java.security.RsaWithoutOaepQuery
5+
6+
class HasFlowTest extends InlineFlowTest {
7+
override DataFlow::Configuration getTaintFlowConfig() { result instanceof RsaWithoutOaepConfig }
8+
9+
override DataFlow::Configuration getValueFlowConfig() { none() }
10+
}

0 commit comments

Comments
 (0)