Voltar às atualizações
New releaseAug 3, 2026

DOMPurify v3.4.13

DOMPurify - um sanitizador de XSS somente DOM, super-rápido e supertolerante para HTML, MathML e SVG. DOMPurify funciona com um padrão seguro, mas oferece muita configurabilidade e hooks. Demonstração:

Compartilhar

DOMPurify

npm License Downloads dependents npm package minimized gzipped size (select exports) Cloudback

OpenSSF Best Practices Build & Test OpenSSF Scorecard Socket Badge snyk.io package health

O DOMPurify é um sanitizador de XSS exclusivamente DOM, super-rápido e ultra-tolerante para HTML, MathML e SVG.

Também é muito simples de usar e de começar. O DOMPurify foi iniciado em fevereiro de 2014 e, entretanto, atingiu a versão v3.4.14.

O DOMPurify é executado como JavaScript e funciona em todos os navegadores modernos (Safari (10+), Opera (15+), Edge, Firefox e Chrome — bem como praticamente qualquer outro que use Blink, Gecko ou WebKit). Ele não quebra no MSIE ou em outros navegadores legados. Ele simplesmente não faz nada.

Observe que o DOMPurify v2.5.9 é a versão mais recente com suporte ao MSIE. Para atualizações de segurança importantes compatíveis com o MSIE, use o branch 2.x.

Nossos testes automatizados cobrem 9 combinações de navegador/SO nos mecanismos atuais (Chromium, Firefox e WebKit em Ubuntu, macOS e Windows) a cada push, e uma matriz separada reexecuta a suíte em snapshots de mecanismos mais antigos (até aproximadamente Chromium 110, Firefox 108 e WebKit 16.4, com cerca de três anos) para que regressões em navegadores desatualizados também sejam detectadas. Também executamos Node.js v20, v22, v24, v25 e v26 com o DOMPurify no jsdom. Versões mais antigas do Node também são conhecidas por funcionar, mas... sem garantias.

O DOMPurify é escrito por profissionais de segurança com vasta experiência em ataques web e XSS. Não tema. Para mais detalhes, leia também sobre nossos Objetivos de Segurança e Modelo de Ameaças. Por favor, leia. Sério. E se você gosta dos detalhes sangrentos, a página Classes de Ataque e Histórico de Bypass cataloga os truques de mutação de parser, namespace, clobbering e template contra os quais o DOMPurify se defende.

O projeto DOMPurify inspirou a criação da HTML Sanitizer API, que já está disponível em muitos navegadores. A mesma capacidade está agora sendo padronizada diretamente na especificação HTML do WHATWG.

Índice

O que ele faz?

O DOMPurify sanitiza HTML e previne ataques XSS. Você pode alimentar o DOMPurify com, por exemplo, uma string cheia de HTML sujo e ele retornará uma string (a menos que configurado de outra forma) com HTML limpo. O DOMPurify removerá tudo o que contiver HTML perigoso e, assim, prevenirá ataques XSS e outras porcarias. Ele também é incrivelmente rápido. Usamos as tecnologias que o navegador fornece e as transformamos em um filtro de XSS. Quanto mais rápido for o seu navegador, mais rápido o DOMPurify será.

Como eu uso?

É fácil. Basta incluir o DOMPurify no seu site.

Usando a versão não minificada (com source-map disponível)```html

### Usar a versão de produção minificada e testada (source-map disponível)```html
<script type="text/javascript" src="dist/purify.min.js"></script>

Depois disso, você pode sanitizar strings executando o seguinte código:```js const clean = DOMPurify.sanitize(dirty);

Ou talvez isto, se adoras trabalhar com Angular ou semelhante:```js
import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize('<b>hello there</b>');

O HTML resultante pode ser escrito em um elemento do DOM usando innerHTML ou no DOM usando document.write(). Isso fica totalmente a seu critério. Observe que, por padrão, permitimos HTML, SVG e MathML. Se você precisar apenas de HTML, o que pode ser um caso de uso muito comum, você também pode configurar isso facilmente:```js const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });

### Existe algum potencial para armadilhas?

Bem, note que, se você _primeiro_ sanitizar o HTML e depois modificá-lo _posteriormente_, você pode facilmente **anular os efeitos da sanitização**. Se você alimentar o markup sanitizado para outra biblioteca _após_ a sanitização, certifique-se de que a biblioteca não mexa no HTML por conta própria. Consulte os [Objetivos de Segurança e Modelo de Ameaças](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model) para receitas de uso seguro e as tags/atributos que valem a pena pensar duas vezes, e [Classes de Ataque e Histórico de Bypass](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History) para entender por que o pós-processamento e a alteração do contexto do markup derrotam a sanitização.

### Ok, faz sentido, vamos em frente

Após sanitizar seu markup, você também pode dar uma olhada na propriedade `DOMPurify.removed` e descobrir quais elementos e atributos foram descartados. Por favor, **não use** essa propriedade para tomar decisões críticas de segurança. Ela é apenas uma pequena ajuda para mentes curiosas.

### Executando o DOMPurify no servidor

O DOMPurify tecnicamente também funciona no lado do servidor com Node.js. Nosso suporte busca seguir o [ciclo de lançamentos do Node.js](https://nodejs.org/en/about/previous-releases).

Executar o DOMPurify no servidor requer que um DOM esteja presente, o que provavelmente não é surpresa. Normalmente, o [jsdom](https://github.com/jsdom/jsdom) é a ferramenta de escolha e nós **recomendamos fortemente** usar a versão mais recente do _jsdom_.

Por quê? Porque versões mais antigas do _jsdom_ são conhecidas por terem bugs que resultam em XSS _mesmo que_ o DOMPurify faça tudo 100% corretamente. Existem **vetores de ataque conhecidos** em, por exemplo, _jsdom v19.0.0_ que foram corrigidos no _jsdom v20.0.0_ - e realmente recomendamos manter o _jsdom_ atualizado por causa disso.

Esteja também ciente de que ferramentas como [happy-dom](https://github.com/capricorn86/happy-dom) existem, mas **não são consideradas seguras** neste momento. Combinar o DOMPurify com o _happy-dom_ atualmente não é recomendado e provavelmente levará a XSS. Para entender por que o DOM do lado do servidor que você escolhe faz parte da sua base de computação confiável, consulte [Classes de Ataque e Histórico de Bypass](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).

Fora isso, você pode usar o DOMPurify no servidor sem problemas. Provavelmente. Isso realmente depende do _jsdom_ ou de qualquer DOM que você utilize no lado do servidor. Se você conseguir conviver com isso, é assim que você faz funcionar:```bash
npm install dompurify
npm install jsdom

Para jsdom (use uma versão atualizada), isto deve resolver:```js const createDOMPurify = require('dompurify'); const { JSDOM } = require('jsdom');

const window = new JSDOM('').window; const DOMPurify = createDOMPurify(window); const clean = DOMPurify.sanitize('hello there');

Ou até isto, se preferir trabalhar com imports:```js
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';

const window = new JSDOM('').window;
const purify = DOMPurify(window);
const clean = purify.sanitize('<b>hello there</b>');

Se tiveres problemas em fazê-lo funcionar na tua configuração específica, considera consultar o fantástico projeto isomorphic-dompurify, que resolve muitos dos problemas com que as pessoas se podem deparar.```bash npm install isomorphic-dompurify

Aqui está a tradução do conteúdo fornecido:

```markdown
## Instalação

### Requisitos

- Python 3.8 ou superior
- pip (gerenciador de pacotes do Python)

### Passos de Instalação

1. Clone o repositório:
   ```bash
   git clone https://github.com/exemplo/ferramenta-seguranca.git
   cd ferramenta-seguranca
  1. Instale as dependências:

    pip install -r requirements.txt
    
  2. Verifique a instalação:

    python ferramenta.py --versao
    

Uso

Comandos Básicos

Para executar uma verificação básica:

python ferramenta.py --alvo https://exemplo.com

Para executar uma verificação avançada com opções personalizadas:

python ferramenta.py --alvo https://exemplo.com --nivel 3 --saida relatorio.json

Opções Disponíveis

OpçãoDescrição
--alvoEspecifica o URL ou endereço IP de destino
--nivelDefine o nível de profundidade da verificação (1-5)
--saidaDefine o arquivo de saída para o relatório
--silenciosoSuprime a saída detalhada no console
--proxyDefine um servidor proxy para as requisições

Exemplos de Uso

Verificação básica de vulnerabilidades:

python ferramenta.py --alvo https://exemplo.com

Verificação com relatório detalhado:

python ferramenta.py --alvo https://exemplo.com --saida relatorio.html

Verificação usando um proxy:

python ferramenta.py --alvo https://exemplo.com --proxy http://127.0.0.1:8080

Configuração

O arquivo de configuração config.yaml permite personalizar o comportamento da ferramenta:

# Configurações gerais
tempo_limite: 30
threads: 10
agente_usuario: "FerramentaSeguranca/1.0"

# Configurações de verificação
verificar_headers: true
verificar_cookies: true
verificar_ssl: true

# Configurações de relatório
formato_saida: "json"
incluir_recomendacoes: true

Arquitetura

A ferramenta é dividida em vários módulos principais:

ferramenta-seguranca/
├── ferramenta.py          # Ponto de entrada principal
├── config.yaml            # Arquivo de configuração
├── requisitos.txt         # Dependências do projeto
├── nucleo/
│   ├── __init__.py
│   ├── scanner.py         # Motor de verificação principal
│   ├── relatorio.py       # Geração de relatórios
│   └── utils.py           # Funções utilitárias
├── modulos/
│   ├── __init__.py
│   ├── sql_injection.py   # Detecção de injeção SQL
│   ├── xss.py             # Detecção de XSS
│   └── headers.py         # Análise de cabeçalhos HTTP
└── testes/
    ├── __init__.py
    └── test_scanner.py    # Testes unitários

Contribuindo

Agradecemos contribuições para melhorar esta ferramenta. Por favor, siga estas etapas:

  1. Faça um fork do repositório
  2. Crie um branch para sua funcionalidade (git checkout -b feature/nova-funcionalidade)
  3. Faça commit das suas alterações (git commit -am 'Adiciona nova funcionalidade')
  4. Envie para o branch (git push origin feature/nova-funcionalidade)
  5. Abra um Pull Request

Licença

Este projeto está licenciado sob a Licença MIT - consulte o arquivo LICENÇA para obter detalhes.

Esta ferramenta é fornecida apenas para fins educacionais e de teste de segurança autorizado. O uso indevido desta ferramenta para atacar sistemas sem permissão explícita é ilegal e antiético. O desenvolvedor não se responsabiliza por qualquer uso indevido desta ferramenta.

import DOMPurify from 'isomorphic-dompurify';

const clean = DOMPurify.sanitize('<s>hello</s>');
```
## Existe uma demonstração?

