Objetivos de aprendizado
Depois de ler este artigo, você vai conseguir:
- Revisar os itens de segurança que valem antes de colocar bot, site ou API no ar
- Aplicar cabeçalhos de segurança e validação de entrada em uma API Express
- Verificar com comandos simples se algum segredo foi parar no Git
Nesta página
- Como manter segredos fora do código?
- Como atualizar as dependências com segurança?
- Como configurar HTTPS e cabeçalhos de segurança?
- Como validar entradas e limitar o acesso?
- O que registrar nos logs e o que nunca registrar?
- O que fazer quando um segredo vazar?
- Como verificar que deu certo e quais erros evitar?
- Como fazer isso na Square Cloud
- Perguntas frequentes
Boa parte dos incidentes em bots, sites e APIs pequenos vem de falhas básicas: um token no repositório, uma dependência velha, um endpoint sem autenticação. Não é preciso ser especialista em segurança para fechar essas portas. Basta passar por uma lista antes do deploy e repeti-la de tempos em tempos.
Este checklist cobre o que um desenvolvedor sozinho consegue fazer em uma tarde. Os exemplos usam uma versão recente do Node.js e Express 5, mas os itens valem para qualquer linguagem. Se a sua dúvida é só sobre o token do Discord, leia como proteger o token do bot.
O checklist, em ordem:
- Segredos fora do código e do Git.
- Dependências atualizadas.
- HTTPS e cabeçalhos de segurança.
- Autenticação, autorização e validação de entrada.
- Permissões mínimas para tokens, chaves e usuários do banco.
- Logs sem dados sensíveis e erros que não vazam detalhes.
- Um plano para quando um segredo vazar.
Esses itens cobrem boa parte das categorias do OWASP Top 10:2025, como controle de acesso quebrado (A01), configuração incorreta de segurança (A02), falhas na cadeia de suprimentos de software (A03) e falhas de autenticação (A07).
Como manter segredos fora do código?#
Token de bot, senha de banco, chave de API e segredo de webhook entram na aplicação por variáveis de ambiente, nunca escritos no código. Quem tem acesso ao repositório não deveria ter acesso à produção só por isso. Se o conceito é novo, veja o que são variáveis de ambiente.
Para desenvolvimento local, use um arquivo .env e coloque-o no .gitignore antes do primeiro commit:
echo ".env" >> .gitignore
git ls-files .env # não deve imprimir nada
git log --all --oneline -- .env # não deve imprimir nadaO primeiro comando confirma que o arquivo não está versionado. O segundo mostra se ele já foi commitado alguma vez, em qualquer branch. Se aparecer algum commit, o segredo está no histórico. Revogue e gere outro. O guia de segredos do OWASP deixa claro que reescrever o histórico do Git tem efeitos colaterais e não substitui a rotação.
Mais três cuidados:
- Não coloque segredos em imagens Docker com
ENVouARG. Injete na hora de executar. - Use um segredo diferente para cada ambiente (teste e produção).
- Ative o secret scanning do GitHub, que procura credenciais expostas em todo o histórico, em todas as branches, e gera um alerta. Ele roda automaticamente em repositórios públicos.
Como atualizar as dependências com segurança?#
Seu código é pequeno, mas node_modules não é. Cada pacote é código de terceiros rodando com as permissões da sua aplicação, e vulnerabilidades novas surgem sem você mexer em nada.
npm audit --omit=dev # relatório só das dependências de produção
npm audit fix # aplica as correções compatíveisO npm audit envia a lista de dependências ao registro e devolve vulnerabilidades conhecidas, saindo com código diferente de zero se achar alguma. Correções que exigem mudar a faixa de versão pedem --force, e isso pode quebrar o código, então rode seus testes depois.
Para não depender de lembrar, ative o Dependabot security updates no GitHub: ele abre pull requests com a versão corrigida mínima quando sai um alerta. Mantenha o package-lock.json no repositório para que o deploy instale exatamente as versões que você testou, e instale com npm ci.
Desconfie de pacotes com nome parecido com o de um popular e de pacotes novos com poucos downloads: é por aí que entram os ataques à cadeia de suprimentos.
Como configurar HTTPS e cabeçalhos de segurança?#
Todo tráfego que chega de fora deve usar HTTPS. Sem ele, senhas e tokens trafegam em texto puro e qualquer rede no caminho pode ler ou alterar a resposta. Numa hospedagem com certificado automático, você não emite nada à mão. Veja como funciona o SSL/TLS.
Depois do HTTPS, os cabeçalhos. O pacote helmet define vários deles de uma vez, entre eles Strict-Transport-Security, X-Content-Type-Options: nosniff, Content-Security-Policy e Referrer-Policy, e remove o X-Powered-By, que revela que você usa Express.
npm install express@5 helmetimport express from "express";
import helmet from "helmet";
const { API_TOKEN } = process.env;
if (!API_TOKEN) {
console.error("API_TOKEN ausente");
process.exit(1);
}
const app = express();
app.use(helmet());
app.use(express.json({ limit: "100kb" }));
// autenticação antes de qualquer rota privada
app.use((req, res, next) => {
const token = (req.headers.authorization ?? "").replace(/^Bearer /, "");
if (token !== API_TOKEN) return res.status(401).json({ error: "Unauthorized" });
next();
});
app.post("/items", (req, res) => {
const { name } = req.body ?? {};
if (typeof name !== "string" || name.length === 0 || name.length > 100) {
return res.status(400).json({ error: "name deve ter de 1 a 100 caracteres" });
}
res.status(201).json({ name });
});
// erro genérico: o detalhe vai para o log, não para o cliente
app.use((err, _req, res, _next) => {
console.error(err);
res.status(500).json({ error: "Internal Server Error" });
});
app.listen(Number(process.env.PORT ?? 3000));O Strict-Transport-Security só tem efeito em respostas HTTPS: o navegador lembra, pelo número de segundos em max-age, que o site só deve ser acessado por HTTPS. O padrão do Helmet é um ano com includeSubDomains. O Content-Security-Policy padrão é restritivo, então um site com scripts e imagens de outros domínios precisa ajustá-lo. Para uma API que só responde JSON, ele raramente atrapalha.
Para o restante da API (rate limit, CORS, comparação de token em tempo constante), siga o checklist de produção da API.
Como validar entradas e limitar o acesso?#
Trate tudo o que vem de fora como hostil: corpo, query string, cabeçalhos, nome de arquivo enviado e até mensagens que usuários mandam para o seu bot. Verifique tipo, tamanho e formato, e use consultas parametrizadas no banco em vez de montar SQL com texto concatenado.
Autenticar não basta: o controle de acesso quebrado lidera o OWASP Top 10:2025. Se GET /orders/42 devolve o pedido 42 para qualquer usuário autenticado, qualquer um troca o número e lê pedidos alheios. Toda rota que acessa um recurso deve checar se aquele usuário é dono dele.
Em bots, vale o mesmo para comandos: um comando que apaga mensagens ou muda configurações precisa conferir o cargo ou a permissão de quem o chamou, não só confiar que o comando está escondido.
Menor privilégio. Cada credencial deve poder fazer apenas o que o uso exige. O guia de segredos do OWASP recomenda dar a cada segredo o mínimo de privilégios e limitar as credenciais de CI/CD aos segredos que o job realmente usa.
- Bot: peça só as permissões e intents de que ele precisa, nunca "Administrador" por conveniência.
- Banco: um usuário da aplicação sem permissão de criar ou apagar tabelas, separado do usuário de migração.
- Chaves de API: uma chave por serviço, para revogar uma sem derrubar as outras.
- Pessoas: quem só lê logs não precisa de acesso para fazer deploy.
O que registrar nos logs e o que nunca registrar?#
Registre eventos que ajudam a investigar: logins que falharam, 401 e 403, erros 500 e ações administrativas. Falhas de log e alerta aparecem como categoria própria no OWASP Top 10:2025, porque sem registro você não percebe o ataque.
Nunca registre senhas, tokens, números de cartão ou o corpo inteiro da requisição. E não devolva stack trace ao cliente: ela revela caminhos, bibliotecas e versões. O exemplo acima registra o erro completo no servidor e responde só "Internal Server Error".
O que fazer quando um segredo vazar?#
Aja na ordem: revogar, trocar, investigar.
- Revogue o segredo no serviço de origem (portal do Discord, painel do banco, provedor da API). Apagar o commit não adianta.
- Gere um novo e atualize a variável de ambiente na hospedagem.
- Reinicie a aplicação para ela ler o valor novo.
- Investigue os logs do serviço atrás de uso suspeito no intervalo em que o segredo ficou exposto.
- Corrija a causa:
.gitignore, secret scanning e uma revisão de quem tinha acesso.
Como verificar que deu certo e quais erros evitar?#
Com a aplicação no ar, confira os cabeçalhos e a autenticação:
curl -sI https://seu-app.exemplo.com | grep -iE "strict-transport|x-content-type|x-powered-by"
curl -i https://seu-app.exemplo.com/items -X POST -H "Content-Type: application/json" -d '{"name":"a"}'Esperado: strict-transport-security e x-content-type-options presentes, x-powered-by ausente e a segunda chamada devolvendo 401. Rode também npm audit --omit=dev e git log --all --oneline -- .env.
Erros que mais aparecem:
- Commitar o
.env"só uma vez": o histórico guarda para sempre. - Token de bot em print ou log de erro colado em fórum ou servidor de suporte.
- CORS com
*em API autenticada. - Painel administrativo sem autenticação, achando que a URL ser desconhecida basta.
- Ignorar o aviso do
npm auditpor meses. - Mesma senha de banco em teste e produção.
Como fazer isso na Square Cloud#
A Square Cloud é hospedagem self-service: você faz o deploy e define a configuração, então o checklist continua sendo seu, mas vários itens já têm onde se apoiar.
- Segredos (item 1): variáveis de ambiente por aplicação, no painel, na API, na CLI ou no VS Code. O painel importa o seu
.envlocal, e a mudança vale no próximo restart, sem rebuild. Para deploy por GitHub Action, a única credencial é uma API key guardada como secret do repositório. - Dependências (item 2): no start, quando não há
node_modules, a plataforma rodanpm installcomNODE_ENV=production, então as devDependencies não vão para produção e onpm audit --omit=devcobre exatamente o que roda. Envie opackage-lock.jsonjunto para instalar as versões que você testou. - HTTPS (item 3): toda aplicação web recebe um subdomínio
*.squareweb.appcom HTTPS. O certificado é renovado sozinho, o HTTP redireciona para HTTPS e os cabeçalhos do Helmet, como o HSTS, passam intactos. - Rede e isolamento: todos os planos incluem WAF e proteção DDoS L3/L4/L7, e as aplicações rodam em containers isolados, sem acesso root; uma não lê variáveis nem arquivos de outra, mesmo na mesma conta. Essas camadas não substituem autenticação, validação e rate limit no seu código.
- Vazamento (item 7): troque a variável e reinicie a aplicação pelo painel, pela CLI ou pela API, acompanhando a volta pelos logs em tempo real.
Depois do deploy, rode os dois curl da seção de verificação contra o seu subdomínio squareweb.app. Veja os detalhes em rede e proteção e em variáveis de ambiente.
Infraestrutura
Mitigação de DDoS L3/L4/L7 e WAF em todos os planos
Perguntas frequentes
Qual é o erro de segurança mais comum em quem publica um bot ou API?
Deixar token, senha ou chave de API dentro do código ou do repositório. Em repositório público, qualquer pessoa pode copiá-lo, então trate o segredo como vazado e gere outro.
Apagar o arquivo .env do repositório resolve se eu já fiz commit dele?
Não. O segredo continua no histórico do Git. Revogue e gere uma credencial nova; limpar o histórico ajuda, mas não substitui a troca.
Preciso de HTTPS para um bot que só fala com o Discord ou o Telegram?
O bot em si só faz conexões de saída, que já usam TLS. HTTPS passa a ser obrigatório se ele recebe tráfego, como um webhook, um painel web ou uma API.
Com que frequência devo rodar npm audit?
A cada deploy e de forma automática no repositório, por exemplo com o Dependabot. Vulnerabilidades novas são publicadas o tempo todo, mesmo sem você mexer no código.
Mais em Segurança
Ver todos os 10 artigos- O que é ataque de força bruta e como se protegerAtaque de força bruta é testar senhas em massa até acertar uma. Veja os tipos (spraying, credential stuffing), como funcionam e as defesas com código que roda.
- Minha aplicação foi invadida: o que fazer agoraSe a sua aplicação foi invadida, contenha o acesso, troque todos os segredos e preserve os logs antes de limpar. Veja a ordem certa, a causa e como voltar.
- Chave de API exposta no GitHub: como revogar e prevenirSubiu uma chave de API para o GitHub? Revogue primeiro, depois limpe o histórico e troque o valor. Veja o passo a passo e como evitar que se repita.
- Vazou o token do bot? O que fazer agoraSe o token do bot vazou, redefina-o no Portal do Discord (ou com /token no BotFather) antes de qualquer outra coisa. Veja a ordem certa e como checar o estrago.