Skip to content

Commit 253e80d

Browse files
committed
🐛 constant-time HMAC security fix
1 parent 19e2f43 commit 253e80d

2 files changed

Lines changed: 9 additions & 2 deletions

File tree

‎src/main/java/com/mindee/parsing/BaseLocalResponse.java‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ public boolean isValidHmacSignature(String secretKey, String signature) {
107107
if (signature == null || secretKey == null) {
108108
return false;
109109
}
110-
byte[] expectedBytes = getHmacSignature(secretKey).getBytes(StandardCharsets.UTF_8);
110+
String expectedString = getHmacSignature(secretKey);
111+
if (expectedString.isEmpty()) {
112+
return false;
113+
}
114+
byte[] expectedBytes = expectedString.getBytes(StandardCharsets.UTF_8);
111115
byte[] actualBytes = signature
112116
.toLowerCase(java.util.Locale.ROOT)
113117
.getBytes(StandardCharsets.UTF_8);

‎src/test/java/com/mindee/v2/parsing/LocalResponseTest.java‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ public class LocalResponseTest {
1919
private static final String DUMMY_SECRET_KEY = "ogNjY44MhvKPGTtVsI8zG82JqWQa68woYQH";
2020

2121
private static void assertLocalResponse(LocalResponse localResponse) {
22+
assertEquals(SIGNATURE, localResponse.getHmacSignature(DUMMY_SECRET_KEY));
23+
2224
assertFalse(localResponse.isValidHmacSignature(DUMMY_SECRET_KEY, "invalid signature"));
2325
assertFalse(localResponse.isValidHmacSignature(DUMMY_SECRET_KEY, null));
2426
assertFalse(localResponse.isValidHmacSignature(null, SIGNATURE));
2527
assertFalse(localResponse.isValidHmacSignature(null, null));
26-
assertEquals(SIGNATURE, localResponse.getHmacSignature(DUMMY_SECRET_KEY));
28+
assertFalse(localResponse.isValidHmacSignature(DUMMY_SECRET_KEY, ""));
2729
assertTrue(localResponse.isValidHmacSignature(DUMMY_SECRET_KEY, SIGNATURE));
30+
assertTrue(localResponse.isValidHmacSignature(DUMMY_SECRET_KEY, SIGNATURE.toUpperCase()));
2831

2932
ExtractionResponse response = localResponse.deserializeResponse(ExtractionResponse.class);
3033
assertNotNull(response, "Loaded ExtractionResponse must not be null");

0 commit comments

Comments
 (0)