Claro que existe uma demonstração! [Jogue com o DOMPurify](https://cure53.de/purify)

## E se eu encontrar uma falha de segurança?

Primeiro de tudo, entre em contato conosco imediatamente via [email](mailto:[email protected]) para que possamos trabalhar em uma correção. [Chave PGP](https://keyserver.ubuntu.com/pks/lookup?op=vindex&search=0xC26C858090F70ADA)

Além disso, você provavelmente se qualifica para um bug bounty! O pessoal do [Fastmail](https://www.fastmail.com/) usa o DOMPurify em seus serviços e adicionou nossa biblioteca ao escopo do bug bounty deles. Então, se você encontrar uma forma de contornar ou enfraquecer o DOMPurify, dê também uma olhada no site deles e nas [informações do bug bounty](https://www.fastmail.com/about/bugbounty/).

## Alguns exemplos de purificação, por favor?

Como o markup purificado se parece? Bem, [a demonstração](https://cure53.de/purify) mostra isso para um monte de elementos maliciosos. Mas vamos mostrar também alguns exemplos menores!```js
DOMPurify.sanitize(''); // becomes <img src="https://raw.githubusercontent.com/cure53/dompurify/main/x">
DOMPurify.sanitize('<svg><g/onload=alert(2)//<p>'); // becomes <svg><g></g></svg>
DOMPurify.sanitize('<p>abcdef</p>'); // becomes <p>abc</p>
DOMPurify.sanitize('<math><mi//xlink:href="data:x,<script>alert(4)</script>">'); // becomes <math><mi></mi></math>
DOMPurify.sanitize('<TABLE><tr><td>HELLO</tr></TABL>'); // becomes <table><tbody><tr><td>HELLO</td></tr></tbody></table>
DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><li><a href="//google.com">click</a></li></ul>
```
Estes são apenas uma amostra. Para a taxonomia completa das classes de ataque das quais essas amostras provêm — XSS por mutação, confusão de namespace, DOM clobbering, breakouts de rawtext e mais — consulte [Attack Classes & Bypass History](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).

## O que é suportado?

O DOMPurify atualmente suporta HTML5, SVG e MathML. Por padrão, o DOMPurify permite CSS e atributos de dados personalizados do HTML. O DOMPurify também suporta o Shadow DOM — e sanitiza modelos DOM recursivamente. O DOMPurify também permite que você sanitize HTML para uso com as APIs `$()` e `elm.html()` do jQuery, sem nenhum problema conhecido. Para o conjunto exato de elementos e atributos permitidos por padrão, consulte a página da wiki [Default TAGs & ATTRIBUTEs allow-list & blocklist](https://github.com/cure53/DOMPurify/wiki/Default-TAGs-ATTRIBUTEs-allow-list-&-blocklist).

## E quanto a navegadores legados, como o Internet Explorer?

O DOMPurify não faz absolutamente nada. Ele simplesmente retorna exatamente a string que você forneceu. O DOMPurify expõe uma propriedade chamada `isSupported`, que informa se ele será capaz de realizar seu trabalho, para que você possa criar seu próprio plano de contingência.

## E quanto ao DOMPurify e Trusted Types?

Na versão 1.0.9, o suporte para a [Trusted Types API](https://github.com/w3c/webappsec-trusted-types) ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API)) foi adicionado ao DOMPurify.
Na versão 2.0.0, um sinalizador de configuração foi adicionado para controlar o comportamento do DOMPurify em relação a isso.

Quando `DOMPurify.sanitize` é usado em um ambiente onde a Trusted Types API está disponível e `RETURN_TRUSTED_TYPE` está definido como `true`, ele tenta retornar um valor `TrustedHTML` em vez de uma string (o comportamento para as opções de configuração `RETURN_DOM` e `RETURN_DOM_FRAGMENT` não muda).

Observe que, para criar uma política em `trustedTypes` usando o DOMPurify, `RETURN_TRUSTED_TYPE: false` é necessário, pois `createHTML` espera uma string normal, não `TrustedHTML`. O exemplo abaixo mostra isso.```js
window.trustedTypes.createPolicy('default', {
  createHTML: (to_escape) =>
    DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: false }),
});
```
Quando nenhuma `TRUSTED_TYPES_POLICY` é fornecida, o DOMPurify tenta criar sua própria política interna de Trusted Types chamada `dompurify`. Se a sua página já define sua própria política juntamente com uma CSP estrita (por exemplo, `trusted-types my-organization`) que não permite uma política chamada `dompurify`, essa tentativa é bloqueada pelo navegador e registra um aviso `TrustedTypes policy dompurify could not be created.` junto com uma violação de CSP.

Para impedir que o DOMPurify crie sua política de fallback interna, passe `TRUSTED_TYPES_POLICY: null`. Essa é a escolha certa quando você chama `DOMPurify.sanitize` de dentro do `createHTML` da sua própria política, e significa que você não precisa adicionar `dompurify` à lista de permissões `trusted-types` da sua CSP.```js
window.trustedTypes.createPolicy('my-organization', {
  createHTML: (input) =>
    DOMPurify.sanitize(input, { TRUSTED_TYPES_POLICY: null }),
});
```
Não **passe** a sua própria política de wrapping de volta ao DOMPurify como sua `TRUSTED_TYPES_POLICY` (por exemplo, via `DOMPurify.setConfig({ TRUSTED_TYPES_POLICY: myPolicy })`) quando o `createHTML` dessa política já chama `DOMPurify.sanitize`. Isso é circular por definição — a sanitização chamaria a política, que sanitiza ao chamar o DOMPurify novamente — e o DOMPurify lançará um `TypeError` descritivo para evitar a recursão infinita. A sua própria política deve chamar o DOMPurify; o DOMPurify não deve ser configurado para chamar a sua política.

Se você quiser que esse padrão de política `default` seja aplicado automaticamente em uma página inteira — de modo que todo sink de HTML seja sanitizado, incluindo código legado, widgets de terceiros e os milhares de atribuições de `innerHTML` que você não consegue encontrar ou reescrever facilmente — dê uma olhada no [DOMFortify](https://github.com/cure53/DOMFortify). Ele instala exatamente uma política `default` do Trusted Types respaldada pelo DOMPurify e recusa sinks de script (`eval`, `script.src`, ...) de imediato. É deliberadamente um projeto separado: o DOMPurify permanece um sanitizador focado, e o DOMFortify lida com a camada de aplicação em todo o documento, que está intencionalmente fora do escopo do DOMPurify.

## Posso configurar o DOMPurify?

Sim. Os valores de configuração padrão incluídos já são bastante bons — mas você pode, é claro, substituí-los. Confira a pasta [`/demos`](https://github.com/cure53/DOMPurify/tree/main/demos) para ver vários exemplos de como você pode [personalizar o DOMPurify](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this).

Antes de ampliar a lista de permissões (`ADD_TAGS`, `ADD_ATTR`, `CUSTOM_ELEMENT_HANDLING`, …) ou relaxar um padrão, vale a pena revisar as [tags e atributos para pensar duas vezes](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model#dangerous-tags-and-attributes-think-twice-before-allow-listing) — alguns são perigosos de maneiras não óbvias.

### Configurações gerais```js
// strip {{ ... }}, ${ ... } and <% ... %> to make output safe for template systems
// be careful please, this mode is not recommended for production usage.
// allowing template parsing in user-controlled HTML is not advised at all.
// only use this mode if there is really no alternative.
const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_TEMPLATES: true });

