Na era das Single Page Applications (SPAs), segurança no Front-End é um pilar essencial, e muitas vezes subestimado. Neste artigo, você vai aprender seis práticas de segurança inegociáveis para proteger sua aplicação React — sem complicar sua arquitetura.
1. Entenda e Combata o XSS (Cross-Site Scripting)
XSS é um dos ataques mais comuns na web. Ele ocorre quando um invasor consegue injetar scripts maliciosos em sua página, geralmente por meio de inputs do usuário.
Como o React já ajuda:
React escapa o HTML automaticamente, evitando que dados dinâmicos sejam interpretados como código. Exemplo seguro:
const SafeComponent = ({ userInput }) => (
<div>{userInput}</div> // React escapa automaticamente
);
Mas cuidado com:
<div dangerouslySetInnerHTML={{ __html: userInput }} /> // perigo!
Se você realmente precisar usar dangerouslySetInnerHTML
, sempre sanitize o conteúdo antes:
Você pode usar o dompurify
import DOMPurify from 'dompurify';
const SafeHTML = ({ html }) => (
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />
);
2. Use uma Política de Segurança de Conteúdo (CSP)
CSP é uma defesa poderosa contra XSS. Ela define quais fontes de conteúdo (scripts, imagens, estilos) são permitidas no seu app.
Exemplo de cabeçalho CSP:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net
Como configurar:
Se você usa um servidor Node/Express:
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' https://cdn.jsdelivr.net"
);
next();
});
Isso impede scripts externos não autorizados de serem executados.
3. Tokens de Autenticação: Nada de LocalStorage
Armazenar tokens JWT em localStorage
ou sessionStorage
parece fácil, mas é vulnerável a ataques XSS.
Alternativa segura:
Use cookies com atributos HttpOnly
e Secure
. Eles:
- Não podem ser acessados via JavaScript.
- São enviados automaticamente com cada requisição.
No backend (Node.js com [cookie-parser](https://www.npmjs.com/package/cookie-parser)
):
res.cookie('token', jwt, {
httpOnly: true,
secure: true,
sameSite: 'Strict'
});
No React, não se preocupe em "guardar o token" — ele já será enviado nas requisições automaticamente.(coisa linda, neh?)
4. Cuidado com Variáveis de Ambiente Expostas
No React, todas as variáveis com prefixo REACT_APP_
são embutidas no bundle e visíveis no navegador.
REACT_APP_API_KEY=12345 // visível publicamente 😬
Nunca coloque chaves sensíveis (como Firebase, Stripe, APIs privadas) nesse arquivo.
Solução:
- Crie uma API intermediária no backend que insira a chave de forma segura.
- Ou limite as chaves com regras específicas (ex: domínios autorizados via CORS ou restrições geográficas).
- Ou usar o AWS Secrets Manager.
5. Use Subresource Integrity (SRI) em Recursos Externos
Se você incluir scripts ou estilos de terceiros via CDN, eles podem ser alterados sem seu conhecimento.
Exemplo inseguro:
<script src="https://cdn.com/lib.js"></script>
Com SRI:
<script src="https://cdn.com/lib.js"
integrity="sha384-abc123"
crossorigin="anonymous"></script>
Você pode gerar esse hash com ferramentas como o SRI Hash Generator
Isso garante que, se o arquivo for alterado, ele não será executado.
Bônus: Use AWS Secrets Manager para proteger chaves privadas no backend
Muitas vezes, aplicações React precisam de acesso a APIs com chaves sensíveis (como Stripe, Firebase Admin ou OpenAI). Usar arquivos .env
com variáveis expostas não é seguro. Uma alternativa poderosa é usar o AWS Secrets Manager.
Como funciona:
O Front-End React nunca acessa o Secrets Manager diretamente. Em vez disso:
- O React faz uma requisição para o seu backend (ex: API Node.js ou AWS Lambda).
- O backend acessa o Secrets Manager com credenciais seguras.
- O backend usa a chave e retorna ao Front-End apenas o necessário.
Exemplo com Node.js:
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManagerClient({ region: 'us-east-1' });
async function getStripeSecret() {
const command = new GetSecretValueCommand({ SecretId: 'stripe-api-key' });
const response = await client.send(command);
return JSON.parse(response.SecretString);
}
Vantagens:
- As chaves nunca são expostas no bundle.
- Permite rotação automática de tokens.
- Controle de acesso refinado via IAM.
Quando usar:
- Projetos com backend próprio (Node, Lambda, etc).
- Times que já usam AWS.
Conclusão
Aplicações modernas em React são rápidas, dinâmicas e… vulneráveis — se a segurança não for tratada com seriedade.
Aqui está um resumo das dicas aplicadas:
Dica | Protege contra |
---|---|
XSS + DOMPurify | Injeção de scripts maliciosos |
CSP | Execução não autorizada de scripts externos |
Cookies HttpOnly | Roubo de tokens via JS |
Evitar REACT_APP_ sensível |
Exposição de dados privados |
SRI | Scripts corrompidos ou comprometidos |
Próximo Passo
Se você curtiu este conteúdo e quer se aprofundar em boas práticas de arquitetura e segurança no Front-End, me siga aqui no Dev.to ou conecte-se comigo no LinkedIn.
Tem alguma dica extra de segurança? Compartilha nos comentários! 🔐👇
Top comments (6)
Great post, Werliton! As a cybersecurity consultant, I can’t stress enough how critical these practices are—especially avoiding token storage in localStorage and using CSP. Simple steps like these can prevent major breaches. Keep sharing!
Thank you so much!
Nice post
Thanks, bro
Show! Ok ok. I'm happy!
werlitoncarlos@gmail.com