HTML Sanitizer

6.1

6.1

The HTML Sanitizer component was introduced in Symfony 6.1.

HTML Sanitizer コンポーネントは Symfony 6.1 で導入されました。

The HTML Sanitizer component aims at sanitizing/cleaning untrusted HTML code (e.g. created by a WYSIWYG editor in the browser) into HTML that can be trusted. It is based on the HTML Sanitizer W3C Standard Proposal.

HTML サニタイザー コンポーネントは、信頼できない HTML コード (ブラウザーの WYSIWYG エディターによって作成されたものなど) を信頼できる HTML にサニタイズ/クリーニングすることを目的としています。 HTML Sanitizer W3C 標準提案に基づいています。

The HTML sanitizer creates a new HTML structure from scratch, taking only the elements and attributes that are allowed by configuration. This means that the returned HTML is very predictable (it only contains allowed elements), but it does not work well with badly formatted input (e.g. invalid HTML). The sanitizer is targeted for two use cases:

HTML サニタイザーは、構成で許可されている要素と属性のみを取得して、新しい HTML 構造をゼロから作成します。これは、返される HTML が非常に予測可能 (許可された要素のみを含む) であることを意味しますが、不適切な形式の入力 (無効な HTML など) ではうまく機能しません。サニタイザーは、次の 2 つのユース ケースを対象としています。
  • Preventing security attacks based on XSS or other technologies relying on execution of malicious code on the visitors browsers;
    訪問者のブラウザでの悪意のあるコードの実行に依存する XSS またはその他の技術に基づくセキュリティ攻撃を防止します。
  • Generating HTML that always respects a certain format (only certain tags, attributes, hosts, etc.) to be able to consistently style the resulting output with CSS. This also protects your application against attacks related to e.g. changing the CSS of the whole page.
    常に特定の形式 (特定のタグ、属性、ホストなどのみ) を尊重する HTML を生成して、結果の出力を CSS で一貫してスタイル設定できるようにします。これにより、アプリケーションを攻撃から保護することもできます。ページ全体の CSS を変更します。

Installation

You can install the HTML Sanitizer component with:

HTML Sanitizer コンポーネントは、次の方法でインストールできます。
1
$ composer require symfony/html-sanitizer

Basic Usage

Use the HtmlSanitizer class to sanitize the HTML. In the Symfony framework, this class is available as the html_sanitizer service. This service will be autowired automatically when type-hinting for HtmlSanitizerInterface:

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);
        // ... proceed using the safe HTML
    }
}

Note

ノート

The default configuration of the HTML sanitizer allows all "safe" elements and attributes, as defined by the W3C Standard Proposal. In practice, this means that the resulting code will not contain any scripts, styles or other elements that can cause the website to behave or look different. Later in this article, you'll learn how to fully customize the HTML sanitizer.

HTML サニタイザーの既定の構成では、W3C 標準提案で定義されているように、すべての「安全な」要素と属性が許可されます。実際には、結果のコードには、Web サイトの動作や外観の違いを引き起こす可能性のあるスクリプト、スタイル、またはその他の要素が含まれないことを意味します。この記事の後半で、HTML サニタイザーを完全にカスタマイズする方法を学習します。

Sanitizing HTML for a Specific Context

The default sanitize() method cleans the HTML code for usage in the <body> element. Using the sanitizeFor() method, you can instruct HTML sanitizer to customize this for the <head> or a more specific HTML tag:

デフォルトの sanitize() メソッドは、要素で使用するために HTML コードをクリーンアップします。 sanitizeFor() メソッドを使用すると、HTML サニタイザーに、 またはより具体的な HTML タグ用にこれをカスタマイズするように指示できます。
1
2
3
4
5
6
7
8
9
10
// tags not allowed in <head> will be removed
$safeInput = $htmlSanitizer->sanitizeFor('head', $userInput);

// encodes the returned HTML using HTML entities
$safeInput = $htmlSanitizer->sanitizeFor('title', $userInput);
$safeInput = $htmlSanitizer->sanitizeFor('textarea', $userInput);