// change how e.g. comments containing risky HTML characters are treated.
// be very careful, this setting should only be set to `false` if you really only handle
// HTML and nothing else, no SVG, MathML or the like.
// Otherwise, changing from `true` to `false` will lead to XSS in this or some other way.
const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_XML: false });
```
### Controlar as nossas listas de permissões e listas de bloqueio```js
// allow only <b> elements, very strict
const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['b'] });

// allow only <b> and <q> with style attributes
const clean = DOMPurify.sanitize(dirty, {
  ALLOWED_TAGS: ['b', 'q'],
  ALLOWED_ATTR: ['style'],
});

// allow all safe HTML elements but neither SVG nor MathML
// note that the USE_PROFILES setting will override the ALLOWED_TAGS setting
// so don't use them together
const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });

// allow all safe SVG elements and SVG Filters, no HTML or MathML
const clean = DOMPurify.sanitize(dirty, {
  USE_PROFILES: { svg: true, svgFilters: true },
});

// allow all safe MathML elements and SVG, but no SVG Filters
const clean = DOMPurify.sanitize(dirty, {
  USE_PROFILES: { mathMl: true, svg: true },
});

// change the default namespace from HTML to something different
const clean = DOMPurify.sanitize(dirty, {
  NAMESPACE: 'http://www.w3.org/2000/svg',
});

// leave all safe HTML as it is and add <style> elements to block-list
const clean = DOMPurify.sanitize(dirty, { FORBID_TAGS: ['style'] });

// leave all safe HTML as it is and add style attributes to block-list
const clean = DOMPurify.sanitize(dirty, { FORBID_ATTR: ['style'] });

