CVE-2023-37471: Improper Authentication (CWE-287)
value: Open Access Management (OpenAM) is an access management solution that includes Authentication, SSO, Authorization, Federation, Entitlements and Web Services Security. OpenAM up to version 14.7.2 does not properly validate the signature of SAML responses received as part of the SAMLv1.x Single Sign-On process. Attackers can use this fact to impersonate any OpenAM user, including the administrator, by sending a specially crafted SAML response to the SAMLPOSTProfileServlet servlet. This problem has been patched in  OpenAM 14.7.3-SNAPSHOT and later. User unable to upgrade should comment servlet `SAMLPOSTProfileServlet` from their pom file. See the linked GHSA for details.
CWE description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
CVSS v3 base score: 9.8
Published: 2023-07-20T17:15Z
Repository: https://github.com/OpenIdentityPlatform/OpenAM
Language: Java
Files changed: openam-federation/openam-federation-library/src/main/java/com/sun/identity/saml/common/SAMLUtils.java
Commit date: 2023-07-18 16:05:03 +0300
Commit message: GHSL-2023-143, GHSL-2023-144, deny unsigned SAML response (#624)


Diff: diff --git a/openam-federation/openam-federation-library/src/main/java/com/sun/identity/saml/common/SAMLUtils.java b/openam-federation/openam-federation-library/src/main/java/com/sun/identity/saml/common/SAMLUtils.java
index 7e78b60e4..6c8c90e16 100644
--- a/openam-federation/openam-federation-library/src/main/java/com/sun/identity/saml/common/SAMLUtils.java
+++ b/openam-federation/openam-federation-library/src/main/java/com/sun/identity/saml/common/SAMLUtils.java
@@ -949,10 +949,14 @@ public class SAMLUtils  extends SAMLUtilsCommon {
      * @param request <code>HttpServletRequest</code> object
      * @return true if the response is valid; false otherwise.
      */
     public static boolean verifyResponse(Response response,
     String requestUrl, HttpServletRequest request) {
+        if(!response.isSigned()) {
+            debug.message("verifyResponse: Response is not signed");
+            return false;
+        }
         if (!response.isSignatureValid()) {
             debug.message("verifyResponse: Response's signature is invalid.");
             return false;
         }
 
@@ -1583,17 +1587,17 @@ public class SAMLUtils  extends SAMLUtilsCommon {
     public static Map processResponse(Response samlResponse, String target) 
         throws SAMLException {
         List assertions = null;    
         SAMLServiceManager.SOAPEntry partnerdest = null;
         Subject assertionSubject = null;
-        if (samlResponse.isSigned()) {
-            // verify the signature
-            boolean isSignedandValid = verifySignature(samlResponse);
-            if (!isSignedandValid) {
-                throw new SAMLException(bundle.getString("invalidResponse"));
-            }
+
+        // verify the signature
+        boolean isSignedandValid = verifySignature(samlResponse);
+        if (!isSignedandValid) {
+            throw new SAMLException(bundle.getString("invalidResponse"));
         }
+
         // check Assertion and get back a Map of relevant data including,
         // Subject, SOAPEntry for the partner and the List of Assertions.
         Map ssMap = verifyAssertionAndGetSSMap(samlResponse);
         if (debug.messageEnabled()) {
             debug.message("processResponse: ssMap = " + ssMap);

Vulnerable code:         if (samlResponse.isSigned()) {
            // verify the signature
            boolean isSignedandValid = verifySignature(samlResponse);
            if (!isSignedandValid) {
                throw new SAMLException(bundle.getString("invalidResponse"));
            }
Fixed code:         if(!response.isSigned()) {
            debug.message("verifyResponse: Response is not signed");
            return false;
        }

        // verify the signature
        boolean isSignedandValid = verifySignature(samlResponse);
        if (!isSignedandValid) {
            throw new SAMLException(bundle.getString("invalidResponse"));