PDA

View Full Version : [0.2] Ext.ux.PasswordMeter



Pagebaker
31 Aug 2007, 12:45 AM
After working with Ext for some time I tought it would be time to start writing some extentions.

Ext.ux.PasswordMeter calculates the strength of a password, shows a nice graph and can be used in any form.

Code and example (http://testcases.pagebakers.com/PasswordMeter/)can be found here. (http://testcases.pagebakers.com/PasswordMeter/)

If you guys have suggestions or comments please let me know.

Hopefully it can be usefull for someone :)


@TODO:
Compare with other fields in the form (configuration option)

@fixed
Fix IE layout inconsistency
I improved the algorithm and it now works like expected
Set meter to 0 if the password field is empty

galdaka
31 Aug 2007, 4:40 AM
Very nice!! ;)

Note: In IE the progress widget is not correct align to password field. May be 1 or 2 pixel to right!

Thanks in advance,

Pagebaker
31 Aug 2007, 4:58 AM
Thanks, I noticed it, I'll add it to the todo list

GrimReapa
31 Aug 2007, 6:18 AM
You might want to do some more checking based on other form fields (ie: first / last name).

I entered my first name and last name, then i choose a password of first+last name and got a high rated password when in fact it isn't that great of a password.

Looks good so far...just needs a little more improving.

smpdawg
31 Aug 2007, 2:34 PM
I have a question what could be construed as a suggestion. Typically the creation of a new password usually requires a second field for confirming the previous password. I am not sure it needs to have a progress bar below the first one - perhaps even an option for this control to make both edit boxes and put the progress bar between them and have it verify that both passwords are the same. It is what I like to call laziness...

Thanks, looks good.

MarkT
31 Aug 2007, 2:43 PM
If the user erases all of the characters in the password field, the score doesn't drop back down to zero. Adding the following to the top of calcStrength should fix that.

if (p.length == 0) {
return 0;
}

Pagebaker
1 Sep 2007, 3:14 AM
@GrimReapa
I was thinking of something like that, good idea. I think I'll add a configuration option for that, so you can pass an array with fields that need to be compared with the password.

@smpdawg
Mayb I'll add this feature.

@MarkT
Thanks

JeffHowden
1 Sep 2007, 9:29 PM
@GrimReapa
I was thinking of something like that, good idea. I think I'll add a configuration option for that, so you can pass an array with fields that need to be compared with the password.

May I suggest a couple of things with regard to this:


Not all string values that we want/need to filter out will be available in a form field, so an array of string values would be nice.
We may not always know the values we wish to force the user to exclude, so a config option referencing a function that returns an array would also be handy.
Which leads me to wonder if maybe this can all be accomplished with a single function that gets called each and every time (like validators do) and returns an array of static string values, an array of field values, a combination, or whatever the developer decides.

Pagebaker
4 Sep 2007, 4:01 AM
JeffHowden, I'm not sure what you mean could you explain it a little better or give an example? thanks :)

johnnycannuk
4 Sep 2007, 4:57 AM
Reminds me of a old function we created when working with Entrust TruePass - as soon as you met a criteria for a strong password, that criteria was checked and you could not create the password unless all criteria was checked.

So, if you required a special character, this appeared initially as an 'x' and didn't change until you supplied one.

Same for numeric, min length etc.

It was customizable too. You might consider dispalying information like that so the user knows why his password is strong or not.

I'll have to see if I can dig that up....

jheid
4 Sep 2007, 6:26 AM
Really nice.

Perhaps it would nice if you can plug in your own algorithm. Acutally I'm thing about using Google for password strength judgement. The only problem is that - as far as I know - you can contact the google search just via HTTP, but this would be a nice way to get rid of simple passwords....

JeffHowden
4 Sep 2007, 7:51 AM
I would seriously reconsider the use of Google.

http://extjs.com/forum/showthread.php?t=9358&highlight=password+strength#post48251

Pagebaker
4 Sep 2007, 8:06 AM
Indeed it doesn't look so powerful.. and you'll need to send the password over the net, unencrypted..

Hm i didn't know someone else already build a passwordmeter, oh well it's a good lesson for me :)

JeffHowden
4 Sep 2007, 9:36 AM
UI-wise, yours is better.

jheid
4 Sep 2007, 11:14 AM
I would seriously reconsider the use of Google.

http://extjs.com/forum/showthread.php?t=9358&highlight=password+strength#post48251

