View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update | 
|---|---|---|---|---|---|
| 0010318 | mantisbt | authentication | public | 2009-04-10 01:36 | 2025-04-13 15:18 | 
| Reporter | cigamit | Assigned To | |||
| Priority | normal | Severity | feature | Reproducibility | N/A | 
| Status | acknowledged | Resolution | open | ||
| Product Version | 1.1.6 | ||||
| Summary | 0010318: Allow for forcing of complex passwords | ||||
| Description | In order for Mantis to more closely adhere to DHS Sensitive Systems Policy Directive 4300A, more stringent password policies are necessary. While the DHS policy also covers items such as using a password history, I don't expect many of the policies to ever be implemented (or even really necessary). To start with, the most important of these policies is a configuration of a minimum password length, and the option to allow for forcing of more complex passwords. Attached is a patch which implements these with minimal impact to the code base (and end user). You will notice these 2 new options inside the config_default. 
EDIT (dregad): fix markdown  | ||||
| Additional Information | This bug is similar to 0009789. If I have more free time (I'm a developer on an open source php based project also!) I will see about submitting a patch for the temporarily locking of accounts for X minutes after Y failed login attempts within Z hours (which is a DHS requirement also).  | ||||
| Tags | passwords, patch, security | ||||
| Attached Files |  mantis_complex.patch (5,447 bytes)   
 
diff -Naur bugs-old/account_update.php bugs/account_update.php
--- bugs-old/account_update.php	2009-04-09 22:16:33.000000000 -0500
+++ bugs/account_update.php	2009-04-09 22:49:14.000000000 -0500
@@ -85,8 +85,29 @@
 			trigger_error( ERROR_USER_CREATE_PASSWORD_MISMATCH, ERROR );
 		} else {
 			if ( !auth_does_password_match( $t_user_id, $f_password ) ) {
-				user_set_password( $t_user_id, $f_password );
-				$t_password_updated = true;
+				$t_password_minimum = config_get( 'password_minimum' );
+				if (strlen($f_password) < $t_password_minimum) {
+					error_parameters( $t_password_minimum );
+					trigger_error( ERROR_USER_PASSWORD_TOO_SHORT, ERROR);
+				} else {
+					if (auth_is_password_complex($f_password)) {
+						user_set_password( $t_user_id, $f_password );
+						$t_password_updated = true;
+					} else {
+						$t_password_complexity = config_get( 'password_complexity' );
+						switch ( $t_password_complexity ) {
+							case 1:
+								trigger_error( ERROR_USER_PASSWORD_NOT_COMPLEX_1, ERROR );
+								break;
+							case 2:
+								trigger_error( ERROR_USER_PASSWORD_NOT_COMPLEX_2, ERROR );
+								break;
+							case 3:
+								trigger_error( ERROR_USER_PASSWORD_NOT_COMPLEX_3, ERROR );
+								break;
+						}
+					}
+				}
 			}
 		}
 	}
diff -Naur bugs-old/config_defaults_inc.php bugs/config_defaults_inc.php
--- bugs-old/config_defaults_inc.php	2009-04-09 22:15:40.000000000 -0500
+++ bugs/config_defaults_inc.php	2009-04-09 23:25:43.000000000 -0500
@@ -182,6 +182,16 @@
 	# Set to OFF to disable this control
 	$g_max_failed_login_count = OFF;
 
+	# Password Complexity
+	# OFF = Disabled
+	# 1 = Requires a mix of upper and lower case
+	# 2 = Also requires at least 1 Number
+	# 3 = Also requires a special character
+	$g_password_complexity = OFF;
+
+	# Minimum Password Length
+	$g_password_minimum = 3;
+
 	# access level required to be notified when a new user has been created using the "signup form"
 	$g_notify_new_user_created_threshold_min = ADMINISTRATOR;
 
diff -Naur bugs-old/core/authentication_api.php bugs/core/authentication_api.php
--- bugs-old/core/authentication_api.php	2009-04-09 22:16:10.000000000 -0500
+++ bugs/core/authentication_api.php	2009-04-09 22:26:41.000000000 -0500
@@ -297,6 +297,28 @@
 		return $t_confirm_hash;
 	}
 