// uses the <body> context, removing tags only allowed in <head>
$safeInput = $htmlSanitizer->sanitizeFor('body', $userInput);
$safeInput = $htmlSanitizer->sanitizeFor('section', $userInput);

Sanitizing HTML from Form Input

The HTML sanitizer component directly integrates with Symfony Forms, to sanitize the form input before it is processed by your application.

HTML サニタイザー コンポーネントは Symfony Forms と直接統合され、アプリケーションによって処理される前にフォーム入力をサニタイズします。

You can enable the sanitizer in TextType forms, or any form extending this type (such as TextareaType), using the sanitize_html option:

sanitize_html オプションを使用して、TextType フォーム、またはこのタイプを拡張する任意のフォーム (TextareaType など) でサニタイザーを有効にできます。
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,
            // use the "sanitizer" option to use a custom sanitizer (see below)
            //'sanitizer' => 'app.post_sanitizer',
        ]);
    }
}

Sanitizing HTML in Twig Templates

Besides sanitizing user input, you can also sanitize HTML code before outputting it in a Twig template using the sanitize_html() filter:

ユーザー入力をサニタイズするだけでなく、sanitize_html() フィルターを使用して、Twig テンプレートで出力する前に HTML コードをサニタイズすることもできます。
1
2
3
4
{{ post.body|sanitize_html }}