// extend the existing array of allowed tags and add <my-tag> to allow-list
const clean = DOMPurify.sanitize(dirty, { ADD_TAGS: ['my-tag'] });

// extend the existing array of allowed attributes and add my-attr to allow-list
const clean = DOMPurify.sanitize(dirty, { ADD_ATTR: ['my-attr'] });

// use functions to control which additional tags and attributes are allowed
const allowlist = {
  one: ['attribute-one'],
  two: ['attribute-two'],
};
const clean = DOMPurify.sanitize(
  '<one attribute-one="1" attribute-two="2"></one><two attribute-one="1" attribute-two="2"></two>',
  {
    ADD_TAGS: (tagName) => {
      return Object.keys(allowlist).includes(tagName);
    },
    ADD_ATTR: (attributeName, tagName) => {
      return allowlist[tagName]?.includes(attributeName) || false;
    },
  }
); // <one attribute-one="1"></one><two attribute-two="2"></two>

// prohibit ARIA attributes, leave other safe HTML as is (default is true)
const clean = DOMPurify.sanitize(dirty, { ALLOW_ARIA_ATTR: false });

// prohibit HTML5 data attributes, leave other safe HTML as is (default is true)
const clean = DOMPurify.sanitize(dirty, { ALLOW_DATA_ATTR: false });
```
### Comportamento de controlo relativo a Elementos Personalizados```js
// DOMPurify allows to define rules for Custom Elements. When using the CUSTOM_ELEMENT_HANDLING
// literal, it is possible to define exactly what elements you wish to allow (by default, none are allowed).
//
// The same goes for their attributes. By default, the built-in or configured allow.list is used.
//
// You can use a RegExp literal to specify what is allowed or a predicate, examples for both can be seen below.
// When using a predicate function for attributeNameCheck, it can optionally receive the tagName as a second parameter
// for more granular control over which attributes are allowed for specific elements.
// The default values are very restrictive to prevent accidental XSS bypasses. Handle with great care!

const clean = DOMPurify.sanitize(
  '<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
  {
    CUSTOM_ELEMENT_HANDLING: {
      tagNameCheck: null, // no custom elements are allowed
      attributeNameCheck: null, // default / standard attribute allow-list is used
      allowCustomizedBuiltInElements: false, // no customized built-ins allowed
    },
  }
); // <div is=""></div>