+	# --------------------
+	# Determines whether the password meets complexity requirements
+	function auth_is_password_complex( $f_password ) {
+		$t_password_complexity = config_get( 'password_complexity' );
+		if ($t_password_complexity == 'OFF') return true;
+
+		# Check for upper case letters
+		if (strtolower($f_password) == $f_password)	return false;
+
+		# Check for lower case letters
+		if (strtoupper($f_password) == $f_password)	return false;
+
+		# Check for numbers
+		if ($t_password_complexity > 1 && str_replace(array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'), '', $f_password) == $f_password)	return false;
+
+		# Check for special characters
+		if ($t_password_complexity > 2 && str_replace(array('!', '@', '#', '$', '%', '^', '^', '&', '*', '(', ')', '-', '_', '+', '=', '{', '}', '[', ']', ':', ';', ',', '.', '?', '~', '|', '\\', '/'), '', $f_password) == $f_password)	return false;
+
+		# Everything checks out
+		return true;
+	}
+
 	#===================================
 	# Cookie functions
 	#===================================
diff -Naur bugs-old/core/constant_inc.php bugs/core/constant_inc.php
--- bugs-old/core/constant_inc.php	2009-04-09 22:48:52.000000000 -0500
+++ bugs/core/constant_inc.php	2009-04-09 22:48:32.000000000 -0500
@@ -245,6 +245,8 @@
 	define( 'ERROR_USER_REAL_MATCH_USER',		807 );
 	define( 'ERROR_USER_CHANGE_LAST_ADMIN',		808 );
 	define( 'ERROR_USER_REAL_NAME_INVALID',         809 );
+	define( 'ERROR_USER_PASSWORD_NOT_COMPLEX',         810 );
+	define( 'ERROR_USER_PASSWORD_TOO_SHORT',         811 );
 
 	# ERROR_AUTH_*
 	define( 'ERROR_AUTH_INVALID_COOKIE',			900 );
diff -Naur bugs-old/lang/strings_english.txt bugs/lang/strings_english.txt
--- bugs-old/lang/strings_english.txt	2009-04-09 22:15:17.000000000 -0500
+++ bugs/lang/strings_english.txt	2009-04-09 22:46:03.000000000 -0500
@@ -267,6 +267,10 @@
 $MANTIS_ERROR[ERROR_VERSION_NOT_FOUND] = 'Version "%s" not found.';
 $MANTIS_ERROR[ERROR_USER_NAME_INVALID] = 'The username is invalid. Usernames may only contain Latin letters, numbers, spaces, hyphens, and underscores.';
 $MANTIS_ERROR[ERROR_USER_REAL_NAME_INVALID] = 'The user real name is invalid.';
+$MANTIS_ERROR[ERROR_USER_PASSWORD_TOO_SHORT] = 'Your Password must be a minimum of %d characters.';
+$MANTIS_ERROR[ERROR_USER_PASSWORD_NOT_COMPLEX_1] = 'Your Password does not meet complexity requirements.  It should use a combination of upper and lower case letters.';
+$MANTIS_ERROR[ERROR_USER_PASSWORD_NOT_COMPLEX_2] = 'Your Password does not meet complexity requirements.  It should use a combination of upper and lower case letters and numbers.';
+$MANTIS_ERROR[ERROR_USER_PASSWORD_NOT_COMPLEX_3] = 'Your Password does not meet complexity requirements.  It should use a combination of upper and lower case letters, numbers, and special characters.';
 $MANTIS_ERROR[ERROR_USER_DOES_NOT_HAVE_REQ_ACCESS] = 'User does not have required access level.';
 $MANTIS_ERROR[ERROR_USER_REAL_MATCH_USER] = 'The "Real Name" chosen matches another user\'s login name. Please choose another.';
 $MANTIS_ERROR[ERROR_SPONSORSHIP_NOT_ENABLED] = 'Sponsorship support not enabled.';
 | ||||
| has duplicate | 0015746 | closed | atrol | Software allows an insecure password. | 
| has duplicate | 0017566 | closed | atrol | Password security | 
| has duplicate | 0022448 | closed | dregad | Accepts all type of passwords | 
| has duplicate | 0033599 | closed | atrol | Setting up password policy | 
| has duplicate | 0035811 | closed | atrol | Weak passwords are accepted without warnings or strength checks | 
| 
	 This is something we'd likely do as a part of "auth plugins"  | 
|
| 
	 Great, let me know when the plugin functionality is done and out in stable, and I will write the plugins for this (and most likely several other pieces of functionality).  | 
|
| 
	 Similar patch for newer version at duplicate 0017566  | 
|
| 
	 This is exactly what we need. Is there a plan on when this will be implemented? Can I help?  | 
|
| 
	 There's currently no plan but if you're willing to contribute I suggest you have a look at the submitted pull request at https://github.com/mantisbt/mantisbt/pull/236 and discuss the issue with grangeway.  | 
|
| 
	 it this could be done as small feature change soon  | 
|