-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: HTML passwordrules attribute #3518
Comments
/cc @battre |
possible refinement, since a perverse |
@Bsitter Good catch! I agree that it's bad if perverse password rules limit the number of possibilities to an overly low number. For an implementation requirement like "the password constraints will be ignored if they would reduce the number of possible passwords below 2**60", the standard would need to include an algorithm to calculate the number of possible passwords to enable interoperable behavior. If browsers calculated it slightly differently, it would be a significant interop problem. We tried to evade the need for a full entropy calculation by having higher-level rules to ensure a wide enough range of passwords. Specifically, passwordrules must be ignored if the max length too low, or the set of allowed characters is too small a range. You are right that excessive "required" directives could also overly limit the passwords. In the spirit of the easier to determine rule for rejecting overly restrictive "passwordrules", how about setting an upper limit on the number of "required" directives that may be present? |
First of all, I really like this! Giving declarative credential generation more love is great. My main worry here is the complexity of the attribute and requiring another custom parser for it. Can we consolidate that with something somehow? Perhaps just having more attributes or going full JSON? Should we also integrate this with https://w3c.github.io/webappsec-credential-management/ somehow? I understand that has adoption due to WebAuthn so presumably it's something that'll stick around and we need to account for? (The other thing we should include in the examples advocating this technique is |
@othermaciej indeed, and I actually considered including such a wrinkle on my original comment but realized that some |
Another question: is character class merging the intended behavior for
Otherwise |
@bsittler I think what this proposal says is right for On the "trivial character class" rule, that makes sense to me as an approach, but the specific proposal would require a minimum length of 15 instead of 12 for passwords with the typical "must include at least one uppercase, at least one lowercase, at least one number" restriction. If in addition a special character is required, that would be a minimum length of 16. That seems excessive, as adequate entropy is possible for 12-character passwords with either of these common restrictions. @annevk We care more about the capabilities than the syntax. That said:
|
I disagree with the fundamental premise of this. :( Restrictions on passwords beyond minimum length (and maybe a large maximum length) are all fundamentally bad, particularly restricted characters - such restrictions indicate that the site is storing passwords very badly (in plaintext, with bad escaping practices when interacting with their database). Required characters are also generally a bad restriction - it's much better to simply increase the minimum length and let people use whatever characters they (or their pw generators) want. Do we really want to be adding a feature whose primary use-case is making it easier for already-broken sites to continue being broken? |
Restrictions on passwords are indeed bad. I agree it would be best if they went away. But it also seems unlikely they will go away any time soon. Password generators are extremely good. About the safest thing anyone can do for their online security is to use a unique randomly generated password for each site. If password generators can't work with the existing password restrictions of websites, then that leads to a bad user experience (user counts on generator, then the site rejects their password) and poor security (user makes up a weak or reused password on the spot). The current state of the art is to maintain a list of site-specific quirks to get the password generator to do its job right. Safari has a pretty extensive set. We'd like password generators (including ours) to be able to do a good job without needing a quirks list. Thus, even though password restrictions are likely harmful on net (other than minimum length), the most practical harm reduction is for sites with restrictions to make it obvious and machine readable what those restrictions are. |
If the WHATWG decides to add a |
It seems like many, but not all, use cases in the OP can be covered by the existing pattern attribute. (For example, specifying allowed or disallowed characters.) Could we consider scoping this down to only the use cases that cannot be accomplished with today's technology? |
You're right! I updated my proposal to remove this sentence (indicated by a strikethrough). |
I take it you feel that the WARNING paragraph in the proposal is not sufficient? |
Although some of the use cases could be accomplished with today's technology they cannot be accomplished easily or succinctly. For instance, consider the following common variant of the first example in the proposal that disregards the consecutive character requirement: a password that has least 8 characters consisting of a mix of uppercase and lowercase letters, at least one number. This can be accomplished with today's technology. It is non-trivial to do so. Accomplishing this task or variants of it are exemplified by the regexps in https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a. |
@js-choi I don't think password restrictions are related to storing passwords in plaintext. They are either because of dumb legacy system limitations (max lengths, very restricted set of allowed characters), actually good (minimum length limit) or well-intentioned attempts to get users to make handmade passwords that are resilient to guessing or offline dictionary attack against a leaked hashed password database (for example, the popular "one letter, one number, one special" requirement). |
@othermaciej: I agree insofar that many cases of password restrictions are due to dumb legacy system limitations or well-intentioned encouragement of better handmade passwords. I was mostly responding to @tabatkins’s saying that "such restrictions indicate that the site is storing passwords very badly (in plaintext, with bad escaping practices when interacting with their database)”, which may well also be sometimes true. @dbates-wk: The currently worded warning:
…is not quite forceful or empathetic in discouraging password restrictions in general, a discouragement that @tabatkins probably believes ought to be done. I personally am sympathetic to his view, but I am also sympathetic to making usability better for users of password managers. From my own field, bad password restrictions are a particularly pernicious problem in healthcare/clinical applications. Addressing password restrictions at all may be seen by developers as a general statement from WHATWG on its disposition toward password restrictions, for better or for worse. Care should therefore be crafted in how its specification is worded: it probably would not hurt for that warning above to be more forceful and empathetic against password restrictions in general. Such force may somewhat ameliorate @tabatkins’s general reservations against addressing password restrictions at all. |
@domenic We thought about just using the (1) Consider a common limitation like: "must contain at least one letter and one at least number, and may contain !@#$%^&*()_+-=". It's possible to do with a regexp but it's pretty non-obvious. Here is the clearest regexp I could come up with that implements this rule: (2) In theory it's possible to use a regexp to drive generation rather than matching, but it's pretty hard. Getting a password generator to produce a uniformly random password that matches an arbitrary regexp is possible in theory, but way harder than getting it to produce a random password that matches rules of the type that So even though |
@js-choi I am fine with having a more assertive warning. I think the wording in the spec will have very little influence on prevalence of password restrictions one way or the other, but we should do our best to avoid proliferating restrictions even a little. |
Are there many sites out there which restrict passwords in this way, yet still receive enough attention from developers who would be likely to add this attribute? It's anecdotal, but the only sites on which I've encountered restrictive password limitations are ones which have not seen updates for years. I'm also a bit concerned that adding an attribute - despite warnings in the spec - might encourage more sites to introduce restrictions. Do you have data showing how common password restrictions are today, and if their usage is declining? It seems like this might become a smaller problem within a few years, as older systems get replaced. |
It seems like it should be possible to cover 99% of cases by generating ~50 passwords according to different rules and transparently match them against the Unless we foresee other uses for it besides covering the remaining cases for password rules, the added complexity of introducing a unique syntax ought to be avoided. |
@Zirro Many sites have password restrictions, including ones that are popular and actively maintained. For example, here's the restrictions from etrade.com (as stated by the site):
Other sites have hidden restrictions. They don't name any up front, but reject some passwords in practice.
This is inefficient and likely to still fail in edge cases, so I doubt we'd adopt this over a quirks list. Also, the bigger problem with While I am sympathetic to the desire to avoid technically redundant features, I think framing password rules in a more direct way will solve a real practical problem that can't be solved just by pushing existing features harder. |
Fixed this up to match your expectation. |
I updated the proposal. With the exception of the example sections, I demarcated removals from- and additions to- the original proposal using strikethrough and italic, respectively. |
Really great discussion above. I've made a related proposal for a |
I work on 1Password's password generator. I would like to offer a few comments on some of the discussion. ascii-printable is the right default@battre said
I strongly advice against encouraging unicode in passwords until we can be confident that the site properly normalizes the unicode. There are (at least) three different byte sequences that a character like "Å" can come out as. If the system accepting the password doesn't systematically normalize the input, then a user can find themselves locked out merely by changing their keyboard or even an operating system upgrade. Entropy calculation in the face of multiple required setsEnsuring a uniform distribution and being able to compute the strength is a tricky problem. My colleagues and I presented a solution. See Please see https://github.com/1Password/spg/blob/master/passwordscon/paper.pdf We get some bits for freeWhen targeting particular strength, we should keep in mind that it is much more computationally expensive to test 2^70 passwords than it is to test 2^70 AES keys. Exactly how much more expensive is going to depend on how they are hashed, but even without any slow hashing, the process of generating guesses of passwords to try is going to be far slower than generating a key. So where might want a 90 bit key, we can do with a 70 bit password (by some estimates). |
I also work for 1Password and completely agree with Dominic. Although I've also dreamed of having a spec like this, folks who would most likely implement it would be least likely to require any password rules (outside of perhaps minlength, which can already be added). |
One small data point: hey.com has adopted passwordrules. (In fairness, these rules would probably be met automatically by any reasonable password generator.)
|
Whether 70 bits of entropy is enough for a password is kind of dependent on what hash function is in use (for the password database breach threat model at least). If it's bcrypt or scrypt, then 70 bits is more than enough. If it's MD5, then probably not. For very weak hashes like legacy Unix |
I didn't know about this proposal prior, but I wrote a related sketch here: https://discourse.wicg.io/t/add-password-restriction-attributes-to-input-type-password/4767 It's mostly the same as this mod syntax, but it's more regexp-based and deconstructs it a bit more. Also, I'm not a fan of using literals only, as while alphanumeric characters are a pretty standard subset, support for special characters varies so wildly between sites in my experience I'm not convinced any named subset for that is worth anything. That and some places explicitly include various Unicode characters as valid. Some places are also "must contain characters in at least 3 of the following groups" and others have restricted words (like emails), and the current proposal as specified above doesn't encompass either. I didn't add anything for consecutive character restrictions, though. |
I'm sorry I just don't see the logic here: "we currently don't have anything for sites to use to specify password rules" -> "so let's look at the uses of the autocomplete attribute" -> "it's not used much" -> "therefore password-rules wouldn't be used either" -> "we should not implement this standard". My thoughts:
|
It's about opportunity costs. Investing into this is a decision against investing into something else. With infinite resources, I agree that it would be nice to see this happen. |
Why not just consider the entropy of the password without the required characters and use that as a lower bound? Then just add on the required characters from there? It's not optimal, sure, but wouldn't it work? For example, let's say we want 80 bits of entropy. Let's assume printable ascii. That's ~ 96^12, or 12 characters. Let's say most sites require 3 different types of characters. 15 character password should then have a lower bound of 80 bits of entropy if 12 of them are generated using a normal distribution? 9 characters, ~60 bits so 12 chars (pretty reasonable). Probably wouldn't want to go lower than 7 chars (~2^46) + 3, or 10 chars. So basically pick 10, 12, 15 and suggest one of those. Or suggest in the language a minimum number like 8 (that's 56 bits, a nice number) prior to any character class restrictions and recommend that the minimum should be 1 more for each character restriction added. |
@battre Do you have more recent statistics about the use of |
No, I don't have any metrics easily accessible. |
I want to point out that separating websites into "modern" and "not modern" without talking about at least backend vs frontend is an overly simplistic approach to determine the impact of this proposal. There are plenty of situations where it is relatively easy to rewrite a frontend to be much more modern than the underlying backend. Particularly in my home country there's a ton of "lipstick-on-a-pig" development going on, where frontends are written in some JS framework from the past 5 years while the URLs hint at some absolutely arcane backend. So, you cannot conclude that a recently updated website (according to some stats) will not have any use for this new attribute. It may still serve up data from a backend that was written in the early 2000s and therefore have a need to expose password restrictions. Additionally some companies find themselves in situations where lack of hashing is a feature. A recent example is a globally operating ISP I won't name who does not hash their customer's passwords, because customer support reps need to ask for passwords on the phone. You may disagree with the entire premise of that decision, but that ISP's website is as modern as it can be, as far as web standards go. Assuming you don't reject the premise, Password managers aren't a great fit for the user anyway though. I am not sure about the opportunity cost of this proposal myself, but I think the way people this thread talk about usecases and stats passes value judgement on attribute usage too quickly. That said, people are already implementing this proposal in both websites and password managers, so not standardizing some iteration of this would IMO be a mistake, regardless of opportunity cost. |
Well, I'm the only one using the login forms on this site but still wanted to try these. - Raise min length to 15 chars - Help password managers understand the form fields - Indicate which account is the password being changed for - Tell 1Password to generate a bit longer+stronger password by default TIL the `passwordrules` attribute thanks to this great @ScottHelme's blog post https://scotthelme.co.uk/boosting-account-security-pwned-passwords-and-zxcvbn/ Here are some helpful links: - [Design your website to work best with 1Password](https://developer.1password.com/docs/web/compatible-website-design/) - [Password Rules Validation Tool](https://developer.apple.com/password-rules/) by Apple, apparently supported in Safari [since 2018 (Safari 12)](https://webkit.org/blog/8327/safari-technology-preview-58-with-safari-12-features-is-now-available/) - whatwg/html#3518 _This is a companion to #89._
It's implemented in Safari as of Safari 12. Apple even provides a generation tool. It's not in WebKit, just in Safari. |
Checking usage in httparchive: currently 22 pages use a
Results with extracted markup snippets and page rank: https://docs.google.com/spreadsheets/d/1O3ogKWl9Jkm98BC8OdQLK6AXnEsiPbIN-EEOZcl7xvE/edit?usp=sharing query
|
Also 19 instances in GitHub code search It seems that so far this feature has very low adoption rate despite being supported in Safari and 1Password for 5 years. Maybe it would be more rapidly adopted if implemented in all browsers and password managers, though. |
Doesn't help that it's gotten almost no media or mainstream tech blog coverage, either. web.dev has no reference to it anywhere, not even in their sign-in best practices page. This reddit post, linking to this blog post about the attribute, is 2 years old and only has a score of 14 and 8 comments. Also, Mozilla explicitly objects to the proposal's premise: https://mozilla.github.io/standards-positions/#passwordrules-attribute
And personally, having taken a step back from this for so long, I don't feel they're wrong. If you're forward-thinking enough with security to think to use this new attribute to help people, you're also likely forward-thinking enough to know why limiting password characters is a bad idea. You also may even know that passphrases are more secure, despite the smaller source alphabet. So honestly, I find it unlikely this will ever take off even if it did gain wider awareness and publicity, not in 2 years, not in 5, not in 10. |
I don't really understand what you're saying here.
I don't think it's Note that from the official Chromium's documentation, it's supposed to take into account attributes like
(Notice the important What happens in reality is that
The By the way, I personally use KeePass to create completely random, 32 chars long passwords with any kind of characters so my passwords are strong enough. No need to use passphrases. |
@jmevel Read that last paragraph a little more closely. I wasn't explaining why password limitations were bad. I was explaining why the attribute would never get used in practice. And the supporting point wasn't directly that they're bad, but knowledge of them being bad resulting in the server being designed without much in terms of password restrictions other than maybe the obvious of minimum search space, not being one of the most used passwords, a minimum of 8-12 characters, and an unrealistic max of like 64+ characters just for the sake of security. If the server accepts anything, the password manager can generate anything, and no reasonable password manager defaults to anything less than 12 characters anyways (so it doesn't matter). As for the problem sites this attribute is even being suggested for, they are also almost universally at best half-maintained. They aren't likely adding these attributes anytime soon. If you're lucky, they might use |
HTML
passwordrules
attributeMotivation
Some user agents offer to generate random per-site passwords on behalf of the user. Safari has built-in support for this, and add-on password managers such as 1Password add this functionality. This feature improves user security by guaranteeing high-entropy passwords and avoiding reuse of the same password on multiple sites.
One challenge with this approach is that sites have different rules for valid passwords. Many sites require characters from specific sets to be present, or have other constraints. The best known solution is to have a generator rule that matches the password requirements of many sites, plus a curated list of per-site quirks for sites with unusual requirements.
A better solution would be for the website to express its password requirements in machine-readable form, and in a format that is suited for use with a generation algorithm. While the
pattern
attribute allows expressing many value constraints, it's very hard to use it to drive a generator. It's also tricky to express many popular password constraints (such as a limit on the number of consecutive repeated characters) in a regexp.Proposed Solution
We propose a new content attribute on the HTML input element called
passwordrules
and define a mini syntax for web authors to use to express their requirements (rules). We describe how a user agent will makes use of these rules and the minimum requirements for the user agent to honor these rules below.Extensions to HTML
We propose the following new content attribute be added to the HTML input element:
Using the
passwordrules
attributeThe
passwordrules
attribute, when specified, describes the set of extra restrictions on the value of the element'svalue
attribute that a user agent must consider when generating a password and performing client-side form validation. Its value is a semicolon delimited string of one or more property/value pairs and has the form:An
<identifier>
must case-insensitively match one of the following strings:upper
,lower
,digit
,special
,ascii-printable
, andunicode
. These identifiers correspond to the set of ASCII uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), all other ASCII printable characters - including the space character - (-~!@#$%^&*_+=`|(){}[:;"'<>,.? ]), all ASCII printable characters, and all Unicode characters, respectively.A
<character-class>
is a custom characters class.A
<non-negative-integer>
is a valid non-negative integer.The missing value default for
passwordrules
isallowed: ascii-printable
. There is no invalid value default.The values of multiple
required
/allowed
properties are concatenated together and multiplemax-consecutive
properties behave as if a singlemax-consecutive
property was specified whose value is the minimum of allmax-consecutive
properties. Duplicate property values are ignored. Specifying multiple character classes is equivalent to specifying one character class that represents the union of the characters in all character classes. Empty character classes are ignored. Properties without a value are ignored. The following examples illustrate the aforementioned equivalences:required: upper; required: lower
<=>required: upper, lower
allowed: upper; allowed: lower
<=>allowed: upper, lower
max-consecutive: 4; max-consecutive: 2
<=>max-consecutive: 2
required: upper, lower, upper
<=>required: upper, lower
required: [abc], [def]
<=>required: [abcdef]
allowed: upper, []
<=>allowed: upper
required: ; allowed: upper
<=>allowed: upper
NOTE: The expression
required: upper; required: lower
is NOT equivalent torequired: upper, lower
. See Requiring that a password contain certain characters.If you do not specify the
max-consecutive
property then it defaults to being unbounded. That is, the user agent can generate a password with one or more arbitrary length runs of the same character (e.g. ooops).If you specify the
required
property and do not specify theallowed
property then the user agent will infer the value of theallowed
property according to the rules in How a user agent determines theallowed
characters.For example, to require a password have at least 8 characters consisting of a mix of uppercase and lowercase letters, at least one number, and at most two consecutive characters, add this to your markup:
To require at least one digit or one of -().&@?'#,/"+ (not both), add this to your markup:
Or to require at least one of -().&@?'#,/"+, add this to your markup:
Alternatively, to optionally allow one of -().&@?'#,/"+, add this to your markup:
Another example, to allow a password to contain an arbitrary mix of letters, numbers, and -().&@?'#,/"+, add this to your markup:
WARNING: With the exception of the NOTE below, each property/value pair reduces the entropy of a user agent generated password and makes the password more likely to be guessed or brute-forced. The more characters that are required the more likely the user agent generated password can be guessed or brute-forced.
NOTE: Setting the
passwordrules
attribute toallowed: unicode
provides the most entropy for a user agent generated password. Omitting thepasswordrules
attribute or setting it to the empty string provides the second most entropy for a user agent generated password.Custom character classes
A custom character class is a list of ASCII characters that are surrounded by square brackets (e.g. [abc]). Any non-ASCII printable characters in the set are ignored. The dash character (-) is reserved as a special character. To list '-' as a literal character it must appear immediately after the opening square bracket '['. The right square bracket (]) is also reserved as a special character. To list ']' as a literal character it must appear immediately before the closing square bracket ']'.
Specifying the characters allowed to be in a password
The value of the
allowed
property is a comma-separated list of character class identifiers or custom character classes, or both. Each custom characters class represents a set of characters that are allowed to be in the generated password. For example, if theallowed
property is set to[*]]
then the generated password is allowed to contain ']' and '*', but it is not allowed to contain '[' among other non-listed characters. If theallowed
property is set todigit, [@!]
then the generated password is allowed to contain one or more ASCII digits, one or more '@'s and one or more '!'s, but it is not allowed to contain '[' among other non-listed characters.Requiring that a password contain certain characters
You can require that a password contain certain characters or classes of characters by setting the value of therequired
property to a comma-separated list of character class identifiers or custom character classes, or both. For example, if therequired
property is set toupper, digit
then the user agent MUST generate a password that contains at least one ASCII uppercase letter and at least one digit. Ifrequired
is set toupper, [@!]
then the user agent MUST generate a password that contains at least one ASCII uppercase letter and either '@' or '!'.A user agent must generate a password that contains at least one character from each
required
property. For example, if thepasswordrules
attribute is set torequired: upper; required: digit
then the user agent MUST generate a password that contains at least ASCII uppercase letter and at least one digit. If there is a singlerequired
property that is set toupper, digit
then the user agent MUST generate a password that contains at least one ASCII uppercase letter or at least one digit. If there is a singlerequired
property that is set toupper, [@!]
then the user agent MUST generate a password that contains at least one ASCII uppercase letter or '@' or '!'.Limiting the number of consecutive repeated characters
The value of
max-consecutive
is a non-negative integer that represents the maximum length of a run of consecutive identical characters that can be present in the generated password. For example, setmax-consecutive
to2
to disallow a user agent from generating a password that contains a run of more than 2 of the same character (e.g. "ooops" - contains three consecutive o's).How a user agent determines the
allowed
charactersThe set of required characters MUST always be a subset of the set of allowed characters. If the value of
passwordrules
violates this constraint then the user agent MUST adjust the value ofallowed
to satisfy it. The following implications immediately fall out from this constraint:required
property and do not specify theallowed
property then theallowed
property is inferred to be the value of therequired
property.required
property and theallowed
property then the user agent behaves as if theallowed
property were set to the union of the value of theallowed
property and the value of therequired
property. For example, if therequired
property is set tolower
and theallowed
property is set to[abc0123]
then the user agent MUST behave as if theallowed
property were set tolower, [0123]
. Another example, if therequired
property is set tolower
and theallowed
property is set toupper
then the user agent MUST behave as if theallowed
property were set tolower, upper
.required
property nor theallowed
property are specified then the user agent behaves as if theallowed
property was set toascii-printable
.How a user agent generates a password based on
passwordrules
A user agent will generate a password using an algorithm or heuristic of its choice that respects the following attributes of a password element (not necessarily in order):
minlength
,maxlength
, andpasswordrules
. If the set of constraints imposed by the aforementioned attributes fail to meet the following minimum restrictions then they are considered nonconforming and the user agent is REQUIRED to ignore them:Characters in the generated password MUST be expressed in Normalization Form C and must conform to the following UAX31 profile:
Interaction with client-side form validation
It is not recommended to specify both the
pattern
attribute and thepasswordrules
attribute.The
passwordrules
attributes participates in constraint validation. If the element'svalue
attribute does not satisfy the criterion specified by the value of thepasswordrules
attribute then the element is in the "suffering from apasswordrules
mismatch" validity state and the element is invalid for the purposes of constraint validation.Confirmation password field
Some web pages have both a password field ("primary password field") and a confirmation password field. The
passwordrules
attribute needs only to appear on one of these fields. If both fields have thepasswordrules
attribute then you must ensure that they have the same value. Otherwise, the user agent will behave as if both fields have set theirpasswordrules
attribute to the result of the union of both field'srequired
property (if any) and the intersection of both field'sallowed
property (if any) after simplifying thepasswordrules
attribute of both fields according to rules in Using thepasswordrules
attribute. For example, if a page contains the following markup:Then the user agent must behave as if the markup was:
The text was updated successfully, but these errors were encountered: