CVE-2020-6950: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') (CWE-22)
value: Directory traversal in Eclipse Mojarra before 2.3.14 allows attackers to read arbitrary files via the loc parameter or con parameter.
CWE description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
CVSS v3 base score: 6.5
Published: 2021-06-02T16:15Z
Repository: https://github.com/eclipse-ee4j/mojarra
Language: Java
Files changed: impl/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java, impl/src/main/java/com/sun/faces/application/resource/ResourceManager.java, impl/src/main/java/com/sun/faces/application/resource/WebappResourceHelper.java
Commit date: 2019-09-05 16:12:40 +0800
Commit message: Multiple Path Traversal security issues

Diff: diff --git a/impl/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java b/impl/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java
index 9a81ee1a..c745b934 100644
--- a/impl/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java
+++ b/impl/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java
@@ -353,11 +353,11 @@ public class ClasspathResourceHelper extends ResourceHelper {
                 contracts.add(library.getContract());
             }
         } else if (root == null) {
             String contractName = ctx.getExternalContext().getRequestParameterMap()
                   .get("con");
-            if (null != contractName && 0 < contractName.length()) {
+            if (null != contractName && 0 < contractName.length() && !ResourceManager.nameContainsForbiddenSequence(contractName)) {
                 contracts = new ArrayList<>();
                 contracts.add(contractName);
             } else {
                 return null;
             }
diff --git a/impl/src/main/java/com/sun/faces/application/resource/ResourceManager.java b/impl/src/main/java/com/sun/faces/application/resource/ResourceManager.java
index 53e0d645..a8344fb3 100644
--- a/impl/src/main/java/com/sun/faces/application/resource/ResourceManager.java
+++ b/impl/src/main/java/com/sun/faces/application/resource/ResourceManager.java
@@ -349,11 +349,11 @@ public class ResourceManager {
         } else {
             return s;
         }
     }
     
-    private static boolean nameContainsForbiddenSequence(String name) {
+    static boolean nameContainsForbiddenSequence(String name) {
         boolean result = false;
         if (name != null) {
             name = name.toLowerCase();
     
             result = name.startsWith(".") ||
@@ -565,10 +565,12 @@ public class ResourceManager {
         
         localePrefix = context.getExternalContext().getRequestParameterMap().get("loc");
         
         if(localePrefix != null && !nameContainsForbiddenSequence(localePrefix)){
             return localePrefix;
+        } else {
+            localePrefix = null; 
         }
         
         String appBundleName = context.getApplication().getMessageBundle();
         if (null != appBundleName) {
         	
diff --git a/impl/src/main/java/com/sun/faces/application/resource/WebappResourceHelper.java b/impl/src/main/java/com/sun/faces/application/resource/WebappResourceHelper.java
index 1c858079..2b3e89f7 100644
--- a/impl/src/main/java/com/sun/faces/application/resource/WebappResourceHelper.java
+++ b/impl/src/main/java/com/sun/faces/application/resource/WebappResourceHelper.java
@@ -313,11 +313,11 @@ public class WebappResourceHelper extends ResourceHelper {
                 contracts.add(library.getContract());
             }
         } else if (root == null) {
             String contractName = ctx.getExternalContext().getRequestParameterMap()
                   .get("con");
-            if (null != contractName && 0 < contractName.length()) {
+            if (null != contractName && 0 < contractName.length() && !ResourceManager.nameContainsForbiddenSequence(contractName)) {
                 contracts = new ArrayList<>();
                 contracts.add(contractName);
             } else {
                 return null;
             }

Vulnerable code:             if (null != contractName && 0 < contractName.length()) {
    private static boolean nameContainsForbiddenSequence(String name) {
            if (null != contractName && 0 < contractName.length()) {
Fixed code:             if (null != contractName && 0 < contractName.length() && !ResourceManager.nameContainsForbiddenSequence(contractName)) {
    static boolean nameContainsForbiddenSequence(String name) {
        } else {
            localePrefix = null; 
            if (null != contractName && 0 < contractName.length() && !ResourceManager.nameContainsForbiddenSequence(contractName)) {