← Guias por stack

Replit

Segurança para a tua app Replit

O Replit dá-te editor, base de dados e alojamento no mesmo sítio, e com o Agent consegues publicar sem tocar no terminal. O risco: secrets que acabam no código, Repls públicos que expõem os teus ficheiros e serviços abertos sem headers. Analisa-a antes de partilhares o link.

Riscos típicos em Replit

Secrets no código em vez de nos Secrets

O Replit tem um gestor de Secrets, mas é fácil acabar com a chave escrita no código ou num ficheiro de configuração. Se o Repl for público ou for para produção, essa chave vaza.

Repls públicos que expõem os teus ficheiros

Um Repl público deixa qualquer pessoa ver todo o código e ficheiros do projeto, incluindo ficheiros .env esquecidos ou backups. Verifica o que está visível antes de assumires que é privado.

Serviços abertos sem headers

Um deployment do Replit expõe a tua app num URL público sem headers de segurança. Se, além disso, deixares endpoints ou portas sem proteção, ficam ao alcance de qualquer pessoa.

"Segurança no Replit" são duas coisas que convém separar. A primeira é o Repl e o seu deploy: onde vivem os segredos, quem vê os teus ficheiros, que URL é público e que porta está exposta. A segunda é o código que o Replit Agent gera, normalmente um servidor Express com React e uma base de dados Postgres, que traz as falhas clássicas de um backend escrito à pressa. Este guia cobre as duas, com um bloco para o ficheiro que o Agent lê em cada pedido, um prompt de revisão antes do deploy e as verificações de fora.

Parte 1: proteger o teu Repl e o teu deploy

Segredos: o separador Secrets, não o código

O Replit tem um gestor de segredos que guarda as variáveis cifradas e as expõe ao processo como variáveis de ambiente, sem aparecerem em nenhum ficheiro. É o único sítio correto para chaves de API, a string de ligação da base de dados e o segredo de sessão. O erro habitual é o Agent, ou tu com pressa, escrevê-las num .env, num config.json ou diretamente no código. Esses ficheiros fazem parte do Repl: veem-se num Repl público, copiam-se ao fazer fork e são publicados no deploy.

Repls públicos e o URL de desenvolvimento

Um Repl público mostra todos os seus ficheiros a qualquer pessoa, incluindo os que esqueceste: cópias de segurança, um .env antigo, exportações de dados. Antes de o tornares público, revê a árvore completa. E enquanto o Repl está a correr, o URL de desenvolvimento .replit.dev responde a quem o tiver; não é um ambiente privado, é um servidor na internet com os teus dados de teste.

Deploys

O deploy publica a app num subdomínio .replit.app ou no teu domínio, com TLS automático. As variáveis de ambiente do deploy configuram-se à parte das de desenvolvimento, por isso confirma que as de produção não apontam para a base de dados de testes. Só a porta que declaras fica exposta, mas tudo o que essa porta serve é público: rotas de API, ficheiros estáticos e o que o servidor devolver por engano. O Replit não acrescenta cabeçalhos de segurança; é o teu servidor que os põe.

Base de dados e autenticação integradas

A base de dados Postgres integrada entrega a sua string de ligação como segredo; nunca a copies para um ficheiro. Se usas Replit Auth, a sessão é gerida pelo Replit e o teu código recebe o utilizador já identificado, mas cada rota continua a ter de verificar que há sessão e que esse utilizador pode fazer o que pede.

Parte 2: as falhas que o Agent mete no teu código

  • Segredos em ficheiros. A chave da OpenAI ou a string do Postgres no .env, numa constante ou num config.json servido como estático.
  • Rotas de API sem autenticação. O painel verifica a sessão no React; /api/users responde a qualquer pessoa.
  • Pastas estáticas demasiado amplas. express.static a apontar para a raiz do projeto serve package.json, .replit, o código do servidor e qualquer ficheiro esquecido. E sem index.html, alguns servidores listam o diretório.
  • Rotas de depuração e seed. /api/debug, /api/seed, /api/reset criadas para testar e publicadas.
  • CORS aberto com credenciais. cors() sem opções mais cookies de sessão: qualquer site age em nome dos teus utilizadores.
  • Consultas SQL por concatenação. Uma string construída com o que chega do formulário em vez de parâmetros.
  • Uploads de ficheiros para disco servidos tal e qual. Qualquer utilizador carrega um ficheiro e qualquer visitante o descarrega pelo nome.
  • Sem limite de pedidos nem cabeçalhos. Um endpoint que chama um modelo pago sem teto, e nenhum cabeçalho de segurança.

