Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 92c5537

Browse files
committed
Added docs for the NotPwned constraint
1 parent 3e06be9 commit 92c5537

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

reference/constraints.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Validation Constraints Reference
6666
constraints/All
6767
constraints/UserPassword
6868
constraints/Valid
69+
constraints/NotPwned
6970

7071
The Validator is designed to validate objects against *constraints*.
7172
In real life, a constraint could be: "The cake must not be burned". In

reference/constraints/NotPwned.rst

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
NotPwned
2+
========
3+
4+
.. versionadded:: 4.3
5+
6+
The ``NotPwned`` constraint was introduced in Symfony 4.3.
7+
8+
Validates that the given password has not been compromised by checking that is
9+
not included in any of the public data breaches tracked by `haveibeenpwned.com`_.
10+
11+
========== ===================================================================
12+
Applies to :ref:`property or method <validation-property-target>`
13+
Options - `groups`_
14+
- `message`_
15+
- `payload`_
16+
- `skipOnError`_
17+
- `threshold`_
18+
Class :class:`Symfony\\Component\\Validator\\Constraints\\NotPwned`
19+
Validator :class:`Symfony\\Component\\Validator\\Constraints\\NotPwnedValidator`
20+
========== ===================================================================
21+
22+
Basic Usage
23+
-----------
24+
25+
The following constraint ensures that the ``rawPassword`` property of the
26+
``User`` class doesn't store a compromised password:
27+
28+
.. configuration-block::
29+
30+
.. code-block:: php-annotations
31+
32+
// src/Entity/User.php
33+
namespace App\Entity;
34+
35+
use Symfony\Component\Validator\Constraints as Assert;
36+
37+
class User
38+
{
39+
// ...
40+
41+
/**
42+
* @Assert\NotPwned
43+
*/
44+
protected $rawPassword;
45+
}
46+
47+
.. code-block:: yaml
48+
49+
# config/validator/validation.yaml
50+
App\Entity\User:
51+
properties:
52+
rawPassword:
53+
- NotPwned
54+
55+
.. code-block:: xml
56+
57+
<!-- config/validator/validation.xml -->
58+
<?xml version="1.0" encoding="UTF-8" ?>
59+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
60+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
61+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
62+
63+
<class name="App\Entity\User">
64+
<property name="rawPassword">
65+
<constraint name="NotPwned"></constraint>
66+
</property>
67+
</class>
68+
</constraint-mapping>
69+
70+
.. code-block:: php
71+
72+
// src/Entity/User.php
73+
namespace App\Entity;
74+
75+
use Symfony\Component\Validator\Mapping\ClassMetadata;
76+
use Symfony\Component\Validator\Constraints as Assert;
77+
78+
class User
79+
{
80+
public static function loadValidatorMetadata(ClassMetadata $metadata)
81+
{
82+
$metadata->addPropertyConstraint('rawPassword', new Assert\NotPwned());
83+
}
84+
}
85+
86+
In order to make the password validation, this constraint doesn't send the raw
87+
password value to the ``haveibeenpwned.com`` API. Instead, it follows a secure
88+
process known as `k-anonimity password validation`_.
89+
90+
In practice, the raw password is hashed using SHA-1 and only the first bytes of
91+
the hash are sent. Then, the ``haveibeenpwned.com`` API compares those bytes
92+
with the SHA-1 hashes of all leaked passwords and returns the list of hashes
93+
that start with those same bytes. That's how the constraint can check if the
94+
password has been compromised without fully disclosing it.
95+
96+
For example, if the password is ``test``, the entire SHA-1 hash is
97+
``a94a8fe5ccb19ba61c4c0873d391e987982fbbd3`` but the validator only sends
98+
``a94a8`` to the ``haveibeenpwned.com`` API.
99+
100+
Available Options
101+
-----------------
102+
103+
.. include:: /reference/constraints/_groups-option.rst.inc
104+
105+
message
106+
~~~~~~~
107+
108+
**type**: ``string`` **default**: ``This password has been leaked in a data breach, it must not be used. Please use another password.``
109+
110+
The default message supplied when the password has been compromised.
111+
112+
.. include:: /reference/constraints/_payload-option.rst.inc
113+
114+
skipOnError
115+
~~~~~~~~~~~
116+
117+
**type**: ``boolean`` **default**: ``false``
118+
119+
When the HTTP request made to the ``haveibeenpwned.com`` API fails for any
120+
reason, an exception is thrown (no validation error is displayed). Set this
121+
option to ``true`` to not throw the exception and consider the password valid.
122+
123+
threshold
124+
~~~~~~~~~
125+
126+
**type**: ``integer`` **default**: ``1``
127+
128+
This value defines the number of times a password should have been leaked
129+
publicly to consider it compromised. Think carefully before setting this option
130+
to a higher value because it could decrease the security of your application.
131+
132+
.. _`haveibeenpwned.com`: https://haveibeenpwned.com/
133+
.. _`k-anonimity password validation`: https://blog.cloudflare.com/validating-leaked-passwords-with-k-anonymity/

reference/constraints/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,4 @@ Other Constraints
8888
* :doc:`Collection </reference/constraints/Collection>`
8989
* :doc:`Count </reference/constraints/Count>`
9090
* :doc:`UniqueEntity </reference/constraints/UniqueEntity>`
91+
* :doc:`NotPwned </reference/constraints/NotPwned>`

0 commit comments

Comments
 (0)