Segurança de Erros
Regras
- Nunca vazar stack traces, erros de banco de dados ou caminhos de arquivos para clientes em produção
- Retornar mensagens de erro genéricas com um ID único de erro:
{ error: "Algo deu errado", errorId: "abc123" }
- Registrar detalhes completos do erro no lado servidor com o mesmo ID de correlação para depuração
- Usar diferentes níveis de detalhe de erro: desenvolvimento (stack trace completo) vs produção (mensagem segura + ID)
- Capturar todos os erros não tratados com manipuladores globais — nunca permita que erros brutos cheguem ao cliente
- Sanitizar mensagens de erro de serviços de terceiros antes de encaminhá-las aos clientes
- Retornar códigos de status HTTP adequados: 400 (entrada inválida), 401 (não autenticado), 403 (proibido), 404 (não encontrado), 500 (erro do servidor)
import { randomUUID } from "node:crypto";
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
const errorId = randomUUID();
console.error({ errorId, message: err.message, stack: err.stack, url: req.url });
const statusCode = (err as any).statusCode || 500;
res.status(statusCode).json({
error: statusCode >= 500 ? "Erro interno do servidor" : err.message,
errorId,
...(process.env.NODE_ENV === "development" && { stack: err.stack }),
});
});
export default function GlobalError({ error, reset }) {
return (
<div>
<h2>Algo deu errado</h2>
<p>ID do Erro: {error.digest}</p>
<button onClick={reset}>Tentar novamente</button>
</div>
);
}
Evitar
- Retornar
err.message diretamente — erros de banco de dados vazam nomes de tabelas, nomes de colunas e estrutura da consulta
- Stack traces em respostas de produção — eles revelam caminhos de arquivos, dependências e arquitetura interna
- 500 genérico para tudo — use códigos de status adequados para que os clientes possam lidar com os erros apropriadamente
- Registrar erros sem IDs de correlação — torna a depuração em produção quase impossível
- Engolir erros silenciosamente — sempre registre, mesmo que a resposta seja genérica