Um bloco para o Agent aplicar sempre

O Replit Agent lê o ficheiro replit.md do teu projeto como contexto permanente. Acrescenta esta secção:

## Regras de segurança
- As chaves, a string da base de dados e o segredo de sessão leem-se de process.env e vivem no separador Secrets. Nunca em .env, config.json nem no código.
- Toda a rota de API que leia ou escreva dados verifica a sessão e as permissões do utilizador no servidor. As verificações no React não contam.
- express.static só serve a pasta de build do frontend ou public/, nunca a raiz do projeto.
- Sem rotas de depuração, seed ou reset em produção.
- CORS com uma lista explícita de origens; nunca o wildcard com credenciais.
- Todas as consultas SQL usam parâmetros. Toda a entrada de formulário é validada no servidor.
- Os ficheiros carregados guardam-se fora da pasta pública e só se servem depois de verificar permissões.
- Cabeçalhos de segurança com helmet e limite de pedidos nas rotas com custo.

E os cabeçalhos em Express, em duas linhas:

import helmet from 'helmet';
app.use(helmet());
app.use(helmet.hsts({ maxAge: 63072000, includeSubDomains: true, preload: true }));

Um prompt de revisão antes do deploy

Revê a segurança deste projeto e não mudes nada ainda. Responde com uma lista:
1. Chaves, strings de ligação ou segredos escritos em ficheiros ou no código, com ficheiro e linha.
2. Rotas de API que leiam ou escrevam dados sem verificar a sessão, e rotas de depuração, seed ou reset.
3. Pastas servidas como estáticas e que ficheiros expõem.
4. Configuração de CORS e de cookies de sessão.
5. Consultas SQL construídas por concatenação e entradas sem validar.
6. Onde se guardam os ficheiros carregados e como se servem.
7. Se existem cabeçalhos de segurança e limite de pedidos.
Para cada ponto, propõe a alteração exata e espera pela minha confirmação.

Verifica o resultado de fora

curl -sI https://oteudominio.com | grep -iE "strict-transport|x-frame|x-content-type|content-security"
for p in .env .replit package.json config.json .git/config server.js uploads/; do printf "%-14s " "$p"; curl -s -o /dev/null -w "%{http_code}\n" "https://oteudominio.com/$p"; done
curl -s -o /dev/null -w "%{http_code}\n" https://oteudominio.com/api/users

O esperado: cabeçalhos presentes, 404 em toda a lista de ficheiros e um 401 ou 403 na rota de API sem sessão. Um 200 em package.json ou .replit significa que estás a servir a raiz do projeto. O Scanaris faz estas verificações e cerca de quarenta mais em 30 segundos: procura ficheiros expostos e listagens de diretório, endpoints que respondam sem sessão, segredos no JavaScript, cabeçalhos, CORS, cookies e TLS, e dá-te um fix prompt por cada falha para colar no chat do Agent. E pode voltar a analisar todos os dias, porque uma regeneração pode trazer de volta uma falha que já tinhas corrigido.

Perguntas frequentes

Os segredos do separador Secrets veem-se num Repl público?

Não, os segredos não são mostrados nem copiados ao fazer fork. O que se vê é tudo o resto: ficheiros, código e qualquer chave que esteja escrita neles em vez de em Secrets.

O URL de desenvolvimento é privado?

Não. Enquanto o Repl corre, responde a qualquer pessoa que tenha o link. Não o uses com dados reais nem o partilhes a pensar que só tu o vês.

O Replit põe cabeçalhos de segurança nos deploys?

Não. Dá TLS e o domínio, mas os cabeçalhos são enviados pelo teu servidor. Com Express, o helmet acrescenta-os em duas linhas; com outras frameworks, o seu equivalente.

Verificações relacionadas

A tua app Replit passa nestas verificações?

Analisa-a grátis e recebe um fix prompt por cada problema que encontrarmos.

Analisar o meu site grátis