XSS via innerHTML e como evitá-lo
Entenda scripts entre sites e alternativas seguras a innerHTML.
XSS via innerHTML e como evitá-lo é uma aula grátis de HTML Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de HTML Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de HTML Academy inclui 4 aulas no total.
A vulnerabilidade central
Definir el.innerHTML = userInput analisa a string como HTML. Se userInput contiver tags <script> ou atributos de manipuladores de eventos (onclick, onerror), o navegador os interpreta — executando código controlado pelo invasor na página.
Por que é comum
Qualquer código que insira dados do usuário em HTML — modelos no servidor, renderização no cliente — corre risco de XSS se os dados não forem escapados. Aplicativos de página única que constroem innerHTML a partir de respostas de APIs ficam especialmente expostos quando essas respostas incluem conteúdo do usuário.
Um exemplo concreto
Um nome de usuário "Bob<img src=x onerror=alert(1)>" definido por meio de div.innerHTML = `Welcome, ${user}` executa alert(1) quando a imagem não consegue ser carregada. A mesma carga útil como texto simples (via textContent) é inofensiva — o navegador vê apenas caracteres, não tags.
// VULNERABLE
div.innerHTML = `Hi, ${user.name}`;
// SAFE
div.textContent = `Hi, ${user.name}`;Use textContent para texto simples
textContent define somente texto — os caracteres especiais de HTML aparecem como caracteres literais, nunca como tags. Essa é a ferramenta certa em 90% dos casos. Use innerHTML somente quando realmente precisar renderizar marcação, não texto.
Use métodos do DOM para estruturar
Para criar elementos com dados do usuário, construa-os com createElement e textContent: const li = document.createElement("li"); li.textContent = name; ul.appendChild(li);. O resultado é estruturalmente idêntico ao innerHTML, mas seguro contra XSS por construção.
Quando for necessário usar innerHTML
Para HTML confiável gerado pelo servidor (saída do seu próprio modelo, texto rico higienizado de um editor confiável), innerHTML é adequado. Nunca o aplique diretamente a dados de fontes não confiáveis sem sanitização.
Higienize texto rico com DOMPurify
Se os usuários enviarem texto rico (um editor de comentários, renderização de markdown), higienize-o antes de definir innerHTML: el.innerHTML = DOMPurify.sanitize(richHtml). DOMPurify remove tags e atributos perigosos, mantendo formatação segura como <b>, <em> e <a>.
insertAdjacentHTML tem o mesmo risco
el.insertAdjacentHTML("beforeend", html) analisa strings HTML — a mesma superfície de XSS que innerHTML. As mesmas regras se aplicam: nunca forneça dados do usuário diretamente; higienize-os ou use métodos do DOM. O mesmo vale para document.write, embora ninguém deva mais usá-lo.
Padrões das estruturas de trabalho
React, Vue, Svelte e Angular escapam texto interpolado por padrão — {name} é seguro. Eles oferecem mecanismos para contornar esse escape (dangerouslySetInnerHTML no React, v-html no Vue), que apresentam o mesmo risco de XSS; use-os com moderação e sanitização.
Injeção em atributos
Até os valores de atributos podem ser vetores: <a href={url}> com url="javascript:alert(1)" executa o código quando recebe um clique. Valide os endereços por esquema (permita apenas http:, https:, mailto: e tel:) antes de inserir a entrada do usuário em href, src ou outros atributos que contenham endereços.
Política Trusted Types
Os navegadores modernos oferecem suporte a Trusted Types: configure a CSP com require-trusted-types-for 'script' e innerHTML recusará strings brutas — somente valores encapsulados por uma política serão aceitos. Isso torna o XSS impossível por meio da API, e não da disciplina.
Defesa em profundidade
Nenhuma camada isolada é suficiente. Combine: validação da entrada no servidor, escape da saída durante a renderização, CSP para bloquear scripts injetados, Tipos Confiáveis para rejeitar cadeias de caracteres brutas e revisão de segurança de qualquer uso de innerHTML. A defesa em camadas continua eficaz mesmo quando há um erro em qualquer camada.
Verificação de conhecimentos
Por que el.textContent = userInput é seguro contra XSS, enquanto el.innerHTML = userInput é perigoso?
Resumo
innerHTML em entradas fornecidas pelo usuário é o vetor clássico de XSS. Use textContent para texto, createElement+textContent para estrutura e DOMPurify quando for necessário HTML avançado. Valide os esquemas de URL dos valores de atributos. Combine CSP e Tipos Confiáveis para neutralizar erros que escapem à revisão do código. As plataformas modernas fazem o escape por padrão — mantenha raros os atalhos inseguros e revise-os.
Perguntas Frequentes
A aula “XSS via innerHTML e como evitá-lo” é grátis?
Sim — o texto completo de “XSS via innerHTML e como evitá-lo” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de HTML Academy, atualize para CoddyKit PRO. O curso de HTML Academy inclui 4 aulas no total.
O que vou aprender em “XSS via innerHTML e como evitá-lo”?
Entenda scripts entre sites e alternativas seguras a innerHTML. Você pratica HTML Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar HTML Academy?
Nenhuma experiência prévia é necessária. HTML Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “XSS via innerHTML e como evitá-lo”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de HTML Academy?
Sim. Cada aula de HTML Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Política de Segurança de Conteúdo meta http-equiv
- XSS via innerHTML e como evitá-lo
- Sandbox de iframe e Política de Permissões
- HTTPS e integridade de subrecursos