How to require some characters and restrict others with Regex in HTML input pattern - html

As a user is typing their new password, I want them to be able to see if their password meets the requirements or not. I have a Regex pattern set up inside the input tag, and if the requirements aren't met, the input box is outlined in red and the form can't be submitted. This looks like:
<input type="password" pattern="((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.[!###$%&?]).{8,32})" placeholder="Password" required />
I adapted that pattern from here. I have it so that the user's password must contain 8-32 characters, one uppercase letter, one lowercase letter, one special character (!##$%&?), and one number, and that works fine. However, I also want to exclude some special characters from the input, for example, the semicolon (;). I have tried adding (?!.[;]) like so:
((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.[!###$%&?])(?!.[;]).{8,32})
This breaks the entire pattern, though. Could someone explain what I am doing wrong and how I can fix it? Or would it be better to do this manually by using a Javascript listener to check if the password meets the requirements each time the user does a keypress?

Try with:
((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!###$%&?])(?!.*[;]).{8,32})
Fine-tunings from your regex:
Added back an asterisk * to the positive lookahead for symbols list [!###$%&?]
Added back an asterisk * to the negative lookahead for symbol [;]
You need an asterisk * after the dot . in order to allow matching of multiple characters (by *) for any character (by .). Otherwise, your regex allows only ONE single character before the symbols to include and exclude.

Related

How to limit simple form input to 50 characters

Is it possible to limit a simple form input to only 50 characters without javascript?
I have used the max_length attribute, however this includes blank spaces which is not what i want.
I've attempted to use pattern (as suggested on another post), but i can't seem to get that to work either.
Thanks
I don't know why you don't want it to include blanks.
Usually I use max_length including blanks and leave it to the user to trim their excess whitespace. I'm not disagreeing, I honestly don't know what your requirement is.
If you want to allow leading and trailing whitespace, but are willing to leave it to the user to replace excess whitespace within the text to one whitespace character then this is the pattern you want:
<input pattern="^\s*.{0,50}\s*$">
Sometimes for multiline regular expressions, \A is used instead of ^ and \z is used instead of $, but I'm not sure HTML supports that in their regular expressions.

How to set RegEx global flag in HTML pattern attribute of the input element?

I want to client validate a form input (username + password) before sending it to the server (php).
Therefore I applied the pattern attribute in the input tag.
I came up with a RegEx expression that does the job on the server side:
(preg_match_all('/^[a-zA-Z0-9. _äöüßÄÖÜ#-]{1,50}$/', $_POST['username']) == 0)
thereby the global flag is set using preg_match_all (instead of preg_match).
Now I wanted to implement the same RegEx in my pattern attribute in the HTML form.
HTML standard defines that RegEx in the pattern attribute follows RegEx in JavaScript, which devides the expression into "pattern, flags" divided by a comma. I would translate that into HTML like this:
pattern="^[a-zA-Z0-9. _äöüßÄÖÜ#-]{1,50}$,g"
That doesn't work.
All JavaScript RegEx validators I have found enclose the pattern into slashes:
/^[a-zA-Z0-9. _äöüßÄÖÜ#-]{1,50}$/
and say, that the global flag would be behind the last slash:
pattern="/^[a-zA-Z0-9. _äöüßÄÖÜ#-]{1,50}$/g"
That doesn't work either.
Mozilla also states in their developer guide (I also read it elsewhere):
No forward slashes should be specified around the pattern text.
So, how can I get the global flag into the pattern attribute of the input element?
There are a couple of facts you should be aware when using pattern attribute regex:
There is no need to use g flag, the whole string must match the regex, and the regex check will only be performed once, a single match is enough
There is no need wrapping the pattern with regex delimiters, and if you add slashes at the start and end, they will be treated as literal slashes making part of the regex pattern, and in 99.9% of cases that would ruin the regex
You do not even need ^ and $ anchors as the pattern regex must match the entire string input. In fact, the pattern is automatically enclosed with ^(?: and )$, so if you use pattern="^\d+$" (just a quick example), the final regex (in Chrome, e.g.) will look like /^(?:^\d+$)$/u, which looks rather redundant.
So, all you need is
pattern="^[a-zA-Z0-9. _äöüßÄÖÜ#-]{1,50}"
// Or even
pattern="^[\w. äöüßÄÖÜ#-]{1,50}"
Note that [A-Za-z0-9_] = \w in JavaScript regex.

Need a Regex to force either $ or % but not both

Currently, I have the following input defined on an HTML page inside an Angular 9 app:
<input type="text" formControlName="amountToWithholdInput"
onkeyup="this.value = this.value.replace(/[^0-9.%$]/, '');">
As a person types, it automatically removes any character that isn't a number, a $, a % or a decimal.
How do I modify this so it will remove a % if they've already typed a $, and vice-versa (remove the $ if they've already typed a %)? In other words, it needs to check and see if a particular character exists, then remove the "opposite" character if they try to type that.
Or am I going about this all wrong? Is there some other way to do this that I haven't thought of?
Essentially you are asking your users to insert a numeric value with an optional fractional part and a trailing $ or % sign and everything else should be dropped on key input.
So, we could use a regex that matches any string but keeps the fractional numbers and a single sign in an optional group and then replace the original string only with that group $1 while the remainder in the full match gets dropped. Try it:
<input type="text" formControlName="amountToWithholdInput"
onkeyup="this.value = this.value.replace(/^((?:[0-9]+\.?[0-9]*)[%$]?)?.*/, '$1')">
To make this work we need to ensure the inner regex can also match an incomplete version of the final string, i.e. the number, dot, and sign part need to be made optional as well. If you need a more specific (e.g. only two fractional numbers) or different order (e.g. dollar sign first, percent last) we can adjust the inner regex easily but the same concept can be applied, i.e.
<input type="text" formControlName="amountToWithholdInput"
onkeyup="this.value = this.value.replace(/((?:[0-9]*\.?[0-9]{0,2}[%]?)|(?:[$]?[0-9]*\.?[0-9]{0,2}))?.*/, '$1')">
Here, the order of the sub-patterns becomes important as we want to match only one sign and only in a specific position.

data-val-regex-pattern is not working to negate some specfic characters

I am developing a view using html5, I want to validate a VIN field with some particular regex pattern,
So I used data-val-regex-pattern to achieve this.
My validation is to not allow the user to enter i,o,q,I,O,Q he can enter anything in a-zA-Z0-9
So I have written the regex as ^[a-zA-Z0-9&&[^iIoOqQ]]$this regex is not working.
Not working mean when ever I enter ghtygfrt9090 it is saying invalid.
Below is the code:
<input type="text" maxlength="17" data-val-regex-pattern="^[a-zA-Z0-9&&[^iIoOqQ]]$" data-val-regex="VIN is not valid">
Please help !!
The pattern you tried ^[a-zA-Z0-9&&[^iIoOqQ]]$ does not have a quantifier for the character class and if supported will match only a single occurrence of the listed.
Repeating it would look like ^[a-zA-Z0-9&&[^iIoOqQ]]+$
In some regex engines, you could use character class intersection using $$
If it is not supported, you could make use of a negative lookahead:
^(?!.*[iIoOqQ])[a-zA-Z0-9]+$
Regex demo
Another option is to update the ranges excluding the chars
^[a-hj-npr-zA-HJ-NPR-Z]+$
Regex demo

Is it safe to display user input as input values without sanitization?

Say we have a form where the user types in various info. We validate the info, and find that something is wrong. A field is missing, invalid email, et cetera.
When displaying the form to the user again I of course don't want him to have to type in everything again so I want to populate the input fields. Is it safe to do this without sanitization? If not, what is the minimum sanitization that should be done first?
And to clearify: It would of course be sanitized before being for example added to a database or displayed elsewhere on the site.
No it isn't. The user might be directed to the form from a third party site, or simply enter data (innocently) that would break the HTML.
Convert any character with special meaning to its HTML entity.
i.e. & to &, < to <, > to > and " to " (assuming you delimit your attribute values using " and not '.
In Perl use HTML::Entities, in TT use the html filter, in PHP use htmlspecialchars. Otherwise look for something similar in the language you are using.
It is not safe, because, if someone can force the user to submit specific data to your form, you will output it and it will be "executed" by the browser. For instance, if the user is forced to submit '/><meta http-equiv="refresh" content="0;http://verybadsite.org" />, as a result an unwanted redirection will occur.
You cannot insert user-provided data into an HTML document without encoding it first. Your goal is to ensure that the structure of the document cannot be changed and that the data is always treated as data-values and never as HTML markup or Javascript code. Attacks against this mechanism are commonly known as "cross-site scripting", or simply "XSS".
If inserting into an HTML attribute value, then you must ensure that the string cannot cause the attribute value to end prematurely. You must also,of course, ensure that the tag itself cannot be ended. You can acheive this by HTML-encoding any chars that are not guaranteed to be safe.
If you write HTML so that the value of the tag's attribute appears inside a pair of double-quote or single-quote characters then you only need to ensure that you html-encode the quote character you chose to use. If you are not correctly quoting your attributes as described above, then you need to worry about many more characters including whitespace, symbols, punctuation and other ascii control chars. Although, to be honest, its arguably safest to encode these non-alphanumeric chars anyway.
Remember that an HTML attribute value may appear in 3 different syntactical contexts:
Double-quoted attribute value
<input type="text" value="**insert-here**" />
You only need to encode the double quote character to a suitable HTML-safe value such as "
Single-quoted attribute value
<input type='text' value='**insert-here**' />
You only need to encode the single quote character to a suitable HTML-safe value such as ‘
Unquoted attribute value
<input type='text' value=**insert-here** />
You shouldn't ever have an html tag attribute value without quotes, but sometimes this is out of your control. In this case, we really need to worry about whitespace, punctuation and other control characters, as these will break us out of the attribute value.
Except for alphanumeric characters, escape all characters with ASCII values less than 256 with the &#xHH; format (or a named entity if available) to prevent switching out of the attribute. Unquoted attributes can be broken out of with many characters, including [space] % * + , - / ; < = > ^ and | (and more). [para lifted from OWASP]
Please remember that the above rules only apply to control injection when inserting into an HTML attribute value. Within other areas of the page, other rules apply.
Please see the XSS prevention cheat sheet at OWASP for more information
Yes, it's safe, provided of course that you encode the value properly.
A value that is placed inside an attribute in an HTML needs to be HTML encoded. The server side platform that you are using should have methods for this. In ASP.NET for example there is a Server.HtmlEncode method, and the TextBox control will automatically HTML encode the value that you put in the Text property.