Uma análise da biblioteca OAuth escrita por IA da Cloudflare
(neilmadden.blog)- A Cloudflare desenvolveu uma nova biblioteca OAuth usando o Claude LLM da Anthropic e também publicou os prompts
- A estrutura do código da biblioteca é limpa, mas há muitas limitações em termos de testes e validação de segurança
- Foram encontradas escolhas fora do padrão ou arriscadas na implementação de CORS e de algumas especificações de autenticação
- Embora haja pontos positivos na implementação criptográfica, também vieram à tona bugs graves de segurança e mal-entendidos sobre o protocolo
- A codificação automática baseada em LLM ajuda, mas para segurança em nível de produção a revisão minuciosa de especialistas é indispensável
Visão geral da biblioteca OAuth da Cloudflare
- A Cloudflare escreveu de forma majoritariamente automática uma biblioteca de provedor OAuth com o uso do Claude LLM da Anthropic
- O resultado gerado pelo Claude passou por revisão de segurança e conformidade com padrões feita por engenheiros experientes da Cloudflare, e o histórico de commits mostra com transparência o processo de interação com a IA
- Após a implementação inicial, a qualidade foi refinada por meio de prompts adicionais ao Claude e revisão dos resultados
- A empresa afirma que não dependeu apenas da IA, enfatizando a verificação cruzada com documentos RFC e a revisão de especialistas-chave
Primeiras impressões dos especialistas e análise do código
- Como é típico do estilo de programação com LLM, o código fica concentrado em um único arquivo, mas a estrutura é consistente e há relativamente poucos comentários desnecessários
- Existem testes funcionais, porém eles não chegam ao nível exigido para serviços críticos de autenticação como OAuth
- Dá para notar ausência de verificações de requisitos obrigatórios (MUST/MUST NOT) e validação fraca de parâmetros
Preocupações de segurança e explicação do tradutor
1. Problema na política de CORS ("YOLO CORS")
- Foi encontrada uma configuração de cabeçalhos CORS que permite quase todas as origens, desativando na prática a política de mesma origem
- Essa foi uma parte decidida diretamente por um humano, e não pelo LLM, segundo engenheiros da Cloudflare
- Como a funcionalidade de credentials não está ativada, o risco de uma ameaça crítica à segurança do navegador é menor, mas faltou clareza sobre a causa e o objetivo da escolha
2. Ausência de cabeçalhos de segurança padrão
- Nas respostas HTTP, faltam cabeçalhos essenciais de segurança como X-Content-Type-Options: nosniff e HTTP Strict Transport Security
- Por se tratar de uma JSON API, alguns desses cabeçalhos podem parecer menos necessários, mas sua aplicação continua sendo importante para prevenir vulnerabilidades em clientes e navegadores
3. Sinais de pouco domínio do padrão OAuth
- Para oferecer suporte a public clients, foi implementado o fluxo implicit grant, já descontinuado no OAuth 2.1
- Na prática, essa funcionalidade poderia ser substituída suficientemente por PKCE ou por uma flexibilização de CORS
- Ao que tudo indica, o Claude recomendou o implicit grant, e na etapa real de emissão do token a validação não é feita adequadamente
- Tratamento insuficiente de Basic Auth: no OAuth é necessário um esquema específico de codificação de URL, mas isso foi omitido
- Isso pode gerar um bug de segurança secundário quando o client secret contém dois-pontos
- Ainda assim, a biblioteca gera por conta própria client IDs e secrets, o que permite controlar o formato
4. Problemas de segurança no código de geração de IDs de token
- O método de geração de strings aleatórias para IDs de token apresenta viés estatístico (biased)
- A redução de entropia pode facilitar ataques, embora a ameaça prática seja limitada
- Apesar da alegação de que todas as linhas de código foram revisadas por especialistas, o bug permaneceu no commit inicial
- O histórico de um único desenvolvedor fazendo 21 commits diretos na branch principal já no primeiro dia sugere falta de uma revisão mais estruturada
Funções criptográficas e exemplos da interação com o LLM
- O desenho da criptografia do armazenamento de tokens foi conduzido por humanos, com apoio do Claude na implementação
- Foi aplicado um modelo em que as propriedades de cada token são criptografadas, e uma chave simétrica é encapsulada para cada token
- Quando o Claude sugeriu um desenho incorreto no meio do processo, o engenheiro expôs com clareza a intenção e os objetivos de segurança, levando à correção
- Exemplo: depois de apontar a vulnerabilidade que surgiria ao usar um hash SHA-256 como wrapping key, a solução foi alterada para uma abordagem baseada em HMAC
- Diante da sugestão de PBKDF2, foi observado o problema de ineficiência de desempenho, e o desenho foi ajustado para usar uma chave HMAC de 32 bytes
- Esse processo mostra bem como trabalhar com IA exige alto nível de conhecimento de domínio
- Um não especialista talvez nem conseguisse perceber falhas críticas
Avaliação geral e implicações
- Mesmo sendo uma primeira versão, o nível de acabamento é razoavelmente bom, mas aplicá-la diretamente em um serviço real ainda seria arriscado
- O desenvolvimento de um provedor OAuth exige por natureza uma validação extremamente difícil de segurança e funcionalidade
- Em empresas grandes, o comum é haver centenas de milhares de testes automatizados e verificações de segurança em múltiplas camadas
- Não é uma área em que seja fácil aplicar codificação automática baseada em LLM
- O histórico de commits do projeto mostra de forma interessante até que ponto um LLM pode atuar como apoio
- Ainda assim, alguns defeitos são erros que tanto LLMs quanto humanos cometem com frequência, e já aparecem de forma semelhante em respostas do Stack Overflow e em outras comunidades
- Em áreas de código onde rigor e atenção aos detalhes são cruciais, tanto a IA quanto os humanos precisam de cuidado minucioso
- Para revisar código com apoio de LLM ou confiar no resultado, experiência prática de implementação e pensamento System 2 são indispensáveis
- Em tarefas simples ou não centrais, o LLM pode ser usado com tranquilidade, mas sistemas principais ligados a autenticação ou segurança devem preferencialmente ser projetados e implementados sob liderança de especialistas
2 comentários
Analisando a biblioteca OAuth escrita pela IA da Cloudflare
Comentários do Hacker News
Este caso mostra de forma bem direta que é preciso muito conhecimento de domínio ao interagir com LLMs. Por exemplo, um desenvolvedor comum talvez não percebesse a “falha crítica” que o Claude inventou no meio do processo. Estranhar a mudança para PBKDF2 também só acontece por causa da especialização no domínio. Minha conclusão é que, para usar LLMs de forma eficiente, é preciso um bom revisor e um “líder”. Se você sabe menos sobre o assunto do que o próprio LLM, então isso precisa ser algo de baixa prioridade ou você precisa ter bastante tempo para validar toda a saída
Isso me faz pensar de onde vão surgir os especialistas de domínio nesse novo ambiente. No fim, fico pensando quem vai conseguir se tornar alguém com esse nível de profundidade
Sempre acho estranho quando ouço a opinião de que “só se usa LLM em áreas que você não conhece; se for especialista, você programa direto”. Na verdade, quanto mais especialista você é, melhor consegue revisar a saída do LLM, e quanto mais você consegue explicar o que quer de uma forma próxima à de um especialista no domínio, melhor fica o resultado. De certo modo isso é óbvio (já que o LLM é um motor de texto gerado estatisticamente)
LLMs têm muita tendência a adicionar defaults, tratamento de exceções e todo tipo de workaround com facilidade demais. Aí o código parece funcionar, mas na prática tem problemas ou vai falhar em breve. Tentei enfatizar isso várias vezes no meu
CLAUDE.md, mas mesmo assim esse tipo de resultado continua aparecendo às vezesEu fiz a maior parte de deploys em k8s com LLM. Ele gera algo funcional rapidamente, mas eu sempre precisava lembrar repetidamente para usar secrets e não dar commit em credenciais em texto puro. Esse tipo de erro é realmente perigoso. Tutoriais educacionais muitas vezes omitem segurança para focar no básico, e parece que há exemplos demais disso nos dados de treino dos LLMs, então eles acabam produzindo esse tipo de saída
Com o tempo, espero que ferramentas de coding com IA consigam pesquisar conhecimento de domínio por conta própria. Algumas ferramentas de “pesquisa com IA” que já existem são muito boas nisso, mas ainda não estão bem integradas às ferramentas de programação. A pesquisa pode consultar não só a internet pública, mas também conhecimento de domínio em documentação interna da empresa. Ainda assim, parte desse conhecimento só existe na cabeça das pessoas, então o usuário vai precisar transmitir isso diretamente
Recentemente escrevi um consumer de Kafka com ajuda de IA para fazer uma migração de dados. Esse foi o cenário em que o uso de IA teve seu efeito máximo: um projeto curto, feito do zero, e eu conhecia bem a linguagem (Go), mas não a usava havia algum tempo. Todos os dados entravam por um único topic, então implementei um processamento paralelo bem complexo para garantir performance. No geral, tive a sensação de ter ficado umas 2 vezes mais rápido graças à IA. Foi especialmente útil quando eu esquecia algum detalhe de sintaxe de Go e, em vez de pesquisar, perguntava direto para a IA. Mas havia pelo menos 4 bugs potenciais escondidos ali (além de muitos outros bugs óbvios). Se eu não fosse familiarizado com Kafka ou multithreading, talvez tivesse colocado isso direto em produção. Em projetos grandes ou de longo prazo, a melhora fica mais na faixa de 10% a 20%. Com os modelos atuais, é isso que tenho visto. No quadro geral, isso se parece com o ganho de produtividade que houve ao migrar para linguagens com gerenciamento de memória. Está bem longe da fantasia de PM substituindo desenvolvedores (pelo ritmo de mudança dos últimos 3 anos). Minha preocupação real é que, se um desenvolvedor de nível intermediário e muito produtivo ficar 10 vezes mais eficiente com IA, ele pode se tornar ainda mais perigoso por não conseguir encontrar ou lidar com bugs sutis. Engenheiros sênior/staff talvez não deem conta da avalanche de revisões. E também me preocupo que o processo de crescimento de júnior para sênior fique mais frágil. Já existe o problema do programador de copiar e colar, e a IA reforça ainda mais esse padrão. No fim o mercado vai resolver isso, mas dá medo pensar que isso pode levar décadas
Os bugs produzidos por IA são realmente traiçoeiros. Eu também já mandei IA escrever código multithread e acabei colocando um bug sutil em produção. Mesmo com revisão e testes, a concentração não chega ao mesmo nível de quando você escreveu aquilo à mão. Por enquanto, tenho a sensação de que código gerado por IA precisa ser tratado assumindo bugs comuns de antemão e usado apenas em áreas sem impacto crítico
Eu também sinto uma melhora de uns 10% a 20% em “trabalho importante”. É uma mudança real, mas não altera a essência do desenvolvimento de software. No fim, é uma reafirmação da tese “No Silver Bullet” do Brooks
Também concordo com o ponto sobre o “vendaval técnico” de nível intermediário. Especialmente no setor de consultoria, veteranos muitas vezes são tratados como tendo pouco valor pelo custo. Antigamente eu também era do tipo que entregava rápido, e mais tarde tive a experiência difícil de explicar para PMs não especialistas as fraquezas de soluções de curto prazo. Grandes empresas de tecnologia provavelmente vão detectar esse tipo de problema rapidamente, mas na prática códigos que lidam com dados financeiros e médicos são escritos por mão de obra barata de contrato curto. Isso já era um problema antes dos LLMs. Agora deve ser uma época muito mais dura para desenvolvedores sensíveis a questões de segurança
Você mencionou que encontrou bugs sutis no código gerado; fiquei pensando se não daria para detectá-los automaticamente com código de teste também gerado por IA. Claro, o próprio código de teste também pode ter bugs, mas dá para imaginar um futuro em que revisamos com atenção apenas os resultados dos testes, e não mais o código gerado em si
Você falou em processamento paralelo complexo, mas isso não seria algo que poderia ser resolvido com partitions e consumer groups?
Fico angustiado quando vejo gente confiando ativamente em LLMs e trabalhando “como quem cai de um penhasco”, apoiando-se neles sem senso crítico. É perigoso depender completamente de uma caixa-preta para trabalhar e ainda delegar toda a validação a ela. Além disso, é uma estrutura que consome uma quantidade absurda de energia e acaba sendo usada como desculpa para substituir pessoas. Sinceramente, não consigo acreditar que esse ambiente torne a vida 10 vezes melhor
Quando comparo desenvolver algo eu mesmo com o processo de validar o resultado feito por outra pessoa (especialmente código gerado por LLM), parece que os humanos muitas vezes se deixam enganar por uma aparência plausível e aceitam problemas de forma menos crítica. A “cara” do código também influencia muito na detecção de bugs. Uma forma de verificar isso seria inserir bugs propositalmente no código e fazer experimentos para ver se revisores conseguem encontrá-los. Quando você implementa algo com as próprias mãos, pensa de forma muito mais lenta e cuidadosa e presta atenção aos detalhes (por isso encontra bugs inesperados também). Por isso muita gente recomenda, para fins de aprendizado, escrever você mesmo uma “versão de brinquedo” da ferramenta. Isso tem a ver com a própria estrutura cognitiva humana
O artigo dizia que não havia muitos comentários desnecessários, mas no código real existem comentários sem sentido como
// Get the Origin header from the requestComentários assim são um sinal evidente de uso de LLM, e eu sempre apago porque não significam nada
Para humanos esses comentários não servem para nada, mas imagino que, do ponto de vista do LLM, ter a função do código descrita em linguagem natural junto logo abaixo possa ajudar no entendimento, como uma espécie de Pedra de Roseta. Pode custar mais tokens, mas eu até gostaria de testar se LLMs realmente editam melhor código excessivamente comentado
Compartilho a experiência de que o Claude tem uma tendência enorme de escrever esse tipo de comentário inútil e redundante com muita frequência
Uma sugestão seria congelar uma branch do código e usar IAs em uma espécie de batalha: de um lado, tentando criar e esconder vulnerabilidades; do outro, tentando encontrá-las e corrigi-las. Seria como aplicar ao desenvolvimento de código o processo evolutivo que vimos no xadrez
Eu sou o autor desta biblioteca (mais precisamente, o autor do prompt). Não sou tão especialista em OAuth quanto o Neil, mas tenho um certo nível de domínio, e fiquei realmente feliz que ele tenha revisado o código. Houve um mal-entendido sobre o “YOLO CORS”: isso não foi um erro ingênuo de iniciante. Essas configurações de CORS foram intencionais e bastante ponderadas. Eu só desabilitei o CORS nos endpoints da API OAuth (troca de token, registro de cliente) e nos endpoints de API que exigem OAuth bearer token. Como esses endpoints não são autenticados por credenciais do navegador (cookies etc.), concluí que o CORS na prática não estava protegendo nada ali. A essência do CORS é ser uma barreira de segurança que impede o envio automático de credenciais, mas bearer tokens precisam ser anexados explicitamente pelo cliente, então são seguros mesmo em contexto cross-origin. Na verdade, já discuti isso no passado com pessoas que escreveram a especificação de CORS, defendendo que usar bearer tokens em vez de credenciais do navegador é o que de fato é seguro. Quanto à crítica de que a geração de token ID é ineficiente, não acho que isso chegue a ser “crítico”. Não há problema de segurança em si, e o algoritmo pode ser alterado livremente depois. A questão de 21 commits no main em um único dia por uma única pessoa aparece assim no GitHub porque o histórico do git foi reescrito e as datas ficaram distorcidas. E agradeço muito o elogio à implementação criptográfica. Isso não foi gerado pela IA, mas resultado de instruções explícitas de design que eu dei
Você disse que “desabilita os headers de CORS na API OAuth”, mas na prática está configurando headers de CORS para desativar as regras de CORS. Pelo contexto dá para entender, mas vale complementar para evitar confusão
Fico curioso se a Cloudflare pretende usar essa biblioteca em produção de verdade
Fico preocupado ao pensar que respostas populares do Stack Overflow têm exatamente os mesmos erros, e que o Claude provavelmente aprendeu com isso. Mais do que as falhas de segurança ou os erros em si, assusta a possibilidade de o estoque de conhecimento da sociedade ficar congelado nas respostas populares da internet pré-LLM
Ver que a implementação de OAuth da ForgeRock teve centenas de bugs de segurança, mesmo com centenas de milhares de testes automatizados, threat modeling, SAST/DAST de altíssimo nível e revisão de especialistas, me fez sentir de novo o quanto OAuth é complicado. Algumas pessoas até chamam essas implementações de “incêndio em lixão”. Eu mesmo nunca li a spec nem implementei
Sempre que tive envolvimento com implementação de OAuth, a sensação foi de algo horrivelmente complexo
OAuth é realmente irritante e tem nichos demais
Na prática, código novo sempre vai ter bugs. Quanto mais complexo, mais certo isso fica. Por isso as empresas tentam usar código e ferramentas “battle tested” (já validados em campo). Brincadeiras à parte, é interessante ver como a Anthropic usa sua própria IA generativa de forma prática no próprio código. Fico curioso se vão aplicar isso também à API de autenticação do MCP
“Centenas de milhares de testes” parece algo que só pode crescer em quantidade ou então suspeito que tenha sido feito totalmente por LLM. Também fico curioso sobre quem mantém isso na prática
Fico me perguntando se a tendência de as pessoas commitarem seus prompts no git vai se tornar algo comum, ou se isso é mais um showcase