Vulnerability: Cryptographically weak CSRF tokens in Apache MyFaces In the default configuration, Apache MyFaces Core versions 2.2.0 to 2.2.13, 2.3.0 to 2.3.7, 2.3-next-M1 to 2.3-next-M4, and 3.0.0-RC1 use cryptographically weak implicit and explicit cross-site request forgery (CSRF) tokens. Due to that limitation, it is possible (although difficult) for an attacker to calculate a future CSRF token value and to use that value to trick a user into executing unwanted actions on an application.


Mitigation:
Existing web.xml configuration parameters can be used to direct
MyFaces to use SecureRandom for CSRF token generation:

org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN=secureRandom
org.apache.myfaces.RANDOM_KEY_IN_CSRF_SESSION_TOKEN=secureRandom
org.apache.myfaces.RANDOM_KEY_IN_WEBSOCKET_SESSION_TOKEN=secureRandom
Vulnerability ID: GHSA-gq67-pp9w-43gp
CWE: CWE-352
Severity score: 0
Project: https://github.com/apache/myfaces
Published: 2021-06-16
File: impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
Commit message: Merge pull request #132 from wtlucy/secureRandom_master

MYFACES-4373: prefer SecureRandom for token generation
Commit author: Thomas Andraschko

Vulnerable version (before fix):
 public class MyfacesConfig      * Adds a random key to the generated view state session token.      */     @JSFWebConfigParam(since="2.1.9, 2.0.15", expectedValues="secureRandom, random",              defaultValue="random", group="state")     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN             = "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN";     private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_DEFAULT = "random";     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_RANDOM = "random";          /**      * Set the default length of the random key added to the view state session token. public class MyfacesConfig             = "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITHM";     private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITHM_DEFAULT = "SHA1PRNG";          /**      * Defines how to generate the csrf session token.      */     @JSFWebConfigParam(since="2.2.0", expectedValues="secureRandom, random", defaultValue="none", group="state")     public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN             = "org.apache.myfaces.RANDOM_KEY_IN_CSRF_SESSION_TOKEN";     private static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_DEFAULT = "random";          public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";     public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_RANDOM = "random";          /**      * Indicates that the serialized state will be compressed before it is written to the session. By default true.

Fixed version (after fix):
 public class MyfacesConfig      * Adds a random key to the generated view state session token.      */     @JSFWebConfigParam(since="2.1.9, 2.0.15", expectedValues="secureRandom, random",              defaultValue="secureRandom", group="state")     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN             = "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN";     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_RANDOM = "random";     private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_DEFAULT = RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM;          /**      * Set the default length of the random key added to the view state session token. public class MyfacesConfig             = "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITHM";     private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITHM_DEFAULT = "SHA1PRNG";          public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";     public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_RANDOM = "random";          /**      * Defines how to generate the csrf session token.      */     @JSFWebConfigParam(since="2.2.0", expectedValues="secureRandom, random", defaultValue="secureRandom", group="state")     public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN             = "org.apache.myfaces.RANDOM_KEY_IN_CSRF_SESSION_TOKEN";     private static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_DEFAULT = RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM;          /**      * Indicates that the serialized state will be compressed before it is written to the session. By default true.

Patch:
patch: @@ -459,12 +459,12 @@
      * Adds a random key to the generated view state session token.
      */
     @JSFWebConfigParam(since="2.1.9, 2.0.15", expectedValues="secureRandom, random", 
-            defaultValue="random", group="state")
+            defaultValue="secureRandom", group="state")
     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN
             = "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN";
-    private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_DEFAULT = "random";
     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";
     public static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_RANDOM = "random";
+    private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_DEFAULT = RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM;
     
     /**
      * Set the default length of the random key added to the view state session token.
@@ -499,16 +499,16 @@
             = "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITHM";
     private static final String RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITHM_DEFAULT = "SHA1PRNG";
     
+    public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";
+    public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_RANDOM = "random";
+    
     /**
      * Defines how to generate the csrf session token.
      */
-    @JSFWebConfigParam(since="2.2.0", expectedValues="secureRandom, random", defaultValue="none", group="state")
+    @JSFWebConfigParam(since="2.2.0", expectedValues="secureRandom, random", defaultValue="secureRandom", group="state")
     public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN
             = "org.apache.myfaces.RANDOM_KEY_IN_CSRF_SESSION_TOKEN";
-    private static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_DEFAULT = "random";
-    
-    public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM = "secureRandom";
-    public static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_RANDOM = "random";
+    private static final String RANDOM_KEY_IN_CSRF_SESSION_TOKEN_DEFAULT = RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM;
     
     /**
      * Indicates that the serialized state will be compressed before it is written to the session. By default true.
path: impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java