From e618c9c0f299a651be904a322e80c89bddb22de5 Mon Sep 17 00:00:00 2001
From: Thomas Florio <thomas.florio@suse.com>
Date: Tue, 28 Oct 2025 14:38:02 +0100
Subject: [PATCH] fix(security): Timing Attack Vulnerability

---
 checks/forbiddenapis.txt                                  | 2 ++
 .../main/java/com/ongres/scram/common/ScramFunctions.java | 8 ++++----
 scram-parent/pom.xml                                      | 3 +++
 3 files changed, 9 insertions(+), 4 deletions(-)
 create mode 100644 checks/forbiddenapis.txt

diff --git a/checks/forbiddenapis.txt b/checks/forbiddenapis.txt
new file mode 100644
index 0000000..57bd571
--- /dev/null
+++ b/checks/forbiddenapis.txt
@@ -0,0 +1,2 @@
+
+java.util.Arrays#equals(byte[],byte[]) @ Replace with java.security.MessageDigest#isEqual(byte[],byte[])
diff --git a/scram-common/src/main/java/com/ongres/scram/common/ScramFunctions.java b/scram-common/src/main/java/com/ongres/scram/common/ScramFunctions.java
index 43687c4..a129e55 100644
--- a/scram-common/src/main/java/com/ongres/scram/common/ScramFunctions.java
+++ b/scram-common/src/main/java/com/ongres/scram/common/ScramFunctions.java
@@ -7,8 +7,8 @@ package com.ongres.scram.common;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import java.security.MessageDigest;
 import java.security.SecureRandom;
-import java.util.Arrays;
 
 import com.ongres.scram.common.util.Preconditions;
 import org.jetbrains.annotations.NotNull;
@@ -190,8 +190,7 @@ public final class ScramFunctions {
     byte[] clientSignature = clientSignature(scramMechanism, storedKey, authMessage);
     byte[] clientKey = CryptoUtil.xor(clientSignature, clientProof);
     byte[] computedStoredKey = hash(scramMechanism, clientKey);
-
-    return Arrays.equals(storedKey, computedStoredKey);
+    return MessageDigest.isEqual(storedKey, computedStoredKey);
   }
 
   /**
@@ -205,7 +204,8 @@ public final class ScramFunctions {
    */
   public static boolean verifyServerSignature(
       ScramMechanism scramMechanism, byte[] serverKey, String authMessage, byte[] serverSignature) {
-    return Arrays.equals(serverSignature(scramMechanism, serverKey, authMessage), serverSignature);
+    byte[] computedServerSignature = serverSignature(scramMechanism, serverKey, authMessage);
+    return MessageDigest.isEqual(serverSignature, computedServerSignature);
   }
 
   /**
diff --git a/scram-parent/pom.xml b/scram-parent/pom.xml
index 77346b5..0be3191 100644
--- a/scram-parent/pom.xml
+++ b/scram-parent/pom.xml
@@ -529,6 +529,9 @@
                 <!-- don't allow System.out or System.err: -->
                 <bundledSignature>jdk-system-out</bundledSignature>
               </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${checks.location}/forbiddenapis.txt</signaturesFile>
+              </signaturesFiles>
             </configuration>
             <executions>
               <execution>
-- 
2.51.0

