Password validation regex: require and forbid certain characters - javascript

I have an MVC form with jQuery validation and System.ComponentModel.DataAnnotations
Problem is if I enter & in the password textbox then jQuery and MVC Model.Isvalid allows it, even though it's not one of the allowed characters.
I have tried to search for this on Google but the results I get back have nothing to do with the issue. i.e. JavaScript: client-side vs. server-side validation - Stack Overflow
My regex is below in case I have made a mistake with that.
RegularExpression("^((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%]).{6,10})",
ErrorMessage = "{0} must be between 6 and 10 characters and have at least 1 upper case letter, 1 lower case letter, 1 number and contain either ##$%")

The pattern in your example ^((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%]).{6,10}) uses positive lookaheads to ensure certain character classes are present in the input string but it will not in any way prevent other types of characters to appear. Each lookahead group starts with .* which allows literally anything hence & or any other character as a matter of fact will be accepted in the input string and whatever a lookahead signifies will be enforced in addition.
In other words, this approach using only positive lookaheads will make some types of characters required but it will not make any characters disallowed.
To overcome this, you can simply add another lookahead group but this time a negative one:
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%])(?!.*[&]).{6,10}$
Also, pay attention to end the pattern with string terminator $ (which was missing in your example). Without that the regex engine will produce a match for inputs that are more than 10 characters long.
See example here.

Related

Password Regex For Angular 4 fails

