Pular para o conteúdo

Seu app do Windsurf é seguro?

O Windsurf serve para um app no ar? O código gerado costuma estar bem. O que passa é a mudança que ninguém leu, num arquivo que ninguém abriu.

Vlad Tkachenko5 min de leitura
O cartão de verificação de segurança da Reeve para apps do Windsurf, com o logo do Windsurf num ladrilho branco.

Os logotipos são propriedade de seus respectivos donos e são exibidos apenas para indicar compatibilidade.

Em resumo

  • Um app do Windsurf costuma ser seguro do lado do código. O que passa é a mudança que ninguém leu, então confira resultados em vez de diffs.
  • Procure service_role e sk_live_ na saída do seu build. Isso cobre todo arquivo que o assistente tocou, tendo você aberto ou não.
  • O Row Level Security é a única conferência que sobrevive a código que você nunca leu, porque todo pedido tem que passar pelo banco.

O Windsurf consegue mudar muita coisa do seu projeto num passo só: vários arquivos, uma migração, uma configuração, tudo de uma vez e tudo funcionando. O resultado costuma ser bom. O problema é a revisão: uma mudança espalhada por muitos arquivos não é lida do jeito que uma que toca um só é lida, e as duas coisas que valem ser pegas têm uma linha cada.

Aqui está o que guia após guia erra: a resposta não é ler com mais atenção. Na velocidade em que essas ferramentas trabalham, ler com atenção não escala. O que escala é conferir os dois resultados que importam, de fora e depois do fato.

A metade do seu app que é pública aconteça o que acontecer

A frente inteira.

Pense numa loja. Tudo que o Windsurf constrói na sua interface é a vitrine, e a vitrine é entregue inteira a cada visitante: um navegador não exibe uma página que não recebeu. Atrás dela fica o estoque, o seu banco de dados, um prédio separado na internet com endereço e fechadura próprios.

Essa distinção importa porque ler código te fala de intenção, e intenção não é o que vai para o ar. O que vai para o ar é a saída do build: um pacote de JavaScript, montado a partir de cada arquivo editado, entregue a quem quer que carregue o seu site. É esse pacote que vale inspecionar, e ele é muito menor de vasculhar do que o fonte de onde veio.

Uma chave no bundle do seu app do Windsurf é problema?

Normalmente não. Depende de qual chave, e as duas parecem quase idênticas.

As duas se chamam chave de API. Só uma delas foi feita para ser lida.

Uma chave publicável nomeia o seu projeto e não faz mais nada: sb_publishable_… nos projetos novos do Supabase, anon nos antigos. Ela foi feita para ser lida, e encontrá-la não é um achado. Uma chave secreta, sb_secret_… ou a antiga service_role, contorna todas as regras que você escreveu e lê e escreve em toda linha de toda tabela.

Como a segunda chega vale saber, porque não é descuido. Um assistente a quem se pede que um componente de navegador converse com o seu banco escreve código que funciona, e se esse código precisa de uma chave secreta, a chave vai para onde o código roda. O Vite diz sem rodeios que um valor com prefixo VITE_ vai empacotado no seu fonte na hora do build; o Next.js faz o mesmo com NEXT_PUBLIC_. Nada te avisa, porque do ponto de vista da ferramenta você pediu exatamente isso. Ler qual chave você tem leva cerca de um minuto.

A única regra que sobrevive a código que você não leu

Row Level Security, se os seus dados estão no Supabase, uma chave por tabela que decide linha a linha quem pode ler o quê.

O seu app e um estranho batem na mesma porta. A configuração decide quem entra, não as telas do seu app.

É por isso que essa é a conferência que vale. Todo pedido chega ao banco de dados, qualquer que seja o arquivo que o fez e quem quer que tenha escrito esse arquivo. Uma regra aplicada ali vale para todos de uma vez, inclusive o código daquela mudança que você só passou o olho. Nenhuma quantidade de código não revisado muda o que um pedido sem autenticação recebe de volta.

Duas coisas decidem se você tem isso. O Supabase liga o Row Level Security por padrão nas tabelas criadas no Table Editor do painel, e não nas criadas rodando SQL, que é como uma migração gerada as cria. E a chavinha é só metade da história: uma política que permite todo mundo deixa a tabela aberta enquanto o painel a informa como segura.

Como conferir o seu próprio projeto do Windsurf em uns dez minutos

Procure no build, não no fonte. Compile o projeto e depois procure nos arquivos de saída por service_role, sb_secret_ e sk_live_. Um comando, e ele cobre todo arquivo que o assistente tocou, tendo você aberto ou não.

Leia as variáveis com prefixo. Tudo que se chamar VITE_… ou NEXT_PUBLIC_… está publicado. Para cada uma, pergunte se você a colocaria na sua página inicial.

Abra Authentication → Policies no Supabase. Qualquer tabela listada com Row Level Security desligado responde a quem tiver o endereço do seu projeto, e esse endereço está no seu app.

E então olhe de fora. As três conferências acima dizem o que está configurado. O que um estranho realmente alcança é outra pergunta, e é a que o nosso scan gratuito responde: ele lê o seu site no ar como um visitante e te dá uma nota em uns 20 segundos, sem conta: escaneie seu app.

O que fazer

  • Revise por resultado, não por diff. Nessa velocidade, ler cada linha alterada não é um plano.
  • O que vai para o ar é o bundle compilado. Vasculhá-lo é mais rápido e mais verdadeiro do que ler o fonte de onde ele veio.
  • Uma chave publicável no navegador está certa. sb_secret_… e service_role são as que se trocam.
  • Um assistente põe a chave onde o código que ele escreveu precisa dela. Mantê-la fora do navegador nunca fez parte do pedido.
  • O Row Level Security é a conferência que sobrevive a código que você nunca leu, porque todo pedido tem que passar pelo banco.

Compile o seu projeto e procure service_role e sk_live_ na saída: leva um minuto e dá uma resposta sem ambiguidade sobre a mudança que você não leu. Depois disso, o checklist de segurança de 10 minutos cobre o resto.

O que pode dar errado de verdade com um app criado com o Windsurf

Nada disso significa que você fez algo errado: são os efeitos colaterais normais de um agente escrevendo muito código rápido. Vale a pena verificar isto:

  • Uma chave secreta que o agente ligou para você

    Para uma integração funcionar de primeira, o agente às vezes escreve a chave direto no código, e se aquele arquivo roda no navegador, qualquer um consegue ler. Algumas chaves são feitas para ser públicas e tudo bem. O Reeve lê o código carregado do seu app, encontra as chaves e diz quais são seguras e quais precisam ir para o servidor.

  • Um .env commitado ou uma pasta .git exposta

    Chaves ficam em um arquivo .env que nunca vai para produção. Mas uma mudança que mexe em dezenas de arquivos é fácil de aprovar sem ler todos os caminhos: o .env acaba commitado, ou a pasta oculta .git é publicada, e todo o seu histórico, chaves inclusive, fica a um download de distância. O Reeve verifica se algum dos dois é alcançável de fora.

  • Seu banco de dados aberto (RLS desligado)

    Se o seu app guarda dados (normalmente no Supabase ou em outro Postgres), quem decide quem pode ler ou alterar cada linha é o Row Level Security. Desligar é um jeito rápido de fazer algo funcionar enquanto você constrói, e costuma ficar assim. O Reeve verifica contando linhas, nunca lendo o conteúdo delas.

  • Armazenamento de arquivos público

    O que é enviado vai para "buckets" de armazenamento, e um bucket público deixa qualquer um listar e baixar o que está lá dentro: notas fiscais, documentos, fotos privadas. O Reeve verifica se os seus buckets podem ser listados; ele nunca baixa os arquivos de ninguém.

  • Source maps ligados

    Um source map entrega a quem olhar uma cópia legível do seu código original. Útil enquanto você constrói e um presente para estranhos depois que está no ar, porque facilita encontrar qualquer outra brecha. O Reeve verifica se os seus foram junto com a build.

  • Cabeçalhos de segurança faltando e endpoints abertos

    Algumas configurações dizem ao navegador como proteger seus visitantes; separado disso está se os seus endpoints de dados respondem a qualquer um, de qualquer site. Sozinhos são pequenos; juntos decidem o quanto um estranho consegue fazer com o que encontrar. O Reeve aponta o que está faltando.

