This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-codec.git


The following commit(s) were added to refs/heads/master by this push:
     new ad28b0f1 Md5Crypt now throws IllegalArgumentException on an invalid 
prefix
ad28b0f1 is described below

commit ad28b0f1ea4010dc0eaeb1d1cda041efe0ef7323
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Thu May 16 16:44:32 2024 -0400

    Md5Crypt now throws IllegalArgumentException on an invalid prefix
---
 src/changes/changes.xml                                    |  1 +
 .../java/org/apache/commons/codec/digest/Md5Crypt.java     | 14 +++++++++++---
 .../java/org/apache/commons/codec/digest/Md5CryptTest.java | 10 ++++++++++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 25c5bb19..f9094328 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -45,6 +45,7 @@ The <action> type attribute can be add,update,fix,remove.
   <body>
     <release version="1.17.1" date="YYYY-MM-DD" description="Feature and fix 
release. Requires a minimum of Java 8.">
       <!-- FIX -->
+      <action type="fix" dev="ggregory" due-to="Gary Gregory">Md5Crypt now 
throws IllegalArgumentException on an invalid prefix.</action>
       <!-- ADD -->
       <!-- UPDATE -->
     </release>
diff --git a/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java 
b/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java
index 05c6a6ce..7d25225c 100644
--- a/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java
+++ b/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java
@@ -20,6 +20,7 @@ import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.SecureRandom;
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -238,7 +239,7 @@ public class Md5Crypt {
      *            real salt value without prefix or "rounds=". The salt may be 
null, in which case a salt
      *            is generated for you using {@link SecureRandom}.
      * @param prefix
-     *            salt prefix
+     *            The salt prefix {@value #APR1_PREFIX}, {@value #MD5_PREFIX}.
      * @return the hash value
      * @throws IllegalArgumentException
      *             if the salt does not match the allowed pattern
@@ -261,13 +262,13 @@ public class Md5Crypt {
      *            real salt value without prefix or "rounds=". The salt may be 
null, in which case a salt
      *            is generated for you using {@link SecureRandom}.
      * @param prefix
-     *            salt prefix
+     *            The salt prefix {@value #APR1_PREFIX}, {@value #MD5_PREFIX}.
      * @param random
      *            the instance of {@link Random} to use for generating the 
salt.
      *            Consider using {@link SecureRandom} for more secure salts.
      * @return the hash value
      * @throws IllegalArgumentException
-     *             if the salt does not match the allowed pattern
+     *             if the salt or prefix does not match the allowed pattern
      * @throws IllegalArgumentException
      *             when a {@link java.security.NoSuchAlgorithmException} is 
caught.
      * @since 1.12
@@ -280,6 +281,13 @@ public class Md5Crypt {
         if (salt == null) {
             saltString = B64.getRandomSalt(8, random);
         } else {
+            Objects.requireNonNull(prefix, "prefix");
+            if (prefix.length() < 3) {
+                throw new IllegalArgumentException("Invalid prefix value: " + 
prefix);
+            }
+            if (prefix.charAt(0) != '$' && prefix.charAt(prefix.length() - 1) 
!= '$') {
+                throw new IllegalArgumentException("Invalid prefix value: " + 
prefix);
+            }
             final Pattern p = Pattern.compile("^" + prefix.replace("$", "\\$") 
+ "([\\.\\/a-zA-Z0-9]{1,8}).*");
             final Matcher m = p.matcher(salt);
             if (!m.find()) {
diff --git a/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java 
b/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java
index 8eac52f9..cad63b28 100644
--- a/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java
+++ b/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java
@@ -35,6 +35,16 @@ public class Md5CryptTest {
         assertNotNull(new Md5Crypt()); // for code-coverage
     }
 
+    @Test
+    public void testInvalidPrefix() {
+        assertThrows(IllegalArgumentException.class, () -> 
Md5Crypt.md5Crypt(new byte[] { 1, 2, 3, 4, 5 },
+                
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!",
 "(.*a){10000}"));
+        assertThrows(IllegalArgumentException.class, () -> 
Md5Crypt.md5Crypt(new byte[] { 1, 2, 3, 4, 5 },
+                
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!",
 "$(.*a){10000}$"));
+        assertThrows(IllegalArgumentException.class, () -> 
Md5Crypt.md5Crypt(new byte[] { 1, 2, 3, 4, 5 },
+                
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 "$(.*a){10000}$"));
+    }
+
     @Test
     public void testMd5CryptBytes() {
         // An empty Bytearray equals an empty String

Reply via email to