Skip to content

Proposal: HTML passwordrules attribute #3518

@dbates-wk

Description

@dbates-wk

HTML passwordrules attribute

Motivation

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:

	passwordrules

Using the passwordrules attribute

The passwordrules attribute, when specified, describes the set of extra restrictions on the value of the element's value 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:

required: (<identifier> | <character-class>), ..., (<identifier> | <character-class>); allowed: (<identifier> | <character-class>), ..., (<identifier> | <character-class>); max-consecutive: <non-negative-integer>

An <identifier> must case-insensitively match one of the following strings: upper, lower, digit, special, ascii-printable, and unicode. 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 is allowed: ascii-printable. There is no invalid value default.

The values of multiple required/allowed properties are concatenated together and multiple max-consecutive properties behave as if a single max-consecutive property was specified whose value is the minimum of all max-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 to required: 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 the allowed property then the user agent will infer the value of the allowed property according to the rules in How a user agent determines the allowed 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:

<input type="password" minlength="8" passwordrules="required: upper; required: lower; required: digit; max-consecutive: 2">

To require at least one digit or one of -().&@?'#,/"+ (not both), add this to your markup:

<input type="password" minlength="8" passwordrules="required: upper; required: lower; required: digit, [-().&@?'#,/&quot;+]; max-consecutive: 2">

Or to require at least one of -().&@?'#,/"+, add this to your markup:

<input type="password" minlength="8" passwordrules="required: upper; required: lower; required: digit; required: [-().&@?'#,/&quot;+]; max-consecutive: 2">

Alternatively, to optionally allow one of -().&@?'#,/"+, add this to your markup:

<input type="password" minlength="8" passwordrules="required: upper; required: lower; required: digit; allowed: [-().&@?'#,/&quot;+]; max-consecutive: 2">

Another example, to allow a password to contain an arbitrary mix of letters, numbers, and -().&@?'#,/"+, add this to your markup:

<input type="password" minlength="8" passwordrules="allowed: upper, lower, digit, [-().&@?'#,/&quot;+]">

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 to allowed: unicode provides the most entropy for a user agent generated password. Omitting the passwordrules 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 the allowed 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 the allowed property is set to digit, [@!] 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 the required property to a comma-separated list of character class identifiers or custom character classes, or both. For example, if the required property is set to upper, digit then the user agent MUST generate a password that contains at least one ASCII uppercase letter and at least one digit. If required is set to upper, [@!] 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 the passwordrules attribute is set to required: 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 single required property that is set to upper, 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 single required property that is set to upper, [@!] 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, set max-consecutive to 2 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 characters

The 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 of allowed to satisfy it. The following implications immediately fall out from this constraint:

  1. If you specify the required property and do not specify the allowed property then the allowed property is inferred to be the value of the required property.
  2. If you set both the required property and the allowed property then the user agent behaves as if the allowed property were set to the union of the value of the allowed property and the value of the required property. For example, if the required property is set to lower and the allowed property is set to [abc0123] then the user agent MUST behave as if the allowed property were set to lower, [0123]. Another example, if the required property is set to lower and the allowed property is set to upper then the user agent MUST behave as if the allowed property were set to lower, upper.
  3. If neither the required property nor the allowed property are specified then the user agent behaves as if the allowed property was set to ascii-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, and passwordrules. 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:

  1. The maximum password length cannot be less than 12.
  2. Allowed characters must consist of at least two of the following character classes: ASCII uppercase letter, ASCII lowercase letters, digits.

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 the passwordrules attribute.

The passwordrules attributes participates in constraint validation. If the element's value attribute does not satisfy the criterion specified by the value of the passwordrules attribute then the element is in the "suffering from a passwordrules 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 the passwordrules attribute then you must ensure that they have the same value. Otherwise, the user agent will behave as if both fields have set their passwordrules attribute to the result of the union of both field's required property (if any) and the intersection of both field's allowed property (if any) after simplifying the passwordrules attribute of both fields according to rules in Using the passwordrules attribute. For example, if a page contains the following markup:

<input type="password" name="password" minlength="8" passwordrules="required: upper, lower, digit, [-().&@?'#,/&quot;+]; max-consecutive: 2">
<input type="password" name="confirmation-password" minlength="8" passwordrules="required: upper; allowed: [!]; max-consecutive: 3">

Then the user agent must behave as if the markup was:

<input type="password" name="password" minlength="8" passwordrules="required: upper, lower, digit, [-().&@?'#,/&quot;+]; max-consecutive: 2">
<input type="password" name="confirmation-password" minlength="8" passwordrules="required: upper, lower, digit, [-().&@?'#,/&quot;+]; max-consecutive: 2">

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions