Skip to main content
Blog
Blog

Como prevenir a injeção de JavaScript: guia prático passo a passo

Guia prático para prevenir a injeção de JavaScript: feche a classe XSS, controle scripts de terceiros com CSP e SRI, e inspecione sessões reais.

Aug 21, 2026 Atualizado Aug 22, 2026 11 min read
Como prevenir a injeção de JavaScript: guia prático passo a passo
Índice

Prevenir a injeção de JavaScript não é uma única tarefa. É fechar várias portas distintas que levam todas à mesma sala: código controlado por um atacante rodando nos navegadores dos seus visitantes com todos os privilégios da sua própria página. Algumas dessas portas são bugs no seu código. A maioria são scripts que você carregou deliberadamente e que depois se tornaram hostis. Este guia percorre os controles que realmente reduzem o risco, na ordem que oferece mais proteção com o menor esforço, e é honesto sobre onde cada controle para.

Se você quer primeiro o contexto, o que é a injeção de JavaScript cobre o mecanismo e todos os caminhos pelos quais o código estranho entra numa página. Este artigo é a continuação prática: o que fazer a respeito.

Como prevenir a injeção de JavaScript, em resumo

  • Feche a classe XSS no seu próprio código. Codifique na saída, use sinks do DOM seguros, sanitize o HTML não confiável e ative Trusted Types.
  • Restrinja de onde o script pode vir. Uma Content Security Policy rigorosa baseada em nonce bloqueia as origens de script não autorizadas.
  • Fixe o que puder. Subresource Integrity congela as dependências estáticas de terceiros num hash conhecido.
  • Reduza a árvore de dependências. Cada script de terceiros que você remove é um caminho de injeção a menos.
  • Monitore o tempo de execução. Vigie cada script que roda em sessões reais do navegador, porque a prevenção não consegue alcançar o comprometimento de um fornecedor de confiança.

Os caminhos de injeção contra os quais você se defende

A prevenção só faz sentido quando você sabe o que está prevenindo. O JavaScript é injetado por quatro caminhos amplos, e cada um pede um controle diferente:

Caminho de injeçãoComo aconteceO controle que ajuda
Cross-site scripting (XSS)Uma falha no seu código permite que a entrada do atacante rode como scriptCodificação de saída, sinks seguros, sanitização, Trusted Types
Script de terceiros comprometidoUm fornecedor cuja tag você carrega distribui código maliciosoRevisão de dependências, CSP, Subresource Integrity, monitoramento em execução
Magecart / skimmersAtacantes plantam código de roubo de cartões em páginas de pagamento, muitas vezes via uma dependência comprometidaMonitoramento da carga em execução no checkout, controles PCI DSS
Extensões maliciosas / malware do clienteO código é injetado na própria máquina do visitante, em cada site que ele visitaDetecção em execução; você não pode corrigir o navegador do visitante

O primeiro caminho é uma falha de código que é sua e você pode corrigir. O resto são falhas de confiança: o código foi convidado, ou vive numa máquina que você não controla. Essa distinção importa, porque explica por que corrigir o seu próprio código é necessário mas nunca suficiente.

Passo 1: Feche a classe XSS no seu próprio código

O cross-site scripting é o único caminho de injeção inteiramente sob o seu controle, então comece por aqui. O XSS acontece quando um dado fornecido por um usuário é escrito na página num lugar onde o navegador o tratará como código em vez de texto. As correções são bem compreendidas:

  • Codifique na saída, não só na entrada. A mesma string é segura num contexto e perigosa noutro, então codifique os dados para o contexto exato onde eles chegam: corpo HTML, atributo HTML, JavaScript, URL ou CSS. A codificação de saída consciente do contexto é o controle anti-XSS mais eficaz.
  • Use sinks do DOM seguros. Atribua dados não confiáveis com textContent em vez de innerHTML, e evite eval, document.write e setAttribute em manipuladores de eventos. Esses "sinks" são onde as strings injetadas se tornam executáveis.
  • Sanitize o HTML que você precisa renderizar. Quando você realmente precisar renderizar HTML fornecido pelo usuário (um comentário em texto rico, por exemplo), passe-o por um sanitizador mantido que remove o script e os manipuladores de eventos, em vez de escrever o seu próprio filtro.
  • Ative Trusted Types. Trusted Types fazem os sinks perigosos do DOM recusarem strings simples no nível do navegador, de modo que uma carga injetada não consegue alcançá-los mesmo que um bug escape à revisão de código. São aplicados por uma diretiva de CSP, o que leva diretamente ao próximo passo.

Corrigir a classe XSS remove a porta que um atacante abre explorando o seu código. Não faz nada quanto às portas que você mesmo abriu ao carregar o script de outra pessoa, que é de onde vem a maioria das violações modernas do lado do cliente.

Passo 2: Restrinja as origens com uma Content Security Policy

Uma Content Security Policy diz ao navegador quais origens estão autorizadas a carregar e executar script na sua página. Uma CSP rigorosa baseada em nonce é um dos controles individuais mais fortes que você pode implantar contra a injeção: o script que não vem de uma origem permitida, e que não carrega o nonce correto por requisição, simplesmente não roda. Os blocos <script> embutidos que um atacante injeta por meio de um furo XSS são bloqueados por padrão.

Duas observações práticas. Primeiro, prefira nonces a listas de hosts permitidos sempre que puder; uma lista script-src ampla reabre em silêncio caminhos que você pretendia fechar. Segundo, e este é o limite importante: a CSP autoriza origens, não julga o comportamento. Assim que você autoriza o domínio de um fornecedor para que o script legítimo dele rode, a CSP não tem como saber se esse script está se comportando ou roubando dados do seu formulário. Se o fornecedor for comprometido na origem, o domínio dele continua na sua lista de permissões e a versão maliciosa carrega sem problemas. A CSP é necessária. Não é a resposta completa.

Passo 3: Fixe as dependências estáticas com Subresource Integrity

Subresource Integrity (SRI) permite anexar um hash criptográfico a uma tag <script> ou <link>. O navegador calcula o hash do arquivo que baixou e se recusa a executá-lo se o hash não corresponder, o que significa que um arquivo estático de terceiros não pode ser trocado por uma versão adulterada sem que a mudança seja bloqueada.

O SRI é excelente para dependências que não mudam: uma versão específica de uma biblioteca fixada no seu hash exato. Seu limite é o espelho dessa força. Não faz nada pelos scripts destinados a se atualizar (a maioria das análises, gerenciadores de tags e SDKs de pagamento muda o arquivo servido com regularidade), e não faz nada pelos scripts carregados dinamicamente por outros scripts. Use SRI em todo lugar onde puder fixar uma versão. Não espere que ele cubra as partes da sua pilha que se atualizam sozinhas.

Passo 4: Reduza e revise a árvore de dependências

Cada script de terceiros na sua página é um caminho de injeção com todos os privilégios da página. A prevenção mais barata disponível é ter menos deles.

  • Inventarie o que você realmente carrega. A maioria das equipes se surpreende com quantos scripts rodam numa página típica, e com quantos são carregados não diretamente, mas por outro script (um gerenciador de tags carregando um fornecedor que carrega outro fornecedor).
  • Remova o que você não precisa. Um pixel de marketing sem uso ou uma ferramenta de teste A/B abandonada é puro risco sem benefício. Apagá-lo elimina um caminho de injeção por completo.
  • Minimize o raio de impacto do gerenciador de tags. Uma conta de gerenciador de tags comprometida pode injetar "só mais uma tag" que parece rotineira. Restrinja quem pode publicar e revise o que publicam.

Este passo não tem desvantagem e nenhum controle por script pode substituí-lo: um script que não está na página não pode ser o que é comprometido.

Passo 5: Monitore o tempo de execução com inspeção da carga em sessões reais

Os passos de um a quatro reduzem a probabilidade. Nenhum deles consegue alcançar o caso que causa as piores violações do lado do cliente: um script em que você confia legitimamente, de uma origem que você permitiu legitimamente, que se torna malicioso depois de já estar carregado. A CSP o deixa passar porque a origem está permitida. O SRI o perde porque o script foi projetado para se atualizar. O seu próprio código está limpo. O único lugar que resta para pegá-lo é onde a injeção de fato chega, o navegador, no momento em que o script roda.

É isso que o monitoramento em tempo de execução faz. Ele constrói um inventário de cada script que roda em sessões reais de usuários, registra o que cada um faz e para onde envia dados, e alerta quando um script novo aparece, o código de um script conhecido muda, ou os dados começam a fluir para um destino inesperado. Esta é a camada que pega os skimmers do tipo Magecart e os ataques de fornecedores comprometidos que todos os controles preventivos acima deixam passar.

As ferramentas do lado do servidor não conseguem fornecer isso. Um firewall de aplicações web ou uma varredura do servidor vê o HTML que você entregou, não a carga que um fornecedor comprometido troca depois nem o código que uma extensão injeta na máquina do visitante. A detecção precisa ocorrer na camada do navegador, em sessões reais.

Onde a cside se encaixa: monitoramento de scripts em sessões reais

A cside é um único script JavaScript próprio (first-party) que fornece a camada de tempo de execução desta lista de verificação. Ela não substitui a sua CSP, a sua codificação de saída nem os seus hashes de SRI; é o controle que vigia o que os seus scripts permitidos realmente fazem uma vez que estão rodando, algo que nenhum dos outros consegue ver.

O monitoramento de scripts da cside inventaria cada script que roda em sessões reais do navegador, analisa a carga completa do script e alerta sobre domínios novos, código alterado e fluxos de dados inesperados. Funciona em dois modelos operacionais: o Script Method busca e analisa os scripts de terceiros do lado da cside antes que eles rodem na sessão, e o Scan Method para equipes que preferem uma pegada mais leve. É implantado como uma única tag de script a partir da sua própria origem, sem mudança de DNS; a cside busca e analisa os scripts de terceiros que a sua página carrega, mas não fica à frente do tráfego do seu site e não atua como um proxy.

Nas páginas de pagamento, esse inventário em tempo de execução também é um requisito de conformidade. Os requisitos 6.4.3 e 11.6.1 do PCI DSS 4.0.1 existem justamente porque o script injetado na página de pagamento é invisível para todos os controles do lado do servidor: 6.4.3 pede que você gerencie e autorize cada script nas suas páginas de pagamento, e 11.6.1 pede que você detecte alterações não autorizadas nesses scripts e nos cabeçalhos da página. O monitoramento de scripts em sessões reais é a resposta direta a ambos.

Lista de verificação de prevenção

A prevenção da injeção de JavaScript é em camadas, e as camadas não se sobrepõem:

  1. Codifique a saída e use sinks do DOM seguros para fechar a classe XSS no seu próprio código.
  2. Implante uma CSP rigorosa baseada em nonce para bloquear as origens de script não autorizadas.
  3. Adicione Subresource Integrity para fixar as dependências estáticas de terceiros.
  4. Reduza e revise a árvore de dependências para que haja menos a comprometer.
  5. Monitore sessões reais do navegador para que um script de confiança que se torna hostil seja pego no momento em que age.

Acerte os quatro primeiros e você terá fechado a maioria das portas. Adicione o quinto e você poderá ver a única porta que a prevenção nunca consegue trancar por completo: o fornecedor de confiança que é comprometido depois que você o deixou entrar.

Leitura adicional

Mike Kutlu
Client-Side Security Consultant

Client-side security consultant at cside. 10+ years of experience implementing technology solutions for enterprises (previously at Oracle, Cloudflare, and Splunk). Now helping teams use client-side intelligence to catch & reduce fraud.

FAQ

Frequently Asked Questions

Não existe um único controle que feche todos os caminhos, porque são problemas diferentes. Para deter o cross-site scripting, você corrige como o seu próprio código trata a entrada e a saída: codifique na saída, use sinks do DOM seguros e ative Trusted Types. Para deter a injeção pelos scripts de terceiros que você já carrega, restrinja as origens com uma Content Security Policy, fixe as dependências estáticas com Subresource Integrity e monitore o que esses scripts realmente fazem em tempo de execução. O primeiro é uma correção de código; o resto são controles de confiança. Você precisa de ambos.

Não. Uma CSP rigorosa baseada em nonce é um dos controles individuais mais fortes que você pode implantar, porque bloqueia o script de origens que você não autorizou. Mas a CSP autoriza origens, não julga o comportamento: assim que você permite o domínio de um fornecedor, a CSP não tem como saber se o script desse fornecedor está roubando dados do seu formulário de pagamento. Se um script permitido for comprometido na origem, a CSP o deixa passar. Por isso as restrições de origem precisam ser combinadas com o monitoramento em tempo de execução do que os scripts permitidos realmente fazem.

Magecart e ataques à cadeia de suprimentos não exploram um bug no seu código; abusam de um script que você convidou. A prevenção ali consiste em reduzir e vigiar a árvore de dependências: remova os scripts de terceiros de que você não precisa, fixe os que puder com Subresource Integrity, restrinja as origens com CSP e monitore cada script que roda em sessões reais do navegador para que um domínio novo ou uma carga alterada gere um alerta. O monitoramento de scripts da cside foi feito para essa última camada.

Geralmente não, porque a injeção costuma ocorrer depois que a página sai do seu servidor, no navegador do visitante. Um firewall de aplicações web ou uma varredura do servidor vê o HTML que você entregou, não o script que um fornecedor comprometido troca uma hora depois, nem o código que a extensão de um atacante injeta na máquina do visitante. Detectar o script injetado exige visibilidade na camada do navegador: um inventário de cada script que roda em sessões reais e para onde cada um envia dados.

A injeção de JavaScript é qualquer situação em que código controlado por um atacante roda no navegador de um visitante com os mesmos privilégios dos scripts da sua própria página. Ela chega à página por várias vias: uma falha de cross-site scripting no seu próprio código, um script de terceiros que você carrega e que se torna malicioso, um skimmer de Magecart plantado em uma página de pagamento, ou uma extensão de navegador na máquina do visitante. Como o código injetado herda o acesso da sua página ao DOM, aos cookies e aos campos de formulário, ele pode ler o que os usuários digitam, redirecionar solicitações ou exfiltrar dados, e por isso a prevenção precisa tratar de todas as vias, não apenas de uma.

O cross-site scripting é um bug na sua própria aplicação: ele permite que a entrada de um atacante seja escrita na página onde o navegador a trata como código, então você o corrige mudando como o seu código trata a entrada e a saída. Um script de terceiros comprometido é diferente: é código que você carregou deliberadamente de um fornecedor e que se tornou hostil depois que você o convidou, seja porque o fornecedor sofreu uma violação ou porque o arquivo foi adulterado em trânsito. O XSS é uma falha de código que é sua; uma dependência comprometida é uma falha de confiança em algo que você não pode corrigir. Elas exigem controles diferentes, e por isso fechar o XSS nunca cobre por completo o risco de terceiros.

A codificação na saída converte os caracteres que um navegador trataria como marcação ou código em seus equivalentes de exibição inofensivos, para o contexto específico onde os dados aterrissam: corpo HTML, atributo, JavaScript, URL ou CSS. Codificar para o contexto errado deixa uma brecha, então a codificação na saída consciente do contexto é a defesa central contra o XSS. Os Trusted Types adicionam uma segunda camada no nível do navegador: fazem com que sinks perigosos do DOM, como innerHTML, recusem strings simples, de modo que uma carga injetada não pode alcançá-los mesmo que um bug passe pela revisão. Os Trusted Types são aplicados por uma diretiva da Content Security Policy, então os dois controles trabalham juntos.

O Subresource Integrity fixa um script ou uma folha de estilos a um hash criptográfico, e o navegador se recusa a executar o arquivo se o hash não corresponder, de modo que uma dependência estática não pode ser trocada por uma versão adulterada. Seu limite é o outro lado dessa força: só funciona para arquivos que nunca mudam. Scripts projetados para se atualizar (a maioria das análises, gerenciadores de tags e SDKs de pagamento altera o arquivo servido com frequência) não podem ser fixados, e o SRI não faz nada para scripts que outros scripts carregam dinamicamente em tempo de execução. Use-o em todo lugar onde puder fixar uma versão, mas não espere que ele cubra as partes que se autoatualizam da sua stack, que são justamente onde os ataques de fornecedores comprometidos costumam aterrissar.

