NotCompromisedPassword

NotCompromisedPassword

New in version 4.3: The NotCompromisedPassword constraint was introduced in Symfony 4.3.

Validates that the given password has not been compromised by checking that it is not included in any of the public data breaches tracked by haveibeenpwned.com.

Applies toproperty or method
Options
ClassSymfony\Component\Validator\Constraints\NotCompromisedPassword
ValidatorSymfony\Component\Validator\Constraints\NotCompromisedPasswordValidator

Basic Usage

The following constraint ensures that the rawPassword property of the User class doesn’t store a compromised password:

  • Annotations

    1. // src/Entity/User.php
    2. namespace App\Entity;
    3. use Symfony\Component\Validator\Constraints as Assert;
    4. class User
    5. {
    6. /**
    7. * @Assert\NotCompromisedPassword
    8. */
    9. protected $rawPassword;
    10. }
  • YAML

    1. # config/validator/validation.yaml
    2. App\Entity\User:
    3. properties:
    4. rawPassword:
    5. - NotCompromisedPassword
  • XML

    1. <!-- config/validator/validation.xml -->
    2. <?xml version="1.0" encoding="UTF-8" ?>
    3. <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    5. xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
    6. <class name="App\Entity\User">
    7. <property name="rawPassword">
    8. <constraint name="NotCompromisedPassword"></constraint>
    9. </property>
    10. </class>
    11. </constraint-mapping>
  • PHP

    1. // src/Entity/User.php
    2. namespace App\Entity;
    3. use Symfony\Component\Validator\Constraints as Assert;
    4. use Symfony\Component\Validator\Mapping\ClassMetadata;
    5. class User
    6. {
    7. public static function loadValidatorMetadata(ClassMetadata $metadata)
    8. {
    9. $metadata->addPropertyConstraint('rawPassword', new Assert\NotCompromisedPassword());
    10. }
    11. }

In order to make the password validation, this constraint doesn’t send the raw password value to the haveibeenpwned.com API. Instead, it follows a secure process known as k-anonymity password validation.

In practice, the raw password is hashed using SHA-1 and only the first bytes of the hash are sent. Then, the haveibeenpwned.com API compares those bytes with the SHA-1 hashes of all leaked passwords and returns the list of hashes that start with those same bytes. That’s how the constraint can check if the password has been compromised without fully disclosing it.

For example, if the password is test, the entire SHA-1 hash is a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 but the validator only sends a94a8 to the haveibeenpwned.com API.

See also

When using this constraint inside a Symfony application, define the not_compromised_password option to avoid making HTTP requests in the dev and test environments.

Available Options

groups

type: array | string

It defines the validation group or groups this constraint belongs to. Read more about validation groups.

message

type: string default: This password has been leaked in a data breach, it must not be used. Please use another password.

The default message supplied when the password has been compromised.

payload

type: mixed default: null

This option can be used to attach arbitrary domain-specific data to a constraint. The configured payload is not used by the Validator component, but its processing is completely up to you.

For example, you may want to use several error levels to present failed constraints differently in the front-end depending on the severity of the error.

skipOnError

type: boolean default: false

When the HTTP request made to the haveibeenpwned.com API fails for any reason, an exception is thrown (no validation error is displayed). Set this option to true to not throw the exception and consider the password valid.

threshold

type: integer default: 1

This value defines the number of times a password should have been leaked publicly to consider it compromised. Think carefully before setting this option to a higher value because it could decrease the security of your application.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.