Make WordPress Core

Changeset 25637


Ignore:
Timestamp:
09/28/2013 06:46:29 AM (12 years ago)
Author:
nacin
Message:

Expand the zxcvbn password meter blacklist, based on user input.

props iandunn.
see #25174.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/password-strength-meter.js

    r25157 r25637  
    1 function passwordStrength(password1, username, password2) {
    2     if (password1 != password2 && password2.length > 0)
    3         return 5;
    4     var result = zxcvbn( password1, [ username ] );
    5     return result.score;
    6 }
     1window.wp = window.wp || {};
     2
     3var passwordStrength;
     4(function($){
     5    wp.passwordStrength = {
     6        /**
     7         * Determine the strength of a given password
     8         *
     9         * @param string password1 The password
     10         * @param array blacklist An array of words that will lower the entropy of the password
     11         * @param string password2 The confirmed password
     12         */
     13        meter : function( password1, blacklist, password2 ) {
     14            if ( ! $.isArray( blacklist ) )
     15                blacklist = [ blacklist.toString() ];
     16
     17            if (password1 != password2 && password2.length > 0)
     18                return 5;
     19
     20            var result = zxcvbn( password1, blacklist );
     21            return result.score;
     22        },
     23
     24        /**
     25         * Builds an array of data that should be penalized, because it would lower the entropy of a password if it were used
     26         *
     27         * @return array The array of data to be blacklisted
     28         */
     29        userInputBlacklist : function() {
     30            var i, userInputFieldsLength, rawValuesLength, currentField,
     31                rawValues       = [],
     32                blacklist       = [],
     33                userInputFields = [ 'user_login', 'first_name', 'last_name', 'nickname', 'display_name', 'email', 'url', 'description', 'weblog_title', 'admin_email' ];
     34
     35            // Collect all the strings we want to blacklist
     36            rawValues.push( document.title );
     37            rawValues.push( document.URL );
     38
     39            userInputFieldsLength = userInputFields.length;
     40            for ( i = 0; i < userInputFieldsLength; i++ ) {
     41                currentField = $( '#' + userInputFields[ i ] );
     42
     43                if ( 0 == currentField.length ) {
     44                    continue;
     45                }
     46
     47                rawValues.push( currentField[0].defaultValue );
     48                rawValues.push( currentField.val() );
     49            }
     50
     51            // Strip out non-alphanumeric characters and convert each word to an individual entry
     52            rawValuesLength = rawValues.length;
     53            for ( i = 0; i < rawValuesLength; i++ ) {
     54                if ( rawValues[ i ] ) {
     55                    blacklist = blacklist.concat( rawValues[ i ].replace( /\W/g, ' ' ).split( ' ' ) );
     56                }
     57            }
     58
     59            // Remove empty values, short words, and duplicates. Short words are likely to cause many false positives.
     60            blacklist = $.grep( blacklist, function( value, key ) {
     61                if ( '' == value || 4 > value.length ) {
     62                    return false;
     63                }
     64
     65                return $.inArray( value, blacklist ) === key;
     66            });
     67
     68            return blacklist;
     69        }
     70    }
     71
     72    // Backwards compatibility.
     73    passwordStrength = wp.passwordStrength.meter;
     74})(jQuery);
  • trunk/src/wp-admin/js/user-profile.js

    r21592 r25637  
    1010        }
    1111
    12         strength = passwordStrength(pass1, user, pass2);
     12        strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputBlacklist(), pass2 );
    1313
    1414        switch ( strength ) {
  • trunk/tests/qunit/wp-admin/js/password-strength-meter.js

    r25275 r25637  
    7878    });
    7979
    80     test( 'username in password should be penalized', function() {
     80    test( 'blacklisted words in password should be penalized', function() {
    8181        var allowedPasswordScore, penalizedPasswordScore,
    8282            allowedPassword   = 'a[janedoe]4',
    8383            penalizedPassword = 'a[johndoe]4',
    84             username          = 'johndoe';
     84            blacklist         = [ 'extra', 'johndoe', 'superfluous' ];
    8585
    86         allowedPasswordScore = passwordStrength( allowedPassword, username, allowedPassword );
    87         penalizedPasswordScore = passwordStrength( penalizedPassword, username, penalizedPassword );
     86        allowedPasswordScore = passwordStrength( allowedPassword, blacklist, allowedPassword );
     87        penalizedPasswordScore = passwordStrength( penalizedPassword, blacklist, penalizedPassword );
    8888
    8989        ok( penalizedPasswordScore < allowedPasswordScore, 'Penalized password scored ' + penalizedPasswordScore + '; allowed password scored: ' + allowedPasswordScore );
    9090    });
     91
     92    test( 'user input blacklist array should contain expected words', function() {
     93        var blacklist = wp.passwordStrength.userInputBlacklist();
     94
     95        ok( jQuery.isArray( blacklist ), 'blacklist is an array' );
     96        ok( jQuery.inArray( 'WordPress', blacklist ) > -1, 'blacklist contains "WordPress" from page title' );
     97        ok( jQuery.inArray( 'tests', blacklist ) > -1, 'blacklist contains "tests" from site URL' );
     98    });
    9199});
Note: See TracChangeset for help on using the changeset viewer.