Skip to content

Commit 2792c27

Browse files
MatTheCatMathieu
authored andcommitted
Document the new NoSuspiciousCharacters constraint
1 parent 647da19 commit 2792c27

File tree

2 files changed

+146
-0
lines changed

2 files changed

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