{# you can also use a custom sanitizer (see below) #}
{{ post.body|sanitize_html('app.post_sanitizer') }}

Configuration

The behavior of the HTML sanitizer can be fully customized. This allows you to explicitly state which elements, attributes and even attribute values are allowed.

HTML サニタイザーの動作は完全にカスタマイズできます。これにより、どの要素、属性、さらには属性値を許可するかを明示的に指定できます。

You can do this by defining a new HTML sanitizer in the configuration:

これを行うには、構成で新しい HTML サニタイザーを定義します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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

This configuration defines a new html_sanitizer.sanitizer.app.post_sanitizer service. This service will be autowired for services having an HtmlSanitizerInterface $appPostSanitizer parameter.

この構成は、新しい html_sanitizer.sanitizer.app.post_sanitizerservice を定義します。このサービスは、HtmlSanitizerInterface $appPostSanitizer パラメーターを持つサービスに対して自動配線されます。

Allow Element Baselines

You can start the custom HTML sanitizer by using one of the two baselines:

次の 2 つのベースラインのいずれかを使用して、カスタム HTML サニタイザーを開始できます。
Static elements
All elements and attributes on the baseline allow lists from the W3C Standard Proposal (this does not include scripts).
ベースラインのすべての要素と属性は、W3C 標準提案のリストを許可します (これにはスクリプトは含まれません)。
Safe elements
All elements and attributes from the "static elements" list, excluding elements and attributes that can also lead to CSS injection/click-jacking.
「静的要素」リストのすべての要素と属性。ただし、CSS インジェクション/クリックジャッキングにつながる可能性のある要素と属性は除きます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
  • Standalone Use
    スタンドアロン使用
1
2
3
4
5
6
7
8
# config/packages/html_sanitizer.yaml
framework:
    html_sanitizer:
        sanitizers:
            app.post_sanitizer:
                # enable either of these
                allow_safe_elements: true
                allow_static_elements: true

Allow Elements

This adds elements to the allow list. For each element, you can also specify the allowed attributes on that element. If not given, all allowed attributes from the W3C Standard Proposal are allowed.

これにより、要素が許可リストに追加されます。要素ごとに、その要素で許可される属性を指定することもできます。指定しない場合、W3C 標準提案のすべての許可された属性が許可されます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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:
                    # allow the <article> element and 2 attributes
                    article: ['class', 'data-attr']
                    # allow the <img> element and preserve the src attribute
                    img: 'src'
                    # allow the <h1> element with all safe attributes
                    h1: '*'

Block and Drop Elements

You can also block (the element will be removed, but its children will be kept) or drop (the element and its children will be removed) elements.

要素をブロック (要素は削除されますが、その子は保持されます) またはドロップ (要素とその子は削除されます) することもできます。

This can also be used to remove elements from the allow list.

これは、許可リストから要素を削除するためにも使用できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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:
                # ...

                # remove <div>, but process the children
                block_elements: ['div']
                # remove <figure> and its children
                drop_elements: ['figure']

Allow Attributes

Using this option, you can specify which attributes will be preserved in the returned HTML. The attribute will be allowed on the given elements, or on all elements allowed before this setting.

このオプションを使用すると、返される HTML で保持する属性を指定できます。属性は、指定された要素、またはこの設定の前に許可されたすべての要素で許可されます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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:
                    # allow "src' on <iframe> elements
                    src: ['iframe']

                    # allow "data-attr" on all elements currently allowed
                    data-attr: '*'

Drop Attributes

This option allows you to disallow attributes that were allowed before.

このオプションを使用すると、以前は許可されていた属性を禁止できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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:
                    # allow the "data-attr" on all safe elements...
                    data-attr: '*'

                drop_attributes:
                    # ...except for the <section> element
                    data-attr: ['section']
                    # disallows "style' on any allowed element
                    style: '*'

Force Attribute Values

Using this option, you can force an attribute with a given value on an element. For instance, use the follow config to always set rel="noopener noreferrer" on each <a> element (even if the original one didn't contain a rel attribute):

このオプションを使用すると、要素に特定の値を持つ属性を強制できます。たとえば、次の構成を使用して、各要素に常に rel="noopener noreferrer" を設定します (元の要素に rel 属性が含まれていなくても):
  • YAML
    YAML
  • XML
    XML
  • PHP
    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

Besides allowing/blocking elements and attributes, you can also control the URLs of <a> elements:

要素と属性を許可/ブロックするだけでなく、要素の URL を制御することもできます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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:
                # ...

                # if `true`, all URLs will be forced using the `https://` scheme (instead
                # of e.g. `http://` or `mailto:`)
                force_https_urls: true

                # specifies the allowed URL schemes. If the URL has a different scheme, the
                # attribute will be dropped
                allowed_link_schemes: ['http', 'https', 'mailto']

                # specifies the allowed hosts, the attribute will be dropped if the
                # URL contains a different host
                allowed_link_hosts: ['symfony.com']

                # whether to allow relative links (i.e. URLs without scheme and host)
                allow_relative_links: true

Force/Allow Media URLs

Like link URLs, you can also control the URLs of other media in the HTML. The following attributes are checked by the HTML sanitizer: src, href, lowsrc, background and ping.

リンク URL と同様に、HTML で他のメディアの URL を制御することもできます。次の属性は、HTML サニタイザーによってチェックされます: src、href、lowsrc、background、および ping。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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:
                # ...

                # if `true`, all URLs will be forced using the `https://` scheme (instead
                # of e.g. `http://` or `data:`)
                force_https_urls: true

                # specifies the allowed URL schemes. If the URL has a different scheme, the
                # attribute will be dropped
                allowed_media_schemes: ['http', 'https', 'mailto']

                # specifies the allowed hosts, the attribute will be dropped if the URL
                # contains a different host
                allowed_media_hosts: ['symfony.com']

                # whether to allow relative URLs (i.e. URLs without scheme and host)
                allow_relative_medias: true

Custom Attribute Sanitizers

Controlling the link and media URLs is done by the UrlAttributeSanitizer. You can also implement your own attribute sanitizer, to control the value of other attributes in the HTML. Create a class implementing AttributeSanitizerInterface and register it as a service. After this, use with_attribute_sanitizers to enable it for an HTML sanitizer:

リンクとメディア URL の制御は、UrlAttributeSanitizer によって行われます。独自の属性サニタイザーを実装して、HTML の他の属性の値を制御することもできます。 AttributeSanitizerInterface を実装するクラスを作成し、サービスとして登録します。この後、with_attribute_sanitizers を使用して HTML サニタイザーを有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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

                # you can also disable previously enabled custom attribute sanitizers
                #without_attribute_sanitizers:
                #    - App\Sanitizer\CustomAttributeSanitizer