コンテンツにスキップ

HTMLサニタイズ

XSS攻撃を防ぐために信頼されていないHTMLをサニタイズ。bluemondayに基づく。

サニタイズはHTMLをパースし、ホワイトリストポリシーを通じてフィルタリングすることで機能。明示的に許可されていない要素と属性は削除される。出力は常に整形式のHTML。

local html = require("html")

一般的なユースケース用の3つの組み込みポリシー:

ポリシーユースケース許可
new_policyカスタムサニタイズなし(ゼロから構築)
ugc_policyユーザーコメント、フォーラム一般的なフォーマット(pbia、リストなど)
strict_policyプレーンテキスト抽出なし(すべてのHTMLを除去)

何も許可しないポリシーを作成。ゼロからカスタムホワイトリストを構築するために使用。

local policy, err = html.sanitize.new_policy()
policy:allow_elements("p", "strong", "em")
policy:allow_attrs("class"):globally()
local clean = policy:sanitize(user_input)

戻り値: Policy, error

ユーザー生成コンテンツ用に事前設定。一般的なフォーマット要素を許可。

local policy = html.sanitize.ugc_policy()
local safe = policy:sanitize('<p>Hello <strong>world</strong></p>')
-- '<p>Hello <strong>world</strong></p>'
local xss = policy:sanitize('<p>Hello <script>alert("xss")</script></p>')
-- '<p>Hello </p>'

戻り値: Policy, error

すべてのHTMLを除去し、プレーンテキストのみを返す。

local policy = html.sanitize.strict_policy()
local text = policy:sanitize('<p>Hello <b>world</b>!</p>')
-- 'Hello world!'

戻り値: Policy, error

特定のHTML要素をホワイトリストに追加。

local policy = html.sanitize.new_policy()
policy:allow_elements("p", "strong", "em", "br")
policy:allow_elements("h1", "h2", "h3")
policy:allow_elements("a", "img")
local result = policy:sanitize('<p>Hello <strong>world</strong></p>')
-- '<p>Hello <strong>world</strong></p>'
パラメータ説明
...string要素タグ名

戻り値: Policy

属性許可を開始。on_elements()またはglobally()でチェーン。

policy:allow_attrs("href"):on_elements("a")
policy:allow_attrs("src", "alt"):on_elements("img")
policy:allow_attrs("class", "id"):globally()
パラメータ説明
...string属性名

戻り値: AttrBuilder

特定の要素のみで属性を許可。

policy:allow_elements("a", "img")
policy:allow_attrs("href", "target"):on_elements("a")
policy:allow_attrs("src", "alt", "width", "height"):on_elements("img")
パラメータ説明
...string要素タグ名

戻り値: Policy

許可されたすべての要素でグローバルに属性を許可。

policy:allow_attrs("class"):globally()
policy:allow_attrs("id"):globally()

戻り値: Policy

正規表現パターンに対して属性値を検証。

-- styleで16進カラーのみを許可
local builder, err = policy:allow_attrs("style"):matching("^color:#[0-9a-fA-F]{6}$")
if err then
return nil, err
end
builder:on_elements("span")
policy:sanitize('<span style="color:#ff0000">Red</span>')
-- '<span style="color:#ff0000">Red</span>'
policy:sanitize('<span style="background:red">Bad</span>')
-- '<span>Bad</span>'
パラメータ説明
patternstring正規表現パターン

戻り値: AttrBuilder, error

セキュリティデフォルトでURL処理を有効化。

policy:allow_elements("a")
policy:allow_attrs("href"):on_elements("a")
policy:allow_standard_urls()

戻り値: Policy

許可するURLスキームを制限。

policy:allow_url_schemes("https", "mailto")
policy:sanitize('<a href="https://example.com">OK</a>')
-- '<a href="https://example.com">OK</a>'
policy:sanitize('<a href="javascript:alert(1)">XSS</a>')
-- '<a>XSS</a>'
パラメータ説明
...string許可するスキーム

戻り値: Policy

相対URLを許可または禁止。

policy:allow_relative_urls(true)
policy:sanitize('<a href="/page">Link</a>')
-- '<a href="/page">Link</a>'
パラメータ説明
allowboolean相対URLを許可

戻り値: Policy

クリーンにパースできないURLを拒否する。trueを指定すると、HTMLサニタイザーがパースできない属性URLは通過させずに削除される。

policy:require_parseable_urls(true)
パラメータ説明
requirebooleanURLがパース可能であることを要求

戻り値: Policy

すべてのリンクにrel="nofollow"を追加。SEOスパムを防止。

policy:allow_attrs("href", "rel"):on_elements("a")
policy:require_nofollow_on_links(true)
policy:sanitize('<a href="https://example.com">Link</a>')
-- '<a href="https://example.com" rel="nofollow">Link</a>'
パラメータ説明
requirebooleannofollowを追加

戻り値: Policy

すべてのリンクにrel="noreferrer"を追加。リファラ漏洩を防止。

policy:require_noreferrer_on_links(true)
パラメータ説明
requirebooleannoreferrerを追加

戻り値: Policy

完全修飾URLにtarget="_blank"を追加。

policy:allow_attrs("href", "target"):on_elements("a")
policy:add_target_blank_to_fully_qualified_links(true)
policy:sanitize('<a href="https://example.com">Link</a>')
-- '<a href="https://example.com" target="_blank">Link</a>'
パラメータ説明
addbooleantarget blankを追加

戻り値: Policy

標準属性付きで<img>を許可。

policy:allow_images()
policy:sanitize('<img src="photo.jpg" alt="Photo">')
-- '<img src="photo.jpg" alt="Photo">'

戻り値: Policy

base64埋め込み画像を許可。

policy:allow_elements("img")
policy:allow_attrs("src"):on_elements("img")
policy:allow_data_uri_images()
policy:sanitize('<img src="data:image/png;base64,iVBORw...">')
-- '<img src="data:image/png;base64,iVBORw...">'

戻り値: Policy

リスト要素を許可: ulollidldtdd

policy:allow_lists()
policy:sanitize('<ul><li>Item 1</li><li>Item 2</li></ul>')
-- '<ul><li>Item 1</li><li>Item 2</li></ul>'

戻り値: Policy

テーブル要素を許可: tabletheadtbodytfoottrtdthcaption

policy:allow_tables()
policy:sanitize('<table><tr><td>Cell</td></tr></table>')
-- '<table><tr><td>Cell</td></tr></table>'

戻り値: Policy

一般的な属性を許可: idclasstitledirlang

policy:allow_elements("p")
policy:allow_standard_attributes()
policy:sanitize('<p id="intro" class="text" title="Introduction">Hello</p>')
-- '<p id="intro" class="text" title="Introduction">Hello</p>'

戻り値: Policy

HTML文字列にポリシーを適用。

local policy = html.sanitize.ugc_policy()
policy:require_nofollow_on_links(true)
local dirty = '<p>Hello</p><script>alert("xss")</script>'
local clean = policy:sanitize(dirty)
-- '<p>Hello</p>'
パラメータ説明
htmlstringサニタイズするHTML

戻り値: string

条件種別再試行可能
無効な正規表現パターンerrors.INVALIDno

エラーの処理についてはエラー処理を参照。