I have added a regex which will check for least 8 characters, at least one number, one uppercase letter, one lowercase letter and one special character
This is the regex Used
'(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$#$!%*?&])[A-Za-zd$#$!%*?&].{8,}'
The above regex works fine for most of the scenarios but when I use
1oB!gb0s5
or
Pass#123
It fails. Can anyone tell me the issue here.
Here is the portion of your regex which actually consumes the input:
[A-Za-zd$#$!%*?&].{8,}
This means that the password must start with one of the characters in the above character class. It also means that a valid password must have nine or more characters, because the class counts for one, and {8,} means 8 or more. So the following would fail because it does not begin with any such character:
1oB!gb0s5
The second example you gave fails for a different reason, because it only has 8 characters:
Pass#123
I don't know exactly what logic you want here. If you just want to ensure that a password has a lowercase, uppercase, number, and special character, then maybe you can remove the leading character class and just stick with the lookaheads:
(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$#$!%*?&]).{8,}
Here is a demo which shows that your two example passwords would pass using the above pattern.
Demo

Javascript Regex for strong password with specific ordering of the characters

I have seen answers for strong password checks but I have an additional requirement for the order in which the characters appear.
The password should contain at least:
One upper case letter.
One lower case letter.
One number.
One special character.
The order being:
Should start with upper case and lower case letters.
Followed by number and/or alphabetical characters.
In the end, should be a special character.
e.g.
Xyz1325# is valid.
aBcd123xYz# is also valid.
#Xyz1234 is invalid.
1234Xyz# is invalid.
Xyz# is invalid.
Introducing a specific order of characters in a password makes it relatively more predictable, hence losing the strength of it, and I'll suggest you to get away with that restriction. Nevertheless, you can use this regex that will meet your needs,
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!##$%^&*])[a-zA-Z][a-zA-Z\d]*[~!##$%^&*?<>]*$
Explanation:
^ --> Start of string
(?=.*[a-z]) --> Ensures the password has at least one lowercase letter.
(?=.*[A-Z]) --> Ensures the password has at least one uppercase letter.
(?=.*\d) --> Ensures the password has at least one digit.
(?=.*[~!##$%^&*]) --> Ensures the password has at least one special character from this set. You can put more characters inside that you want to treat as special.
Now comes the part for ensuring the order. As you said it should start with an alphabet, hence we need the first character as,
[a-zA-Z]
Then following it can be alphabet or numbers hence you can use,
[a-zA-Z\d]*
And finally you want special characters, and by your this statement "In the end, should be a special character." I assume you do not want to restrict it to just one single special character, hence at the end of regex it should be this,
[~!##$%^&*?<>]*
which can match one or more special characters. If you really meant just one special character then just make it [~!##$%^&*?<>]
And finally end it with $ to stop matching the string.
Live Demo
Hope this works for you. Or else, let me know for any other queries.
Edit
Bonus:
If you want to check length as well you can do so using the following:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!##$%^&*])(?=.{6,18}$)[a-zA-Z][a-zA-Z\d]*[~!##$%^&*?<>]*$
The additional (?=.{6,18}$) is to ensure that your regex has length between 6 to 18.
#Pushpesh,
Please correct if wrong.
The regex I believe you are looking for is this: https://regex101.com/r/nO2DxE/2
Explanation:
These groups (?=.*[A-Z].*) (?=.*[0-9].*) (?=.*[a-z].*) make sure your string contains at least one uppercase letter, one lowercase letter and one digit. The rest of the regex checks that the order you described is respected.
Overall, the regex is:
(?=.*[A-Z].*)(?=.*[0-9].*)(?=.*[a-z].*)^[a-zA-z][a-zA-Z0-9]*[#!#+-]$

javascript regex requiring at least one letter, one number and prevents from adding certain words

I'm trying to modify my regex which requires user to type at least one letter and one digit which looks like this :
new RegExp('^(?=.*[a-z])(?=.*[0-9]).+$')
And I want to prevent user from using certain words like email address part before #.
So let's assume the email address is example#example.com
I want to force user to use a string that doesn't contain example in it (any part of the string)
This is what I have so far:
\b(?:(?!example)\w)+\b
But it doesn't really force the user to use at least one character and one digit.
When I'm trying to restric it I'm ending up with this:
\b(?:(?!example).*[a-z].*[0-9])+\b
But now the strings must follow the order of example then a [a-z] and then [0-9]
Any help greatly appreciated
Thanks!
In your sample the negative lookahead disallows example only at start of the string. Just add .*? as joker to disallow the word anywhere in the string and use word boundaries \b if needed.
/^(?!.*?example)(?=\D*\d)[^a-z]*[a-z].*$/i
(?!.*?example) first lookahead disallows example anywhere in the line
(?=\D*\d) second lookahead requires a digit after any amount of \D non-digits.
[^a-z]*[a-z] matches any amount of non-alphetic characters until an alphabetic.
See demo at regex101
Actually you just need two lookaheads for being independent of condition. One for the required digit and one for the word. The requirement of alphabetic can be done inside the pattern.
Lookarounds are zero-length assertions triggered at a certain position.

Why are my optional characters not being caught?

I'm trying to create a regex to test passwords against. My current one checks for the following:
One Uppercase Letter
One Lowercase Letter
One number
Currently, the user can't enter special characters, however I'm trying to add that as an optional check (so Testing1 and Testing1! should both match). I've tried:
^(?=.*[A-Za-z])(?=.*\d)(?=.*[$#$!%*#?&])(A-Za-z\d[$#$!%*#?&]?){8,}$
But it doesn't catch it. I have a feeling my special character set is in the wrong place, but I'm not sure where to place it.
Where do I add my list of special characters as optional checks?
There's many ways that you can set up your regex, such as creating a whitelist, or a blacklist, for types of characters. This one in particular creates a whitelist for characters that can be used which seems to be what you are looking for.
^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9$#$!%*#?&]{8,}$
Regex Breakdown:
^ // Assert position at start of the line
(?=.*[A-Z]) // First positive lookahead, makes sure a capital character exists
(?=.*[a-z]) // Make sure a lowercase character exists
(?=.*[0-9]) // Make sure a number exists
[A-Za-z0-9$#$!%*#?&] // All of the possible characters that can be typed
{8,} // 8 to infinity characters
$ // Assert position at end of line
Since you say that you want special characters as optional, they are just placed in the possible characters that can be typed, but they are not validated by any positive lookaheads.
See this regex in action on regex101. Keep in mind, the modifiers gm are there to validate across lines in this example and should probably be removed in your use case.
Of course you may have reasons for the "whitelist" approach, but a more common approach, and one you may want to look into trying sometime, is to allow almost anything (blacklist), and then validate that a certain criteria is met.

Excluding $ in a regex in CF

I am working through some different form validation types and I am having trouble getting all the items on my wishlist to work.
My code for my cfinput is this (works the same as a regular form input and has some canned javascript validation)
<cfinput type="Text" name="negdays"
range="0,23"
pattern="^(([^0]{1})([0-9])*|(0{1}))?$"
message="Negative Days must be a number between 0 and 23"
required="No" width="2" >
This one should, and does, exclude everything I need except the $. I am having difficulty stopping the form from accepting the $.
Another example that is similar is this one where I want a range and to keep it numeric, so I mixed the validation types
<cfinput type="text" name="achamount"
validate = "range,numeric"
range = "0,99999"
message="ACH Amount must be a range from 0 - 99999 and numeric only" >
... and it works perfect - except for one problem: a $ is allowed.
So I thought maybe I could add to it with a regex like this:
<cfinput type="text" name="achamount"
validate = "range,numeric,regex"
range = "0,99999"
pattern="^\d"
message="ACH Amount must be a range from 0 - 99999 and numeric only" >
But my pattern is of course only to limiting it to numeric, which I am already doing. I need my pattern to exclude the dollar signs. But as a special character its not behaving like the other stuff I want to get rid of.
Any ideas or suggestions? Everything I have tried either does not work or breaks all the other validation on the page.
Solution: Matching Only Numbers
You don't need to specifically exclude $ - to only allow numeric digits, you simply need to ensure every character matches \d.
To do this, you need to anchor the start and end of the regex to the start and the end of the input, which is done with the regex metacharacters ^ and $ respectively. (If you ever need to use either of these characters as literals, prefix them with a backslash.)
So for an integer between 0 and 99999 you want:
^\d{1,5}$
Matching an integer between 0 and 23 works the same way thing, but the central part of the pattern needs to be complex, to ensure you don't get 24 or above:
^(?:[03-9]|1\d?|2[0-3]?)$
The three alternatives here are:
* [03-9] matches any single digit except 1 or 2.
* 1\d? matches 1, or 1 followed by any digit.
* 2[0-3]? matches 2, or 2 followed by any digit upto 3.
The (?:..) is to ensure the ^ and $ still apply to the entire string.
(Of course, you could also just use ^\d{1,2}$ then later check if it's less than 24.)
Bonus Info: Excluding Characters
As above, you don't need to do this in this case, but if you encounter a situation where you did need to exclude $, you could do it either using a negative character class:
^[^$]{1,5}$
Or using a negative lookahead:
^(?:(?!\$).){1,5}$
This latter one is a bit more complicated, but it allows more flexibility so is useful to be aware of.
A lookahead is another form of anchor (it matches at a position, but doesn't consume the characters it matches). When used against a item that has a quantifier (the {1,5} bit) attached, you need to group both items together for it to apply correctly. (i.e. If you only did (?!\$).{1,5} the negative lookahead would only be checked for the first character, not all five.)
Note that outside of a character class $ must be escaped as \$ to prevent it's special meaning of "end of string anchor". Inside a character class it is just a regular character.
(Hopefully this explanation is clear - let me know if further information or clarification would be useful.)
Your regex ^(([^0]{1})([0-9])*|(0{1}))?$ can be simplified quite a bit. It seems that you want either a single digit preceeded by a 0 or maximum 2 digits.
Try this: ^\d{2}$
What about adding the $ to a range of characters you don't allow?
pattern="[^$]"

Categories

Resources