CVE-2010-10006: Observable Timing Discrepancy (CWE-208)
value: A vulnerability, which was classified as problematic, was found in michaelliao jopenid. Affected is the function getAuthentication of the file JOpenId/src/org/expressme/openid/OpenIdManager.java. The manipulation leads to observable timing discrepancy. The complexity of an attack is rather high. The exploitability is told to be difficult. Upgrading to version 1.08 is able to address this issue. The name of the patch is c9baaa976b684637f0d5a50268e91846a7a719ab. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-218460.
CWE description: Two separate operations in a product require different amounts of time to complete, in a way that is observable to an actor and reveals security-relevant information about the state of the product, such as whether a particular operation was successful or not.
CVSS v3 base score: 7.5
Published: 2023-01-18T00:15Z
Repository: https://github.com/michaelliao/jopenid
Language: Java
Files changed: JOpenId/src/org/expressme/openid/OpenIdManager.java
Commit date: 2010-07-15 14:27:13 +0000
Commit message: fix timing vulnerability.
Diff: diff --git a/JOpenId/src/org/expressme/openid/OpenIdManager.java b/JOpenId/src/org/expressme/openid/OpenIdManager.java
index b9a9518..6524412 100644
--- a/JOpenId/src/org/expressme/openid/OpenIdManager.java
+++ b/JOpenId/src/org/expressme/openid/OpenIdManager.java
@@ -108,13 +108,13 @@ public class OpenIdManager {
             if (value!=null)
                 sb.append(value);
             sb.append('\n');
         }
         String hmac = getHmacSha1(sb.toString(), key);
-        if (!sig.equals(hmac))
+        if (!safeEquals(sig, hmac))
             throw new OpenIdException("Verify signature failed.");
-        
+
         // set auth:
         Authentication auth = new Authentication();
         auth.setIdentity(identity);
         auth.setEmail(request.getParameter("openid." + alias + ".value.email"));
         auth.setLanguage(request.getParameter("openid." + alias + ".value.language"));
@@ -123,10 +123,22 @@ public class OpenIdManager {
         auth.setFirstname(getFirstname(request, alias));
         auth.setLastname(getLastname(request, alias));
         return auth;
     }
 
+    boolean safeEquals(String s1, String s2) {
+        if (s1.length()!=s2.length())
+            return false;
+        int result = 0;
+        for (int i=0; i<s1.length(); i++) {
+            int c1 = s1.charAt(i);
+            int c2 = s2.charAt(i);
+            result |= (c1 ^c2);
+        }
+        return result==0;
+    }
+
     String getLastname (HttpServletRequest request, String axa) {
     	String name = request.getParameter("openid." + axa + ".value.lastname");
     	// If lastname is not supported try to get it from the fullname
     	if (name == null) {
     		name = request.getParameter("openid." + axa + ".value.fullname");

Vulnerable code:         if (!sig.equals(hmac))
        
Fixed code:         if (!safeEquals(sig, hmac))

    boolean safeEquals(String s1, String s2) {
        if (s1.length()!=s2.length())
            return false;
        int result = 0;
        for (int i=0; i<s1.length(); i++) {
            int c1 = s1.charAt(i);
            int c2 = s2.charAt(i);
            result |= (c1 ^c2);
        }
        return result==0;
    }