diff --git a/reference/constraints.rst b/reference/constraints.rst index 93339043bc4..67544bc45c3 100644 --- a/reference/constraints.rst +++ b/reference/constraints.rst @@ -79,6 +79,7 @@ Validation Constraints Reference constraints/Traverse constraints/CssColor constraints/Cascade + constraints/NoSuspiciousCharacters The Validator is designed to validate objects against *constraints*. In real life, a constraint could be: "The cake must not be burned". In diff --git a/reference/constraints/NoSuspiciousCharacters.rst b/reference/constraints/NoSuspiciousCharacters.rst new file mode 100644 index 00000000000..a0b65cb6cd3 --- /dev/null +++ b/reference/constraints/NoSuspiciousCharacters.rst @@ -0,0 +1,157 @@ +NoSuspiciousCharacters +====================== + +.. versionadded:: 6.3 + + The ``NoSuspiciousCharacters`` constraint was introduced in Symfony 6.3. + +.. + + Because Unicode contains such a large number of characters and incorporates + the varied writing systems of the world, incorrect usage can expose programs + or systems to possible security attacks. + + `Unicode® Technical Standard #39`_ + +"symfony.com" and "ѕymfony.com" look similar, but the latter actually starts with a +`cyrillic small letter dze`_. It could make a user think they'll navigate to Symfony's +website, whereas it would be somewhere else. +This is a kind of `spoofing attack`_ (called "IDN homograph attack"). It tries to +identify something as something else to exploit the resulting confusion. +This is why it is recommended to check user-submitted, public-facing identifiers for +suspicious characters in order to prevent such attacks. + +This constraint ensures strings or :phpclass:`Stringable`s do not include any +suspicious characters. As it leverages PHP's :phpclass:`Spoofchecker`, the intl +extension must be enabled to use it. + +========== =================================================================== +Applies to :ref:`property or method ` +Class :class:`Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharacters` +Validator :class:`Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharactersValidator` +========== =================================================================== + +Basic Usage +----------- + +The following constraint will ensures a username cannot be spoofed by using many +detection mechanisms: + +.. configuration-block:: + + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\NoSuspiciousCharacters] + private string $username; + } + + .. code-block:: yaml + + # config/validator/validation.yaml + App\Entity\User: + properties: + username: + - NoSuspiciousCharacters: ~ + + .. code-block:: xml + + + + + + + + + + + + + .. code-block:: php + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + use Symfony\Component\Validator\Mapping\ClassMetadata; + + class User + { + public static function loadValidatorMetadata(ClassMetadata $metadata) + { + $metadata->addPropertyConstraint('username', new Assert\NoSuspiciousCharacters()); + } + } + +.. include:: /reference/constraints/_empty-values-are-valid.rst.inc + +Options +------- + +``checks`` +~~~~~~~~~~ + +**type**: ``integer`` **default**: all + +This option is a bitmask of the checks you want to perform on the string: + +* ``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. +* ``NoSuspiciousCharacters::CHECK_MIXED_NUMBERS`` (usable with ICU 58 or higher) checks for numbers from different numbering systems. +* ``NoSuspiciousCharacters::CHECK_HIDDEN_OVERLAY`` (usable with ICU 62 or higher) checks for combining characters hidden in their preceding one. + +You can also configure additional requirements using :ref:`locales ` and +:ref:`restrictionLevel `. + +``locales`` +~~~~~~~~~~~ + +**type**: ``array`` **default**: :ref:`framework.enabled_locales ` + +Restrict the string's characters to those normally used with the associated languages. + +For example, the character "π" would be considered suspicious if you restricted the +locale to "English", because the Greek script is not associated with it. + +Passing an empty array, or configuring :ref:`restrictionLevel ` to +``NoSuspiciousCharacters::RESTRICTION_LEVEL_NONE`` will disable this requirement. + +``restrictionLevel`` +~~~~~~~~~~~~~~~~~~~~ + +**type**: ``integer`` **default**: ``NoSuspiciousCharacters::RESTRICTION_LEVEL_MODERATE`` on ICU >= 58, otherwise ``NoSuspiciousCharacters::RESTRICTION_LEVEL_SINGLE_SCRIPT`` + +Configures the set of acceptable characters for the validated string through a +specified "level": + +* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_MINIMAL`` requires the string's characters to match :ref:`the configured locales `'. +* ``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. +* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_HIGH`` (usable with ICU 58 or higher) also requires the string to be `covered`_ by any of the following sets of scripts: + + * Latin + Han + Bopomofo (or equivalently: Latn + Hanb) + * Latin + Han + Hiragana + Katakana (or equivalently: Latn + Jpan) + * Latin + Han + Hangul (or equivalently: Latn + Kore) +* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_SINGLE_SCRIPT`` also requires the string to be `single-script`_. +* ``NoSuspiciousCharacters::RESTRICTION_LEVEL_ASCII`` (usable with ICU 58 or higher) also requires the string's characters to be in the ASCII range. + +You can accept all characters by setting this option to +``NoSuspiciousCharacters::RESTRICTION_LEVEL_NONE``. + +.. include:: /reference/constraints/_groups-option.rst.inc + +.. include:: /reference/constraints/_payload-option.rst.inc + +.. _`Unicode® Technical Standard #39`: https://unicode.org/reports/tr39/ +.. _`cyrillic small letter dze`: https://graphemica.com/%D1%95 +.. _`spoofing attack`: https://en.wikipedia.org/wiki/Spoofing_attack +.. _`single-script`: https://unicode.org/reports/tr39/#def-single-script +.. _`covered`: https://unicode.org/reports/tr39/#def-cover +.. _`Recommended`: https://www.unicode.org/reports/tr31/#Table_Recommended_Scripts +.. _`Limited Use`: https://www.unicode.org/reports/tr31/#Table_Limited_Use_Scripts diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc index 6df4ecac1d4..1c16d47f81d 100644 --- a/reference/constraints/map.rst.inc +++ b/reference/constraints/map.rst.inc @@ -29,6 +29,7 @@ String Constraints * :doc:`UserPassword ` * :doc:`NotCompromisedPassword ` * :doc:`CssColor ` +* :doc:`NoSuspiciousCharacters ` Comparison Constraints ~~~~~~~~~~~~~~~~~~~~~~