JavaScript Password Validation

Since I've seen tons of password validation help requests on regexadvice.com (where I hang out from time to time), I've written up a more general-purpose JavaScript password validation function. It's reasonably straightforward, and covers the validation requirements I've most frequently encountered. Plus, if it doesn't handle your exact needs, its functionality can be augmented by passing it custom functions and regular expressions.

Here are the validation types supported out of the box. All are optional, which means that all passwords are allowed by default.

  • Minimum and maximum length.
  • Minimum n lowercase characters (a–z).
  • Minimum n uppercase characters (A–Z).
  • Minimum n combined a–z and A–Z characters.
  • Minimum n numeric characters (0–9).
  • Minimum n special characters (characters other than a–z, A–Z, and 0–9).
  • Ban particular words (tested case-insensitively).
  • Ban n-length character sequences (e.g. "abc", "XYZ", or "789", with a sequence length of 3; does not apply to special characters).
  • Ban n-length qwerty character sequences (e.g. "qwerty" or "asdf", with a sequence length of 4; does not apply to special characters).
  • Ban sequential, identical characters (e.g. "aa" or "!!").
  • Use custom regular expressions (tested using RegExp.prototype.test) and functions (the password is provided as the first argument, and a Boolean value is expected in return).

Here's an example of how it can be used:

var password = "password";
var passed = validatePassword(password, {
	length:   [8, Infinity],
	lower:    1,
	upper:    1,
	numeric:  1,
	special:  1,
	badWords: ["password", "steven", "levithan"],
	badSequenceLength: 4
});
// passed: false

The above requires that password is at least eight characters long; has at least one lowercase, uppercase, numeric, and special character; doesn't include the words "password", "steven", or "levithan"; and doesn't include an alphanumeric sequence four or more characters in length (e.g. "1234").

Here's the code (there are no external library dependencies):

/*
	Password Validator 0.1
	(c) 2007 Steven Levithan <stevenlevithan.com>
	MIT License
*/

function validatePassword (pw, options) {
	// default options (allows any password)
	var o = {
		lower:    0,
		upper:    0,
		alpha:    0, /* lower + upper */
		numeric:  0,
		special:  0,
		length:   [0, Infinity],
		custom:   [ /* regexes and/or functions */ ],
		badWords: [],
		badSequenceLength: 0,
		noQwertySequences: false,
		noSequential:      false
	};

	for (var property in options)
		o[property] = options[property];

	var	re = {
			lower:   /[a-z]/g,
			upper:   /[A-Z]/g,
			alpha:   /[A-Z]/gi,
			numeric: /[0-9]/g,
			special: /[\W_]/g
		},
		rule, i;

	// enforce min/max length
	if (pw.length < o.length[0] || pw.length > o.length[1])
		return false;

	// enforce lower/upper/alpha/numeric/special rules
	for (rule in re) {
		if ((pw.match(re[rule]) || []).length < o[rule])
			return false;
	}

	// enforce word ban (case insensitive)
	for (i = 0; i < o.badWords.length; i++) {
		if (pw.toLowerCase().indexOf(o.badWords[i].toLowerCase()) > -1)
			return false;
	}

	// enforce the no sequential, identical characters rule
	if (o.noSequential && /([\S\s])\1/.test(pw))
		return false;

	// enforce alphanumeric/qwerty sequence ban rules
	if (o.badSequenceLength) {
		var	lower   = "abcdefghijklmnopqrstuvwxyz",
			upper   = lower.toUpperCase(),
			numbers = "0123456789",
			qwerty  = "qwertyuiopasdfghjklzxcvbnm",
			start   = o.badSequenceLength - 1,
			seq     = "_" + pw.slice(0, start);
		for (i = start; i < pw.length; i++) {
			seq = seq.slice(1) + pw.charAt(i);
			if (
				lower.indexOf(seq)   > -1 ||
				upper.indexOf(seq)   > -1 ||
				numbers.indexOf(seq) > -1 ||
				(o.noQwertySequences && qwerty.indexOf(seq) > -1)
			) {
				return false;
			}
		}
	}

	// enforce custom regex/function rules
	for (i = 0; i < o.custom.length; i++) {
		rule = o.custom[i];
		if (rule instanceof RegExp) {
			if (!rule.test(pw))
				return false;
		} else if (rule instanceof Function) {
			if (!rule(pw))
				return false;
		}
	}

	// great success!
	return true;
}

You can download it here.

Lemme know if you have any feature requests or other suggestions about how to improve it, or if you need help writing custom rules for it.

