1

My web application will generate the password on registration form. But user are allow to change password by it they want.

When user enter the password, it must follow our password policy.

Our password policy is :

  1. The password length must be greater than or equal to 8
  2. The password must contain one or more uppercase characters
  3. The password must contain one or more lowercase characters
  4. The password must contain one or more numeric values
  5. The password must contain one or more special characters

The regex is (?=^.{8,}$)(?=.\d)(?=.[.!@#$%^&]+)(?![.\n])(?=.[A-Z])(?=.[a-z]).$

This is my C# code to generate password :

Regex passPattern = new Regex("(?=^.{8,}$)(?=.*\\d)(?=.*[!@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$");

    var password = System.Web.Security.Membership.GeneratePassword(10,2);

    while (true)
    {
    if (!passPattern.IsMatch(password))
       {
         password = System.Web.Security.Membership.GeneratePassword(10, 2);                                   
       }
       else
       {
        break;
       }    
    }

It will loop and keep generate the password until it match.

On the form, I also validate the password policy by using Jquery. Here the code snippet :

<script type="text/javascript">

$('#newPassword').keyup(function(e) {
    var strongRegex = new RegExp("(?=^.{8,}$)(?=.*\d)(?=.*[!@@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$", "g");       
    var enoughRegex = new RegExp("(?=.{8,}).*", "g");


    if (false == enoughRegex.test($(this).val())) {
        $('#passstrength').html('More Characters');
    }
    else if (strongRegex.test($(this).val())== true) {          
        $('#passstrength').html('Meet Our Password Policy!');
    }
    else {      
        $('#passstrength').html('Please insert strength password!');
    }

    return true;
});

So the result :

  1. A%rI_2{l#Y = Not match
  2. P@ssw0rd.123 = Match
  3. 2@C*DjDQdJ = Match
  4. ex@#XcINQ0 = Not Match

As you see, not all the password is match. All this value have been tested at regex101.com & regexpal.com and all the result is match.

So how can solved this problem?

p/s: I using razor engine in my page, so you can see double '@' on my regex in jquery.

Azri Zakaria
  • 1,324
  • 5
  • 23
  • 52
  • 1
    You have made at least 2 basic mistakes: 1) never use `/g` with `RegExp.test()` and 2) do not use a constructor notation when the pattern is known, use a literal regex notation (or you have to double backslashes) (that is, use `var strongRegex = /^(?=.{8,}$)(?=.*\d)(?=.*[!@@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/;`). Instead of `var enoughRegex = new RegExp("(?=.{8,}).*", "g");`, you really could just check the password length. BTW, why use `(?![.\n])`? There seems to be no requirement *Does not start with a dot or a line feed*. – Wiktor Stribiżew Feb 15 '16 at 09:54
  • Does it really need to be regex? It would be much easier to implement and read without it (along with more informed errors *why* the password was invalid) – Sayse Feb 15 '16 at 09:55
  • Why are you not just using a `[RegularExpression]` attribute applied to you model property so you get both client and server side validation out of the box without any of this code? –  Feb 15 '16 at 09:58
  • @StephenMuecke: Note that the validations are different on server and client side. That is also a good question, BTW. – Wiktor Stribiżew Feb 15 '16 at 09:59

1 Answers1

1

The problems with the code are:

  • /g modifier used in a regex that is later used in RegExp#test() (see this SO post)
  • single backslashes shorthand character classes in a constructor RegExp notation (see another post on this)

Also, note that checking the length of a string is better done with a regular string length check method:

$('#newPassword').keyup(function(e) {
    var strongRegex = /^(?=.*\d)(?=.*[!@@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).{8,}$/;       
    // Use the literal regex notation so as not to double escape \ symbols!  Else,
    // var strongRegex = RegExp("^(?=.*\\d)(?=.*[!@@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).{8,}$");
    if ($(this).val().length < 8) {   // no need in the enoughRegex
        $('#passstrength').html('More Characters');
    }
    else if (strongRegex.test($(this).val())) {          
        $('#passstrength').html('Meet Our Password Policy!');
    }
    else {      
        $('#passstrength').html('Please insert a strong password!');
    }

    return true;
});
Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • I still am not sure what you want to express with `(?![.\n])`. Right now, it will mean *Does not start with a dot or a line feed.* – Wiktor Stribiżew Feb 15 '16 at 10:37
  • 1
    Forgot to mention, our policy password is not allowed to put dot on first character. Just follow my boss instructions. No idea why. BTW, is working! – Azri Zakaria Feb 16 '16 at 03:11