I'm not talking about using the Google JavaScript files for password strength but the simple web search, so that a password with fewer hits is much better than a password with many hits. The problem is that afaik the Google search doesn't support SSL.

JeffHowden
4 Sep 2007, 12:26 PM
That's a creative approach, but fewer hits probably isn't as indicative of a strong password as you might think. For example, mysuperstrongpassword returns no records, but is clearly not a strong password by any stretch of the imagination. Additionally, even if they did support SSL, queries are still sent via the query string rendering SSL useless:

http://www.google.com/search?hl=en&q=mysuperstrongpassword

jheid
4 Sep 2007, 12:33 PM
That's a creative approach, but fewer hits probably isn't as indicative of a strong password as you might think. For example, mysuperstrongpassword returns no records, but is clearly not a strong password by any stretch of the imagination. Additionally, even if they did support SSL, queries are still sent via the query string rendering SSL useless:

http://www.google.com/search?hl=en&q=mysuperstrongpassword

Yes, you're right. It would just be a good way to check against a dictonary and simple password like 'abcd123'.

JeffHowden
4 Sep 2007, 12:41 PM
There are dictionary webservices available. Even those aren't terribly helpful though as the algorithm needs to check possible strings within the password against word lists. A version I built by reverse engineering the MSN one does exactly that, but the word lists are hard-coded.

http://jeffhowden.com/code/coldfusion/password_strength/

This example uses server-side logic to measure password strength and AJAX calls to query the server-side system.

tjstuart
11 Sep 2007, 11:06 PM
Additionally, even if they did support SSL, queries are still sent via the query string rendering SSL useless

Pretty sure that is incorrect. The query string is protected by SSL. See here

http://answers.google.com/answers/threadview?id=758002#answer

JeffHowden
12 Sep 2007, 10:32 AM
Pretty sure that is incorrect. The query string is protected by SSL. See here

http://answers.google.com/answers/threadview?id=758002#answer
Indeed, not completely useless. However, the password is exposed locally in the browser's cache/history. So, to those who don't want their password exposed, it's still a good idea to not send it over the wire in the query string, SSL or not.

Bottom line, if the data is sensitive, then POST and SSL in combination is the only option.

xpressive
5 Nov 2007, 5:45 AM
very nice feature!
I have added a function to provide client side validation of enterd password.

Maybe it is helpful for somebody



/**
* validate the strength of the entered password, based on the score
* Private function
*/
validateValue : function(value){
if(!Ext.ux.PasswordMeter.superclass.validateValue.call(this, value)){
return false;
}
if(value.length < 1){ // if it's blank and textfield didn't flag it then it's valid
return true;
}
var nScore = this.calcStrength(value);
var minStrength = 25;
if (nScore < minStrength) {
this.markInvalid('The strength of your password is not enough!');
this.isValid = false;
return false;
}
return true;
},

Full source is attached below ...

Pagebaker
6 Nov 2007, 3:42 AM
Nice work! unfortunately I haven't had any time lately to do more work on this one

sanjshah
23 Dec 2007, 3:37 PM
Hi,

I've tried addding this to a form using the following:



var mypassword = new Ext.ux.PasswordMeter({
applyTo:'password',
width:175
});


But cannot see the graph - am I applying this wrong?

Thanks!

Dumbledore
3 Jan 2008, 5:55 AM
perhaps you forgot to add the css-classes?

Bye

wwarby
19 Jul 2008, 8:22 AM
PageBaker,

Thanks a lot for sharing this example - I'm using it in a current development project. The user interface is lovely - however, I had some reservations about the accuracy of your password strength checking algorithm so I've written my own implementation, and thought I'd share it back with the community...


calcStrength: function(p) {
var re_d = /\d/;
var re_l = /[a-z]/;
var re_u = /[A-Z]/;
var re_y = /[\W_\-]/;
var s = 0, cs = 0, cw = 1;
var r = p.length - p.replace(new RegExp(/(\S+?)(\1+)/g), '$1').length; //Length of repeated character sequences
if (re_d.test(p)) { cs += 10; } //Increment the character set size if digits found
if (re_l.test(p)) { cs += 26; } //Increment the character set size if lowercase letters found
if (re_u.test(p)) { cs += 26; } //Increment the character set size if uppercase letters found
if (re_y.test(p)) { cs += 32; } //Increment the character set size if special characters found
cw = (cs / 94); //Proportion of the printable ASCII character set used
if ((p.length - r) >= 4) { cw += ((1 - (cs / 94)) * (1 - (4 / (p.length - r)))); } //Weighting based on relationship between character set size and password length
if (cw > 1) { cw = 1; } //Constrain the weighting value to the range 0-1
s = (p.length - (r / 2)) * (cw * 6); //Score calculation
if (s < 0) { s = 0; }; if (s > 100) { s = 100; } //Constrain the score to the range 0-100
return Math.round(s); //Return score rounded to the nearest integer
}Since there's a fair bit of maths in there, an explanation is in order.

