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.

Comment by Dean on 8 December 2007:
Thanks for the comment. I’m looking forward to posting more substantive info.
Comment by Steve on 8 December 2007:
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.
Comment by Argo on 9 December 2007:
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
Comment by Steve on 9 December 2007:
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.
Comment by André Tagesgeld on 11 February 2008:
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!
Comment by JKatelman on 20 March 2008:
How would the sequential identical check be modified to allow 2, but not 3 or more characters?
Comment by Steve on 20 March 2008:
@JKatelman, here’s one way:
validatePassword(pw, {custom:[/^(?!.*(.)\1\1)/]});Comment by JKatelman on 21 March 2008:
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?
Comment by Steve on 21 March 2008:
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 functionfunction(pw){return !/([\S\s])\1\1/.test(pw);}.