Дезінфектор HTML
Дата оновлення перекладу 2022-11-28
Дезінфектор HTML
6.1
Компонент Дезінфектор HTML було представлено в Symfony 6.1.
Компонент Дезінфектор HTML має на меті дезінфекцію/очишення ненадійного HTML-коду (наприклад, створеного редактором WYSIWYG у браузері) в HTML, якому можна довіряти. Він заснований на Пропозиції стандарту Дезінфектора HTML W3C.
Дезінфектор HTML створює нову структуру HTML з нуля, беручи тільки елементи та атрибути, які дозволені конфігурацією. Це означає, що зворотний HTML дуже передбачуваний (містить лише дозволені елементи), але не дуже добре працює з погано відформатованим введенням (наприклад, невалідним HTML). Дезінфектор призначається для двох випадків використання:
- Запобігання атакам безпеки, заснованим на XSS або інших технологіях, що покладаються на виконання зловмисного коду у браузерах відвідувачів;
- Генерування HTML, який завжди поважає певний формат (тільки певні теги, атрибути, хости і т.д.), щоб мати змогу стійко стилізувати результуюче виведення з CSS. Це також захищає ваш додаток від атак, повʼязаних з, наприклад, зміною CSS всієї сторінки.
Установка
Ви можете встановити компонент Дезінфектор HTML за допомогою:
1
$ composer require symfony/html-sanitizer
Базове використання
Використайте клас HtmlSanitizer, щоб дезінфекувати
HTML. У фреймворку Symfony, цей клас доступний як сервіс html_sanitizer
. Цей сервіс буде
автомонтований автоматично, при додаванні підказки для
HtmlSanitizerInterface:
- Framework Use
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Controller/BlogPostController.php
namespace App\Controller;
// ...
use Symfony\Component\HtmlSanitizer\HtmlSanitizerInterface;
class BlogPostController extends AbstractController
{
public function createAction(HtmlSanitizerInterface $htmlSanitizer, Request $request): Response
{
$unsafeContents = $request->request->get('post_contents');
$safeContents = $htmlSanitizer->sanitize($unsafeContents);
// ... продовжувати використовувати безпечний HTML
}
}
Note
Конфігурація дезінфектора HTML за замовчуванням дозволяє всі "безпечні" елементи та атрибути, як визначено Пропозицією стандарту W3C. На практиці, це означає, що результуючий код не міститиме ніяких скриптів, стилів або інших елементів, які можуть викликати дивну поведінку або вигляд сайту. Пізніше у цій статті ви дізнаєтеся, як повністю налаштовувати дезінфектор HTML .
Дезінфекція HTML для конкретного контексту
Метод за замовчуванням sanitize()
очищує HTML-код для використання в елементі <body>
. Використовуючи метод
sanitizeFor(), ви можете повідомити
дезінфектору HTML налаштувати це для <head>
або більш конкретного тегу HTML:
1 2 3 4 5 6 7 8 9 10
// теги, не дозволені в <head>, будуть видалені
$safeInput = $htmlSanitizer->sanitizeFor('head', $userInput);
// зашифровує зворотний HTML з використанням сутностей HTML
$safeInput = $htmlSanitizer->sanitizeFor('title', $userInput);
$safeInput = $htmlSanitizer->sanitizeFor('textarea', $userInput);
// використовує контекст <body>, видаляючи теги, дозволені лише в <head>
$safeInput = $htmlSanitizer->sanitizeFor('body', $userInput);
$safeInput = $htmlSanitizer->sanitizeFor('section', $userInput);
Дезінфекція HTML з введення форми
Компонент Дезінфектор HTML напряму інтегррується з Формами Symfony, щоб дезінфекувати введення форми до його обробки вашим додатком.
Ви можете включити дезінфектор у формах TextType
, або будь-який формі, що розширює
цей тип (на кшталт TextareaType
), використовуючи опцію sanitize_html
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Form/BlogPostType.php
namespace App\Form;
// ...
class BlogPostType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'sanitize_html' => true,
// використати опцію "sanitizer", щоб використати користувацький дезінфектор (див. нижче)
//'sanitizer' => 'app.post_sanitizer',
]);
}
}
Дезінфекція HTML у шаблонах Twig -------------------------------он-
Окрім дезінфекції введення користувача, ви також можете дезінфекувати HTML-код
перед його виведенням у шаблоні Twig, використовуючи фільтр sanitize_html()
:
1 2 3 4
{{ post.body|sanitize_html }}
{# ви такж можете викристати користувацький дезінфектор (див. нижче) #}
{{ post.body|sanitize_html('app.post_sanitizer') }}
Конфігурація
Повіденка дезінфектора HTML може бути повністю налаштована. Це дозволяє вам чітко зазначити, які елементи, атрибути та навіть значення атрибутів, дозволені.
Ви можете зробити це, визначивши новий дезінфектор HTML у конфігурації:
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
block_elements:
- h1
Ця конфігурація визначає новий сервіс html_sanitizer.sanitizer.app.post_sanitizer
.
Цей сервіс буде автозмонтований для сервісів,
які мають параметр HtmlSanitizerInterface $appPostSanitizer
.
Дозвівл базових ліній елементів
Ви можете розпочати користувацький дезінфектор HTML з використання однієї з двох базових ліній:
- Статичні елементи
- Всі елементи та трибути на базовій лінії дозволяють списки із Пропозіції стандарту W3C (це не включає в себе скрипти).
- Безпечні елементи
- Всі елементи та атрибути зі списку "статичних елементів", за виключенням елементів та атрибутів, які такоож можуть призвети до впровадження/клік-джекінгу CSS.
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# включити щось з цього
allow_safe_elements: true
allow_static_elements: true
Дозвіл елементів
Це додає елементи до списку дозволених. Для кожного елемента, ви також можете вказати дозволені атрибути цього елемента. Якщо не задано, всі дозволені атрибути із Пропозиції стандарту W3C - дозволені.
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12 13
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
allow_elements:
# дозволити елемент <article> і 2 атрибути
article: ['class', 'data-attr']
# дозволити елемент <img> і зберегти атрибут src
img: 'src'
# дозволити елемент <h1> з усіма безпечними атрибутами
h1: '*'
Блокування та впущення елементів
Ви також можете блокувати (елемент буде видалено, але його дочки будуть збережені) або впускати (елемент та його дочки будуть видалені) елементи.
Це може бути також використано для видалення елементів зі списку дозволених.
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
# видалити <div>, але обробити дочок
block_elements: ['div']
# видалити <figure> та його дочок
drop_elements: ['figure']
Дозвіл атрибутів
Використовуючи цю опцію, ви можете вказати, які атрибути будуть збережені у зворотному HTML. Атрибут буде дозволений за заданими елементами, або за всі елементами, дозволеними до цього налаштування.
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
allow_attributes:
# дозволити "src' в елементах <iframe>
src: ['iframe']
# дозволити "data-attr" у всіх поточно дозволених елементах
data-attr: '*'
Впущення атрибутів
Ця опція дозволяє вам забороняти атрибути, які були дозволені раніше.
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
allow_attributes:
# дозволити "data-attr" в усіх безпечних елементах...
data-attr: '*'
drop_attributes:
# ...окрім елемента <section>
data-attr: ['section']
# забороняє "style' у будь-якому дозволеному елементі
style: '*'
Форсування значень атрибутів
Використовуючи цю опцію, ви можете форсувати атрибут із заданим значенням в елементі.
Наприклад, використайте наступну конфігурацію, щоб завжди встановлювати rel="noopener noreferrer"
в кожному елементі <a>
(навіть якщо оригінал не містив атрибуту rel
):
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
force_attributes:
a:
rel: noopener noreferrer
Форсування/дозвіл посилань URL
Окрім дозволу/блокування елементів та атрибутів, ви також можете контролювати URL
елементів <a>
:
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
# якщо `true`, всі URLs будуть форсовані з використанням схеми `https://` (замість,
# наприклад, `http://` або `mailto:`)
force_https_urls: true
# вказує дозволені схеми URL. Якщо URL має іншу схему, атрибут
# буде впущено
allowed_link_schemes: ['http', 'https', 'mailto']
# вказує дозволені хости, атрибут буде впущено, якщо URL
# містить інший хост
allowed_link_hosts: ['symfony.com']
# дозволяти відносні посилання, чи ні (тобто, URL без схеми та хосту)
allow_relative_links: true
Форсування/дозвіл медіа URL
Як і з URL посилань , ви також можете контролювати URL
інших медіа в HTML. Наступні атрибути перевіряються дезінфектором HTML: src
, href
,
lowsrc
, background
та ping
.
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
# якщо `true`, всі URL будуть форсовані з використанням схеми `https://` (замість,
# наприклад, `http://` або `data:`)
force_https_urls: true
# вказує дозволені схеми URL. Якщо URL має іншу схему, атрибут
# буде впущено
allowed_media_schemes: ['http', 'https', 'mailto']
# вказує дозволені хости, атрибут буде впущено, якщо URL
# містить інший хост
allowed_media_hosts: ['symfony.com']
# дозволяти відносні посилання, чи ні (тобто, URL без схеми та хосту)
allow_relative_medias: true
Користувацькі дезінфектори атрибутів
Контроль над URL посилань та медіа відбувається за допомогою
UrlAttributeSanitizer.
Ви також можете реалізувати ваш власний дезінфектор атрибутів, щоб контролювати значення
інших атрибутів в HTML. Створіть клас, що реалізує
AttributeSanitizerInterface
та зареєструйте його як сервіс. Після цього, використайте with_attribute_sanitizers
, щоб
включити його для дезінфектора HTML:
- YAML
- XML
- PHP
- Standalone Use
1 2 3 4 5 6 7 8 9 10 11 12
# config/packages/html_sanitizer.yaml
framework:
html_sanitizer:
sanitizers:
app.post_sanitizer:
# ...
with_attribute_sanitizers:
- App\Sanitizer\CustomAttributeSanitizer
# ви також можете відключити попередньо включені користувацькі дезінфектори атрибутів
#without_attribute_sanitizers:
# - App\Sanitizer\CustomAttributeSanitizer