57 thoughts on “JavaScript Password Validation”

  1. That’s great to hear, Dean!

    For the record, based on Dean’s email address I assume he’s Dean Hachamovitch, General Manager of the IE team, and that his response was regarding a comment where I poked fun at the apparent lack of humor of some other commenters on the IE blog and mentioned that I was looking forward to seeing him keep his promise regarding more IE8 info in the near future.

  2. Hi. I use Passpack to store my password online (http://www.passpack.com). During registration, for example, they checks your password measuring the quality in bit. Your password must be at least 64-bit quality. Maybe, you could have a look at their approach. It is very interesting.
    Argo

  3. Hmm… their password rating system is quite pretty. However, it’s not equivalent to this for several reasons. For one, it’s designed exclusively for their site and they make it very clear that the code is not open source. Secondly, it gives you a sliding scale of “password quality,” rather than a pass/fail system. That’s good if you’re just trying to assist users with selecting a good password, but not as good if you’re trying to meet pre-defined business requirements about password validation. Third, their system relies on password length and basic character types, but doesn’t do any of the more fancy kinds of validation you can see here.

    I’d considered implementing a quality score system, but that would significantly complicate things considering that the goal of this script is to let people who use it decide how they measure password strength, in order for it to be usable in more cases.

  4. Well, of course this is only one half of the whole thing: at serverside you’ll need to do the same thing in your preferred serverside language. That’s why I love ASP.NET Ajax – just define the regex you wanna use and the framework creates the js for you, while you’re focussing on writing the server-side part of it. Frameworks rock!

  5. How would the sequential identical check be modified to allow 2, but not 3 or more characters?

  6. Thanks for the response. I should have been a little more clear in what I was asking. The condition /([\S\s])\1/.test(pw) is a boolean for not allowing two characters. Is there a similar way to have a single condition that acts like a boolean for three characters?

  7. Yes. /([\S\s])\1\1/. But why would you fork the code for something like this when it makes it easy to provide custom validation rules? As an alternative to the standalone regex in my last comment, you could pass in the custom function function(pw){return !/([\S\s])\1\1/.test(pw);}.

  8. can u please tell what is mean by option on that code what we need to initialize for that?

  9. Please help me with the regular expression for the password policy mentioned below:-
    The password length should at least be 8 characters. It should be a combination of at least any two of the given sets.
    a. Set of alphabets a-z, A-Z
    b. Set of numerics 0-9
    c. Set of special characters ~!@#$ etc.

  10. @tuttu, this function doesn’t support x out of y rule validation (apart from accepting a custom function that does it itself). Better to bypass the function:

    var valid = 8 <= pw.length && 2 <= (
        /[a-z]/i.test(pw) +
        /[0-9]/.test(pw) +
        /[~!@#$]/.test(pw)
    );
  11. Hi Steven,

    Can you help me with the following validation requirement.
    Min 8 characters.
    Atleast 1 Uppercase character
    Atleast 1 Numeric
    Atleast 1 Special character

    Thanks in advance…

  12. Hi Steven,

    I’m trying to use the password validation into my assignment for school, but I am having a hard time turning this validation to have a error message directly onto the form, instead of a prompt box.

    What should I do?

  13. I am a complete newbie. How do you apply/append/use this code? Is there a sample html/php snippet I can use?

    for example:

    thanks!

  14. Hello everybody.

    I have a question. How to use validatePassword function if I need to check whether first character is number or not?

    Thanks!

  15. Hi Steven,
    Can you please help me with this validation.

    Should contain at least one element from each of the following
    A)Alphabet (A-Z, a-z)
    B)Numbers (0-9, special characters (~!@#$%^&*()_+[]{}:;)

    Regards,
    Bhagya

  16. hey but i want to check for white spaces also..
    password should not accept spaces rite..??

  17. The code provided for password verification is good but i need a code bit simpler and precise and plz provide me with demo also,as i m fresher to javascript.

  18. The password code validate is very good. I have to implement the no sequential and repeated letters or numbers in the password. I tried with the following code (/([\S\s]){3}/.test(pw)) and didn’t satisfy the above condition.

  19. Thank you for this script. It works really fine. But one question: How would the sequential identical check be modified to allow only a maximum number of characters?

  20. Love this JavaScript! Thank you for creating it, as well as making it available! Have you thought about expanding the “badWords” check to include a dictionary, rather than just a handful of words? Although it might take to long? What are your thoughts?

Leave a Reply

Your email address will not be published. Required fields are marked *