O que o Reeve é, e o que não é

O Reeve é uma verificação gratuita, somente leitura e por fora, como um inspetor que testa as portas sem entrar. É rápida e pega os erros comuns de grande impacto. Não é uma auditoria de segurança completa, e uma nota limpa não é garantia. Significa que as portas óbvias estão fechadas.

O Windsurf é um editor, não uma hospedagem: ele escreve e executa código com você, mas não publica seu app nem toma conta dele depois. Essa parte é sua e do que o agente produziu. Revisar uma mudança grande antes de aceitar é o melhor hábito aqui, e se você usa Supabase o advisor dele aponta problemas de banco de dados. O que o Reeve acrescenta é a visão de fora: o que o app que você publicou realmente expõe, em palavras claras para agir. E se você preferir não pensar nisso, a gente pode ficar de olho por você.

Quer que seja resolvido, não só verificado?

O Reeve Care continua monitorando seu app, faz backup dos seus dados e ajuda você a corrigir as coisas quando quebram, para que você siga criando em vez de se preocupar.

Conheça o Reeve Care

Perguntas frequentes

O código escrito pelo agente do Windsurf é seguro?

Costuma ser um bom código, mas "o agente escreveu" não quer dizer "alguém conferiu se é seguro". Mudanças agênticas otimizam por um resultado que funciona, e para isso às vezes deixam uma chave no lugar errado ou desligam uma regra do banco para passar por um erro. O único jeito de saber é olhar o que ficou exposto. O Reeve faz isso de graça em uns 20 segundos.

O Cascade mudou muitos arquivos de uma vez. Como sei o que ficou exposto?

Lendo, na maioria das vezes você não consegue. Essa é a resposta honesta, e é por isso que olhar de fora ajuda: em vez de auditar um diff, o Reeve olha o app que você realmente publicou e informa o que um estranho consegue alcançar: chaves no navegador, banco de dados aberto, arquivos para baixar, um .env exposto.

Como sei se meu app do Windsurf está vazando chaves de API?

A causa mais comum é uma chave escrita em código que roda no navegador, onde "escondido" não existe. O Reeve lê o código carregado do seu app, encontra as chaves e diz quais podem ser públicas e quais precisam ir para o servidor, sem nunca guardar os valores reais.

Verificar meu app do Windsurf muda alguma coisa?

Não. O Reeve só olha o que já é público de fora. Ele nunca faz login, nunca altera nada e nunca baixa seus arquivos. Somente leitura, como conferir se uma porta está trancada sem entrar.

Um agente mudou arquivos que eu nunca abri. Como é que eu reviso isso?

Linha a linha não, e essa é a resposta honesta. Revise por resultado: compile o projeto e procure na saída os formatos de chave secreta, e depois veja o que o seu banco devolve para um pedido sem login. As duas coisas levam minutos e as duas pegam as duas falhas que realmente importam, tendo mudado quantos arquivos tiverem mudado.

Um assistente de IA coloca segredos no meu frontend de propósito?

Ele os coloca onde o código que escreveu precisa deles. Se um componente que roda no navegador foi escrito para chamar algo que exige uma chave secreta, a chave tem que estar no navegador para aquele código funcionar, então o assistente faz funcionar. A instrução de mantê-la num servidor nunca esteve no pedido.

Qual conferência sozinha me diz mais sobre o meu app?

Se o Row Level Security está ligado em todas as tabelas, e se as políticas de fato restringem alguém. É a única regra que vale para todo pedido, não importa qual arquivo o fez, então ela sobrevive a qualquer quantidade de código que você não leu.

Escrito por

Vlad Tkachenko

Fundador da Reeve

Passo meus dias olhando apps criados com Lovable, Bolt, v0, Cursor e Replit, e a curta lista de erros que aparecem neles sem parar.

Mais sobre o autor

Criou em outro lugar? Temos o mesmo resumo honesto para:

← Ver todos os guias de segurança dos criadores

Verificação externa automatizada, não uma auditoria completa. A ausência de achados não é garantia de segurança.