const clean = DOMPurify.sanitize(
  '<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
  {
    CUSTOM_ELEMENT_HANDLING: {
      tagNameCheck: /^foo-/, // allow all tags starting with "foo-"
      attributeNameCheck: /baz/, // allow all attributes containing "baz"
      allowCustomizedBuiltInElements: true, // customized built-ins are allowed
    },
  }
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>

const clean = DOMPurify.sanitize(
  '<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
  {
    CUSTOM_ELEMENT_HANDLING: {
      tagNameCheck: (tagName) => tagName.match(/^foo-/), // allow all tags starting with "foo-"
      attributeNameCheck: (attr) => attr.match(/baz/), // allow all containing "baz"
      allowCustomizedBuiltInElements: true, // allow customized built-ins
    },
  }
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>

// Example with attributeNameCheck receiving tagName as a second parameter
const clean = DOMPurify.sanitize(
  '<element-one attribute-one="1" attribute-two="2"></element-one><element-two attribute-one="1" attribute-two="2"></element-two>',
  {
    CUSTOM_ELEMENT_HANDLING: {
      tagNameCheck: (tagName) => tagName.match(/^element-(one|two)$/),
      attributeNameCheck: (attr, tagName) => {
        if (tagName === 'element-one') {
          return ['attribute-one'].includes(attr);
        } else if (tagName === 'element-two') {
          return ['attribute-two'].includes(attr);
        } else {
          return false;
        }
      },
      allowCustomizedBuiltInElements: false,
    },
  }
); // <element-one attribute-one="1"></element-one><element-two attribute-two="2"></element-two>
```
### Controlo do comportamento relativo a valores de URI```js
// extend the existing array of elements that can use Data URIs
const clean = DOMPurify.sanitize(dirty, { ADD_DATA_URI_TAGS: ['a', 'area'] });

// extend the existing array of elements that are safe for URI-like values (be careful, XSS risk)
const clean = DOMPurify.sanitize(dirty, { ADD_URI_SAFE_ATTR: ['my-attr'] });
```
### Controlar os valores de atributo permitidos```js
// allow external protocol handlers in URL attributes (default is false, be careful, XSS risk)
// by default only http, https, ftp, ftps, tel, mailto, callto, sms, cid, xmpp and matrix are allowed.
const clean = DOMPurify.sanitize(dirty, { ALLOW_UNKNOWN_PROTOCOLS: true });

// allow specific protocol handlers in URL attributes via regex (default is false, be careful, XSS risk)
// by default only (protocol-)relative URLs, http, https, ftp, ftps, tel, mailto, callto, sms, cid, xmpp and matrix are allowed.
// Default RegExp: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
const clean = DOMPurify.sanitize(dirty, {
  ALLOWED_URI_REGEXP:
    /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
});
```
### Influenciar o tipo de retorno```js
// return a DOM HTMLBodyElement instead of an HTML string (default is false)
const clean = DOMPurify.sanitize(dirty, { RETURN_DOM: true });

// return a DOM DocumentFragment instead of an HTML string (default is false)
const clean = DOMPurify.sanitize(dirty, { RETURN_DOM_FRAGMENT: true });

// use the RETURN_TRUSTED_TYPE flag to turn on Trusted Types support if available
const clean = DOMPurify.sanitize(dirty, { RETURN_TRUSTED_TYPE: true }); // will return a TrustedHTML object instead of a string if possible

// use a provided Trusted Types policy
const clean = DOMPurify.sanitize(dirty, {
  // supplied policy must define createHTML and createScriptURL
  TRUSTED_TYPES_POLICY: trustedTypes.createPolicy('dompurify', {
    createHTML(s) {
      return s;
    },
    createScriptURL(s) {
      return s;
    },
  }),
});

// opt out of DOMPurify's internal `dompurify` Trusted Types policy entirely
// (useful when your CSP `trusted-types` allowlist does not include `dompurify`)
const clean = DOMPurify.sanitize(dirty, { TRUSTED_TYPES_POLICY: null });
```
### Influencie como fazemos a sanitização```js
// return entire document including <html> tags (default is false)
const clean = DOMPurify.sanitize(dirty, { WHOLE_DOCUMENT: true });

// disable DOM Clobbering protection on output (default is true, handle with care, minor XSS risks here)
const clean = DOMPurify.sanitize(dirty, { SANITIZE_DOM: false });

// enforce strict DOM Clobbering protection via namespace isolation (default is false)
// when enabled, isolates the namespace of named properties (i.e., `id` and `name` attributes)
// from JS variables by prefixing them with the string `user-content-`
const clean = DOMPurify.sanitize(dirty, { SANITIZE_NAMED_PROPS: true });

// keep an element's content when the element is removed (default is true)
const clean = DOMPurify.sanitize(dirty, { KEEP_CONTENT: false });

// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases (default is false)
const clean = DOMPurify.sanitize(dirty, { FORCE_BODY: true });

// remove all <a> elements under <p> elements that are removed
const clean = DOMPurify.sanitize(dirty, {
  FORBID_CONTENTS: ['a'],
  FORBID_TAGS: ['p'],
});

// extend the default FORBID_CONTENTS list to also remove <a> elements under <p> elements
const clean = DOMPurify.sanitize(dirty, {
  ADD_FORBID_CONTENTS: ['a'],
  FORBID_TAGS: ['p'],
});

// change the parser type so sanitized data is treated as XML and not as HTML, which is the default
const clean = DOMPurify.sanitize(dirty, {
  PARSER_MEDIA_TYPE: 'application/xhtml+xml',
});
```
### Influência onde sanitizamos```js
// use the IN_PLACE mode to sanitize a node "in place", which is much faster depending on how you use DOMPurify
const dirty = document.createElement('a');
dirty.setAttribute('href', 'javascript:alert(1)');

const clean = DOMPurify.sanitize(dirty, { IN_PLACE: true }); // see https://github.com/cure53/DOMPurify/issues/288 for more info
```
Existem [mais exemplos aqui](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this), mostrando como você pode executar, personalizar e configurar o DOMPurify para atender às suas necessidades.

## Configuração Persistente

Em vez de passar repetidamente a mesma configuração para `DOMPurify.sanitize`, você pode usar o método `DOMPurify.setConfig`. Sua configuração persistirá até a sua próxima chamada a `DOMPurify.setConfig`, ou até você invocar `DOMPurify.clearConfig` para redefini-la. Lembre-se de que existe apenas uma configuração ativa, o que significa que, uma vez definida, todos os parâmetros de configuração extras passados para `DOMPurify.sanitize` são ignorados.

## Hooks

O DOMPurify permite que você aumente sua funcionalidade anexando uma ou mais funções com o método `DOMPurify.addHook` a um dos seguintes hooks:

- `beforeSanitizeElements`
- `uponSanitizeElement` (Sem 's' - chamado para cada elemento)
- `afterSanitizeElements`
- `beforeSanitizeAttributes`
- `uponSanitizeAttribute`
- `afterSanitizeAttributes`
- `beforeSanitizeShadowDOM`
- `uponSanitizeShadowNode`
- `afterSanitizeShadowDOM`

Ele passa o nó DOM atualmente processado, quando necessário um literal com dados verificados de nó e atributo, e a configuração do DOMPurify para o callback. Confira a [demonstração do hook MentalJS](https://github.com/cure53/DOMPurify/blob/main/demos/hooks-mentaljs-demo.html) para ver como a API pode ser usada de forma adequada.

_Exemplo_:```js
DOMPurify.addHook(
  'uponSanitizeAttribute',
  function (currentNode, hookEvent, config) {
    // Do something with the current node
    // You can also mutate hookEvent for current node (i.e. set hookEvent.forceKeepAttr = true)
    // For other than 'uponSanitizeAttribute' hook types hookEvent equals to null
  }
);
```
### Uma nota sobre chamar `sanitize()` a partir de um hook

**`DOMPurify.sanitize()` não é reentrante.** Por favor, não o chame de dentro de um hook, nem de um callback de configuração como `CUSTOM_ELEMENT_HANDLING.tagNameCheck` ou `attributeNameCheck`. Esses callbacks são executados no _meio_ de uma passagem ativa do sanitizador.

Uma chamada aninhada a `sanitize()` relê a configuração que lhe foi passada e, ao fazê-lo, **substitui a configuração que a passagem externa ainda está a usar**. O resto do documento externo é então sanitizado contra a configuração da chamada aninhada, em vez da sua. Como a chamada aninhada normalmente é executada com a configuração padrão, uma lista de permissões estrita de `ALLOWED_TAGS` pode, silenciosamente, voltar a alargar-se para a padrão a meio de um documento, sem erro e sem aviso.

Se precisar de sanitizar marcação aninhada, por exemplo um fragmento HTML transportado dentro de um valor de atributo, tem duas opções seguras. Ou define a sua configuração uma vez com [`DOMPurify.setConfig`](#persistent-configuration) em vez de a passar por chamada, uma vez que uma configuração persistente é partilhada pela chamada aninhada e permanece em vigor durante toda a passagem; ou recolhe os fragmentos durante o hook e sanitiza-os com uma chamada separada a `sanitize()` _depois_ de a chamada externa ter retornado.

## Configuração Removida

| Opção           | Desde | Nota                     |
| --------------- | ----- | ------------------------ |
| SAFE_FOR_JQUERY | 2.1.0 | Não é necessária substituição. |

## Integração Contínua

Atualmente usamos GitHub Actions em combinação com Playwright. Isto permite-nos confirmar em cada commit que tudo funciona nos navegadores modernos relevantes, e um fluxo de trabalho separado, agendado e em merge, reexecuta a suíte em snapshots de motores mais antigos, para que quebras em navegadores desatualizados também sejam detetadas. Consulte os registos de build aqui: https://github.com/cure53/DOMPurify/actions

Pode ainda executar testes locais com `npm run test`.

Todos os commits relevantes serão assinados com a chave `0x24BB6BF4` para segurança adicional (desde 8 de abril de 2016).

### Desenvolvimento e contribuição

#### Instalação (`npm i`)

Suportamos oficialmente o `npm`. O fluxo de trabalho do GitHub Actions está configurado para instalar dependências com `npm`. Ao usar uma versão descontinuada do `npm`, não podemos garantir totalmente as versões das dependências instaladas, o que pode levar a problemas imprevistos.

#### Scripts

Usamos ESLint via `xo` como parte do nosso fluxo de trabalho de pré-commit para ajudar a garantir a consistência do código. Além disso, usamos [Prettier](https://github.com/prettier/prettier) para formatação de código-fonte e Markdown, e os ativos de `/dist` são construídos com `rollup`.

Estes são os nossos scripts npm:

- `npm run dev` para construir o bundle UMD não minificado enquanto observa as fontes para alterações
- `npm run test` para fazer lint das fontes, executar testes via jsdom e executar testes de navegador em Chromium via Playwright
  - `npm run test:jsdom` para executar apenas testes via jsdom
  - `npm run test:happydom` para executar a suíte via happy-dom (um ambiente não suportado; mantido como verificação de robustez, não como promessa de compatibilidade)
  - `npm run test:browser` para executar apenas testes via Playwright
  - `npm run test:browser:legacy` para executar a suíte em motores de navegador mais antigos (aponte `PW_MODULE` para uma instalação antiga fixada do Playwright; veja `.github/workflows/legacy-browsers.yml`)
  - `npm run test:ci` para executar o fluxo de teste de CI para jsdom e Playwright
  - `npm run test:fuzz` para executar um pequeno fuzzer que cobre `sanitize()` e CONFIG
- `npm run bench` para executar o micro-benchmark jsdom sobre o `dist/purify.cjs` construído (construa primeiro; `--json` e `--compare a.json b.json` suportam execuções A/B entre ramos - os resultados são direcionais, confirme afirmações voltadas ao utilizador em navegadores reais)
- `npm run coverage` para construir um bundle instrumentado, executar a suíte jsdom e escrever um relatório local de cobertura de linhas/ramos em HTML em `coverage/index.html` (apenas âmbito jsdom, não executado em CI)
  - `npm run build:cov` para apenas construir o bundle de cobertura instrumentado
- `npm run lint` para fazer lint das fontes usando ESLint via xo
- `npm run format` para formatar fontes JavaScript/TypeScript e Markdown com Prettier
  - `npm run format:js` para apenas formatar fontes JavaScript/TypeScript
  - `npm run format:md` para apenas formatar ficheiros Markdown
- `npm run build` para construir declarações de tipos e bundles de distribuição, depois corrigir e limpar os tipos gerados
  - `npm run build:types` para apenas emitir ficheiros de declaração TypeScript
  - `npm run build:rollup` para construir todos os bundles Rollup
  - `npm run build:umd` para apenas construir um bundle UMD não minificado
  - `npm run build:umd:min` para apenas construir um bundle UMD minificado
  - `npm run build:es` para apenas construir o bundle de módulo ES
  - `npm run build:cjs` para apenas construir o bundle CommonJS
  - `npm run build:fix-types` para pós-processar ficheiros de tipos gerados
  - `npm run build:cleanup` para limpar a saída temporária de tipos gerados
- `npm run verify-typescript` para executar o script de verificação TypeScript
- `npm run commit-amend-build` para executar o script auxiliar do mantenedor para alterar a saída de build

Nota: todos os scripts são executados via `npm run <script>`.

Existem mais scripts npm, mas servem principalmente para integrar com CI ou são destinados a ser "privados", por exemplo, para alterar ficheiros de distribuição de build em cada commit.

## Lista de Correio de Segurança

Mantemos uma lista de correio que notifica sempre que uma versão **crítica de segurança** do DOMPurify é publicada. Isto significa que, se alguém encontrar um bypass e o corrigirmos com uma versão (o que acontece sempre que um bypass é encontrado), um e-mail será enviado para essa lista. Isto normalmente acontece dentro de minutos ou algumas horas após saber do bypass. A lista pode ser subscrita aqui:

[https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security](https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security)

Versões de funcionalidades não serão anunciadas nesta lista.

## Quem contribuiu?

Muitas pessoas ajudaram o DOMPurify a tornar-se o que é hoje, e merecem ser reconhecidas!

[offset](https://github.com/offset), [Bankde](https://github.com/Bankde), [lukewarlow](https://github.com/lukewarlow), [DEMON1A](https://github.com/DEMON1A), [fg0x0](https://github.com/fg0x0), [kodareef5](https://github.com/kodareef5), [DavidOliver](https://github.com/DavidOliver), [1Jesper1](https://github.com/1Jesper1), [bencalif](https://github.com/bencalif), [trace37labs](https://github.com/trace37labs), [eddieran](https://github.com/eddieran), [christos-eth](https://github.com/christos-eth), [researchatfluidattacks](https://github.com/researchatfluidattacks), [frevadiscor](https://github.com/frevadiscor), [Rotzbua](https://github.com/Rotzbua), [binhpv](https://github.com/binhpv), [MariusRumpf](https://github.com/MariusRumpf), [prasadrajandran](https://github.com/prasadrajandran), [Cybozu 💛💸](https://github.com/cybozu), [hata6502 💸](https://github.com/hata6502), [openclaw 💸](https://github.com/openclaw), [intra-mart-dh 💸](https://github.com/intra-mart-dh), [nelstrom ❤️](https://github.com/nelstrom), [hash_kitten ❤️](https://twitter.com/hash_kitten), [kevin_mizu ❤️](https://twitter.com/kevin_mizu), [icesfont ❤️](https://github.com/icesfont), [reduckted ❤️](https://github.com/reduckted), [dcramer 💸](https://github.com/dcramer), [JGraph 💸](https://github.com/jgraph), [baekilda 💸](https://github.com/baekilda), [Healthchecks 💸](https://github.com/healthchecks), [Sentry 💸](https://github.com/getsentry), [jarrodldavis 💸](https://github.com/jarrodldavis), [CynegeticIO](https://github.com/CynegeticIO), [ssi02014 ❤️](https://github.com/ssi02014), [GrantGryczan](https://github.com/GrantGryczan), [Lowdefy](https://twitter.com/lowdefy), [granlem](https://twitter.com/MaximeVeit), [oreoshake](https://github.com/oreoshake), [tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [is2ei](https://github.com/is2ei), [SoheilKhodayari](https://github.com/SoheilKhodayari), [franktopel](https://github.com/franktopel), [NateScarlet](https://github.com/NateScarlet), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb ❤️](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro), [@CmdEngineer\_](https://twitter.com/CmdEngineer_), [@avr4mit](https://twitter.com/avr4mit), [davecardwell](https://github.com/davecardwell), [Develop-KIM](https://github.com/Develop-KIM), [asamuzaK](https://github.com/asamuzaK), [fishjojo1 ❤️](https://github.com/fishjojo1), [Rikuxx0](https://github.com/Rikuxx0), [donmccurdy](https://github.com/donmccurdy), [hhk-png](https://github.com/hhk-png), [elrion018](https://github.com/elrion018), [michalnieruchalski-tiugo](https://github.com/michalnieruchalski-tiugo), [reey](https://github.com/reey), [KanhaKanhaiya](https://github.com/KanhaKanhaiya), [odaysec](https://github.com/odaysec), [Akokonunes](https://github.com/Akokonunes), [alirezarouhbakhsh](https://github.com/alirezarouhbakhsh), [Jaybhade](https://github.com/Jaybhade) e especialmente [@securitymb ❤️](https://twitter.com/securitymb) & [@masatokinugawa ❤️](https://twitter.com/masatokinugawa)

Categorias