Sanitização HTML

Sanitize HTML não confiavel para prevenir ataques XSS. Baseado em bluemonday.

A sanitização funciona parseando HTML e filtrando através de uma política de whitelist. Elementos e atributos não explicitamente permitidos sao removidos. A saida e sempre HTML bem formado.

Carregamento

local html = require("html")

Políticas Predefinidas

Tres políticas embutidas para casos de uso comuns:

Política Caso de Uso Permite
new_policy Sanitização customizada Nada (construir do zero)
ugc_policy Comentarios de usuários, foruns Formatação comum (p, b, i, a, listas, etc.)
strict_policy Extração de texto puro Nada (remove todo HTML)

Política Vazia

Cria uma política que não permite nada. Use para construir uma whitelist customizada do zero.

local policy, err = html.sanitize.new_policy()

policy:allow_elements("p", "strong", "em")
policy:allow_attrs("class"):globally()

local clean = policy:sanitize(user_input)

Retorna: Policy, error

Política de Conteudo de Usuário

Pre-configurada para conteudo gerado por usuários. Permite elementos de formatação comuns.

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>'

Retorna: Policy, error

Política Restrita

Remove todo HTML, retorna apenas texto puro.

local policy = html.sanitize.strict_policy()

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

Retorna: Policy, error

Controle de Elementos

Permitir Elementos

Whitelist de elementos HTML especificos.

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>'
Parâmetro Tipo Descrição
... string Nomes de tags de elementos

Retorna: Policy

Controle de Atributos

Permitir Atributos

Iniciar permissão de atributo. Encadear com on_elements() ou globally().

policy:allow_attrs("href"):on_elements("a")
policy:allow_attrs("src", "alt"):on_elements("img")
policy:allow_attrs("class", "id"):globally()
Parâmetro Tipo Descrição
... string Nomes de atributos

Retorna: AttrBuilder

Em Elementos Especificos

Permitir atributos apenas em elementos especificos.

policy:allow_elements("a", "img")
policy:allow_attrs("href", "target"):on_elements("a")
policy:allow_attrs("src", "alt", "width", "height"):on_elements("img")
Parâmetro Tipo Descrição
... string Nomes de tags de elementos

Retorna: Policy

Em Todos os Elementos

Permitir atributos globalmente em qualquer elemento permitido.

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

Retorna: Policy

Com Pattern Matching

Validar valores de atributo contra padrão regex.

-- Permitir apenas cores hex no style
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>'
Parâmetro Tipo Descrição
pattern string Padrão regex

Retorna: AttrBuilder, error

Segurança de URL

URLs Padrão

Habilitar tratamento de URL com padroes de segurança.

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

Retorna: Policy

Esquemas de URL

Restringir quais esquemas de URL sao permitidos.

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>'
Parâmetro Tipo Descrição
... string Esquemas permitidos

Retorna: Policy

URLs Relativas

Permitir ou proibir URLs relativas.

policy:allow_relative_urls(true)

policy:sanitize('<a href="/page">Link</a>')
-- '<a href="/page">Link</a>'
Parâmetro Tipo Descrição
allow boolean Permitir URLs relativas

Retorna: Policy

Adicionar rel="nofollow" a todos os links. Previne spam de 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>'
Parâmetro Tipo Descrição
require boolean Adicionar nofollow

Retorna: Policy

Adicionar rel="noreferrer" a todos os links. Previne vazamento de referrer.

policy:require_noreferrer_on_links(true)
Parâmetro Tipo Descrição
require boolean Adicionar noreferrer

Retorna: Policy

Adicionar target="_blank" a URLs totalmente qualificadas.

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>'
Parâmetro Tipo Descrição
add boolean Adicionar target blank

Retorna: Policy

Métodos de Conveniencia

Permitir Imagens

Permitir <img> com atributos padrão.

policy:allow_images()

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

Retorna: Policy

Permitir Imagens Data URI

Permitir imagens embutidas em 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...">'

Retorna: Policy

Permitir Listas

Permitir elementos de lista: ul, ol, li, dl, dt, dd.

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>'

Retorna: Policy

Permitir Tabelas

Permitir elementos de tabela: table, thead, tbody, tfoot, tr, td, th, caption.

policy:allow_tables()

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

Retorna: Policy

Permitir Atributos Padrão

Permitir atributos comuns: id, class, title, dir, lang.

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>'

Retorna: Policy

Sanitize

Aplicar política a string 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>'
Parâmetro Tipo Descrição
html string HTML para sanitizar

Retorna: string

Erros

Condição Tipo Retentável
Padrão regex inválido errors.INVALID não

Veja Error Handling para trabalhar com erros.