Skip to content

Commit 40c94ec

Browse files
MatTheCatMathieu
authored andcommitted
Document the new NoSuspiciousCharacters constraint
1 parent 647da19 commit 40c94ec

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
NoSuspiciousCharacters
2+
======================
3+
4+
A good thing about Unicode is that it allows to use (almost) every imaginable character.
5+
A bad thing is that this makes spoofing rather easy: "symfony.com" and "ѕymfony.com"
6+
look similar, but the latter actually starts with a `cyrillic small letter dze`_.
7+
This is why it is recommended to check user-submitted, public-facing identifiers for
8+
suspicious characters to prevent spoofing attempts.
9+
10+
This constraint performs such validation on strings or :phpclass:`Stringable`s.
11+
As it leverages PHP's :phpclass:`Spoofchecker`, the intl extension must be enabled to
12+
use it.
13+
14+
========== ===================================================================
15+
Applies to :ref:`property or method <validation-property-target>`
16+
Class :class:`Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharacters`
17+
Validator :class:`Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharactersValidator`
18+
========== ===================================================================
19+
20+
Basic Usage
21+
-----------
22+
23+
The following constraint will ensures a username cannot be spoofed by using many
24+
detection mechanisms:
25+
26+
.. configuration-block::
27+
28+
.. code-block:: php-attributes
29+
30+
// src/Entity/User.php
31+
namespace App\Entity;
32+
33+
use Symfony\Component\Validator\Constraints as Assert;
34+
35+
class User
36+
{
37+
#[Assert\NoSuspiciousCharacters]
38+
private string $username;
39+
}
40+
41+
.. code-block:: yaml
42+
43+
# config/validator/validation.yaml
44+
App\Entity\User:
45+
properties:
46+
username:
47+
- NoSuspiciousCharacters: ~
48+
49+
.. code-block:: xml
50+
51+
<!-- config/validator/validation.xml -->
52+
<?xml version="1.0" encoding="UTF-8" ?>
53+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
54+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
55+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
56+
57+
<class name="App\Entity\User">
58+
<property name="username">
59+
<constraint name="NoSuspiciousCharacters"/>
60+
</property>
61+
</class>
62+
</constraint-mapping>
63+
64+
.. code-block:: php
65+
66+
// src/Entity/User.php
67+
namespace App\Entity;
68+
69+
use Symfony\Component\Validator\Constraints as Assert;
70+
use Symfony\Component\Validator\Mapping\ClassMetadata;
71+
72+
class User
73+
{
74+
public static function loadValidatorMetadata(ClassMetadata $metadata)
75+
{
76+
$metadata->addPropertyConstraint('username', new Assert\NoSuspiciousCharacters());
77+
}
78+
}
79+
80+
.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
81+
82+
Options
83+
-------
84+
85+
``checks``
86+
~~~~~~~~~~
87+
88+
**type**: ``int`` **default**: all
89+
90+
This option is a bitmask of the checks you want to perform on the string:
91+
92+
* ``NoSuspiciousCharacters::CHECK_INVISIBLE`` checks for the presence of invisible characters such as zero-width spaces, or character sequences that are likely not to display, such as multiple occurrences of the same non-spacing mark.
93+
* ``NoSuspiciousCharacters::CHECK_MIXED_NUMBERS`` checks for numbers from different numbering systems (since ICU 58).
94+
* ``NoSuspiciousCharacters::CHECK_HIDDEN_OVERLAY`` checks for combining characters hidden in their preceding one (since ICU 62).
95+
96+
You can also configure additional requirements using :ref:`locales <locales>` and
97+
:ref:`restrictionLevel <restrictionlevel>`.
98+
99+
``locales``
100+
~~~~~~~~~~~
101+
102+
**type**: ``array`` **default**: :ref:`framework.enabled_locales <reference-enabled-locales>`
103+
104+
Restrict the string's characters to those normally used with the associated languages.
105+
106+
For example, the character "π" would be considered suspicious if you restricted the
107+
locale to "English", because the Greek script is not associated with it.
108+
109+
Passing an empty array, or configuring :ref:`restrictionLevel <restrictionlevel>` to
110+
``NoSuspiciousCharacters::RESTRICTION_LEVEL_NONE`` will disable this requirement.
111+
112+
``restrictionLevel``
113+
~~~~~~~~~~~~~~~~~~~~
114+
115+
**type**: ``int`` **default**: ``NoSuspiciousCharacters::RESTRICTION_LEVEL_MODERATE`` on ICU >= 58, else ``NoSuspiciousCharacters::RESTRICTION_LEVEL_SINGLE_SCRIPT``
116+
117+
Configures the set of acceptable characters for the validated string through a
118+
specified "level":
119+
120+
* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_MINIMAL`` requires the string's characters to match :ref:`the configured locales <locales>`'.
121+
* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_MODERATE`` also requires the string to be `covered`_ by Latin and any one other `Recommended`_ or `Limited Use`_ script, except Cyrillic, Greek, and Cherokee.
122+
* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_HIGH`` also requires the string to be `covered`_ by any of the following sets of scripts (since ICU 58):
123+
124+
* Latin + Han + Bopomofo (or equivalently: Latn + Hanb)
125+
* Latin + Han + Hiragana + Katakana (or equivalently: Latn + Jpan)
126+
* Latin + Han + Hangul (or equivalently: Latn + Kore)
127+
* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_SINGLE_SCRIPT`` also requires the string to be `single-script`_.
128+
* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_ASCII`` also requires the string's characters to be in the ASCII range (since ICU 58).
129+
130+
You can accept all characters by setting this option to
131+
``NoSuspiciousCharacters::RESTRICTION_LEVEL_NONE``.
132+
133+
.. include:: /reference/constraints/_groups-option.rst.inc
134+
135+
.. include:: /reference/constraints/_payload-option.rst.inc
136+
137+
.. _`cyrillic small letter dze`: https://graphemica.com/%D1%95
138+
.. _`single-script`: https://unicode.org/reports/tr39/#def-single-script
139+
.. _`covered`: https://unicode.org/reports/tr39/#def-cover
140+
.. _`Recommended`: https://www.unicode.org/reports/tr31/#Table_Recommended_Scripts
141+
.. _`Limited Use`: https://www.unicode.org/reports/tr31/#Table_Limited_Use_Scripts

reference/constraints/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ String Constraints
2929
* :doc:`UserPassword </reference/constraints/UserPassword>`
3030
* :doc:`NotCompromisedPassword </reference/constraints/NotCompromisedPassword>`
3131
* :doc:`CssColor </reference/constraints/CssColor>`
32+
* :doc:`NoSuspiciousCharacters </reference/constraints/NoSuspiciousCharacters>`
3233

3334
Comparison Constraints
3435
~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)