O CSP autoriza origens e o SRI fixa arquivos estáticos, então ambos deixam passar um script em que você confia legitimamente e que se torna malicioso depois de carregado: o CSP ainda vê uma origem autorizada, e o SRI não consegue fixar um arquivo feito para se atualizar. O monitoramento em sessões reais vigia o único lugar onde essa falha aparece: o navegador, no momento em que o script roda. Ele constrói um inventário de cada script que roda em sessões reais de usuários, registra o que cada um faz e para onde envia dados, e alerta quando um novo script aparece, o código de um script conhecido muda, ou os dados fluem para um destino inesperado. Essa é a camada que pega os skimmers do tipo Magecart e os ataques de fornecedores comprometidos que os controles preventivos não conseguem ver.

O PCI DSS 4.0.1 acrescentou dois requisitos justamente porque o script injetado em uma página de pagamento é invisível para os controles do lado do servidor. O requisito 6.4.3 pede que você gerencie e autorize cada script que roda nas suas páginas de pagamento, e o 11.6.1 pede que você detecte alterações não autorizadas nesses scripts e nos cabeçalhos HTTP da página. Ambos descrevem visibilidade na camada do navegador: um inventário do que realmente roda em sessões reais e um alerta quando isso muda. O monitoramento de scripts em sessões reais é a resposta direta a ambos, e por isso as equipes com um prazo de PCI costumam aplicá-lo primeiro ao fluxo de checkout.

Sim. Uma extensão de navegador maliciosa ou com permissões em excesso roda na própria máquina do visitante e pode injetar script em cada site que ele abre, inclusive o seu, com acesso total à página renderizada. Você não pode preveni-la como corrige o seu próprio código ou blinda um fornecedor, porque a extensão vive inteiramente fora do seu controle: não há nada no seu servidor para corrigir. O que você pode fazer é detectá-la: o monitoramento em tempo de execução que observa o que roda em sessões reais pode sinalizar o script que nenhuma parte legítima da sua página carregou, o que muitas vezes é o único sinal de que uma extensão está adulterando a sessão de um visitante.

Primeiro, confirme o que você está vendo: use a visibilidade na camada do navegador para identificar o script exato, a origem de onde ele veio e para onde envia dados, para agir com base em provas e não em um palpite. Se for uma dependência de terceiros comprometida, remova ou bloqueie esse script imediatamente e revogue quaisquer credenciais que ele possa ter exposto; se for uma falha de XSS, corrija o tratamento de entrada vulnerável e conserte a codificação da saída afetada. Em páginas de pagamento, trate-o como um possível incidente de dados do titular do cartão sob o PCI DSS e siga o seu plano de resposta. Depois, feche a brecha que o permitiu (uma diretiva de CSP ausente, uma dependência sem fixação ou uma conta de gerenciador de tags com publicadores demais) e mantenha o monitoramento em sessões reais para que uma reincidência seja pega no momento em que agir.

Monitore e proteja seus scripts de terceiros

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Comece grátis ou experimente o Business com um teste de 14 dias.

Interface do painel cside mostrando monitoramento de scripts e análises de segurança
Related Articles
Agende uma demonstração

Quer ver isso em detalhe com um engenheiro?

Trinta minutos, no seu próprio site. Sem slides.

Vamos mostrar:

Quais scripts de terceiros estão rodando no seu site agora
Como você está em relação aos requisitos 6.4.3 e 11.6.1 do PCI DSS
Qual parte do seu tráfego é de bots e agentes de IA

Prefere só mandar uma pergunta?

Procurando horários livres…

Apenas humanos de verdade. A gente saberia.

Problemas para agendar? Abrir o agendador em uma nova aba

O que você está tentando resolver?

Conte em uma linha e voltamos com algo útil, não com um discurso genérico.

Costumamos ajudar com:

Ver quais scripts de terceiros rodam no seu site
Evidências para PCI DSS 6.4.3 e 11.6.1
Bots, agentes de IA e roubo de contas

Prefere agendar um horário? Escolher um horário