sa-contrib-2018-077.patch 2.72 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
diff --git a/constraints/constraint_digit_placement.inc b/constraints/constraint_digit_placement.inc
index 3dbefff..2b8f131 100644
--- a/constraints/constraint_digit_placement.inc
+++ b/constraints/constraint_digit_placement.inc
@@ -32,13 +32,10 @@ function password_policy_constraint_digit_placement_error($constraint) {
  * Password validation.
  */
 function password_policy_constraint_digit_placement_validate($password, $constraint, $uid) {
-  $number_of_digits = 0;
-  for ($i=0; $i<10; $i++) {
-    // help string count by sending it a string instead of an int
-    $number_of_digits += substr_count($password, "$i");
-  }
-  if ($number_of_digits < (int)$constraint) {
-    return preg_match("/^(\d+)|(\d+)$/", $password) != 1;
+  $matches = array();
+  $num = preg_match_all('/[0-9]/', $password, $matches);
+  if ($num < (int) $constraint) {
+    return preg_match('/^(\d+)|(\d+)$/', $password) != 1;
   }
   return TRUE;
 }
diff --git a/password_policy.module b/password_policy.module
index bca58cf..1589d61 100644
--- a/password_policy.module
+++ b/password_policy.module
@@ -645,6 +645,15 @@ function password_policy_password_validate($form, &$form_state) {
   $account = isset($form['_account']['#value']) ? $form['_account']['#value'] : (object)array('uid' => 0);
 
   if (!empty($values['pass']) && !isset($values['auth_openid'])) {
+    // Validate length.
+    // Short-circuit validation if password exceeds Drupal maximum length as
+    // safeguard against potential DoS attacks.
+    if (_password_policy_is_form_password_too_long($form_state)) {
+      form_set_error('pass', t('Password exceeds maximum length. Please choose a shorter password.'));
+      return;
+    }
+
+    // Validate constraints.
     $error = _password_policy_constraint_validate($values['pass'], $account);
     if ($error) {
       form_set_error('pass', t('Your password has not met the following requirement(s):') . '<ul><li>' . implode('</li><li>', $error) . '</li></ul>');
@@ -652,6 +661,24 @@ function password_policy_password_validate($form, &$form_state) {
   }
 }
 
+/**
+ * Determines whether password on form exceeds Drupal maximum length.
+ *
+ * The maximum length is copied from includes/password.inc.
+ *
+ * @param array $form_state
+ *   Form state.
+ *
+ * @return bool
+ *   TRUE if password exceeds Drupal maximum length, FALSE otherwise.
+ *
+ * @see _password_crypt()
+ */
+function _password_policy_is_form_password_too_long(array $form_state) {
+  $pass = $form_state['values']['pass'];
+  return strlen($pass) > 512;
+}
+
 /****************************************************************************/
 /* Expired accounts UI                                                      */
 /****************************************************************************/