First I considered which things affect the password strength. Many password hacking tools can try dictionary words and proper nouns, but since it isn't really practical to download dictionary files to the client for a JS strength meter, I will assume a brute force attack method.

Using brute force password strength is measured by the number of permutations required to guarantee breaking of the password. The permutations are a straight forward multiple of password length * character set size. Therefore, the key parameters in the algorithm must be password length and character set size.

Typically the character sets used in brute force attacks are grouped into digits, lowercase, uppercase and specials - assuming we only use the 94 printable ascii characters. Once you've used any single character from any one of these groups, you've effectively forced the hacker to include that whole group in his attack. Therefore, my algorithm calculates the size of the character set used, based on the inclusion of at least one character from each of the character groups.

After some consideration, I resolved that the size of the character set becomes less significant as the length of the password increases, because each new character increases the number of permutations vastly more than increasing the character set size. Therefore, the algorythm assigns a weighting to the character set size which is dependent on the password length; larger character sets always score better, but they affect the scoring more dramatically with shorter passwords than with longer ones.

One final parameter I decided to take into account was repeating character sequences. "aaaaaa" is less strong than "ababab" which is in turn less strong than "abcdef", so I added a penalty for repeating character sequences. Essentially, repeated sequences are considered to be half as long as they really are, so "aaaaaa" which has an actual length of 6 has a measured length of 3.5 in the algorythm, because 5 of the characters are repeats (2.5 penalty). "ababab" has a measured length of 4, because the last four characters are repeated (2 penalty). "abcabc" would have a measured length of 4.5, and so on.

The parameters established by the algorithm are combined to give a rounded score between 0 and 100. It is tuned to score 100 once you hit around 20 characters all in lower case or around 17 characters with a good character set mix.

I'm no mathematician or security expert and I can't say authoritatively whether this algorithm is any good. In my tests however, it closely reflects the results found in 1Password for Mac, and results I would expect with the passwords I have tried. I hope if is of use to somebody ;)

demongloom
12 Jan 2009, 8:38 AM
Hello,
very nice plugin, but please make function updateMeter not depended on event, or add event on value update to force meter update if value set through input.setValue() function.

For example i did new user creation form with password generation function.


var button_generate = new Ext.form.Button({
text: "Generate password",
handler: function() {

var mask = "1qwer2tyuio1pa3sdf2ghjklz43xcvbn4mQW5ER5TYUI6OPA67SD8FG79H8JK0LZ9XCV0BNM";
var pass = "";

while( pass.length < 8 ) {
pass += mask[ parseInt(Math.random() * mask.length) ]; }

input_password.setValue(pass);
input_password.updateMeter();
// ^^^ Here cause crash, because is no event passed as arg.
// ^^^ I've changed updateMeter function to use this.getRawValue(), but how it's correct?

}
});
When i call

ktreagu
10 Jul 2009, 12:03 PM
I modified the password meter with a few changes.

-modified to work with the Jingo javascript dependancy management system (see http://code.google.com/p/jingo/)
-validated against JSLint
-enhanced to take in calcStrength as an optional config parameter so you can replace the password strength algorithm with your own password strength algorithm (I used the one from http://www.passwordmeter.com/)

Changes attached...

asafm
31 Aug 2010, 9:00 AM
Hi,

I've added the following lines of code to support reset() of the form, which also supposed to reset the meter (and score):



reset : function() {
Ext.ux.PasswordMeter.superclass.reset.call(this);
this.updateMeter(this);
}


And changed updateMeter to work without parameters:



updateMeter: function() {
var score = 0;
var p = this.getValue();

osnoek
30 Dec 2011, 4:41 AM
Hi I've ported this to Ext4. Check it out here (http://www.sencha.com/forum/showthread.php?168452-Ext.ux.form.PasswordMeter&p=703713#post703713)