Lean aceitou prova de falso; malware usa comando colado no Terminal

Escultura do Lean atrás de um anel marcado Kernel, que aceita um cartão com a palavra False.

Uma prova formal pode estar completa, sem atalhos aparentes, e ainda provar uma mentira. Foi o que aconteceu no Lean: uma falha no pequeno kernel encarregado da conferência final permitiu aceitar uma prova de False. O bug já foi corrigido, mas atingiu justamente a peça que deveria dar a última palavra.

A história começou com uma tentativa assistida por IA de refutar a conjectura de Collatz. O resultado não resolveu um problema famoso da matemática. Em vez disso, mostrou que, por alguns dias, um artefato aceito pela versão instalada do verificador podia atravessar uma fronteira de confiança quebrada.

Lean corrige o kernel que aceitou uma prova de False

Em 25 de julho, um repositório publicou uma suposta “refutação” da conjectura de Collatz. O trabalho usava IA e não continha sorry, o marcador que permite deixar uma obrigação de prova pendente no Lean. Parecia completo. Kiran Gopinathan reduziu o artefato até chegar a uma prova do falso sem axiomas e abriu o issue 14576 em 28 de julho.

O problema estava no tratamento de parâmetros fantasma em tipos indutivos aninhados. O frontend normal do Lean rejeitava o termo malformado, mas uma declaração indutiva enviada diretamente ao kernel por metaprogramação alcançava a falha. O caminho do exploit era restrito, só que isso não alivia o problema: o frontend é uma camada conveniente e deliberadamente não confiável. O kernel existe para não depender dela.

Um assistente de provas funciona mais ou menos assim: o elaborador transforma o código amigável escrito pelo usuário num termo formal; depois, um kernel bem menor confere esse termo. Se o kernel aceita uma declaração inválida, um arquivo bonito, completo e sem lacunas já não garante muita coisa. A sintaxe passou pela catraca, mas a catraca estava contando errado.

O issue foi aberto às 03h28 UTC e fechado às 13h39 UTC daquele mesmo dia. A correção principal ficou no pull request 14577, e o Lean 4.32.2 saiu ainda em 28 de julho. Quem usa Lean deve atualizar tanto o sistema quanto verificadores independentes como o nanoda, principalmente antes de aceitar ou redistribuir provas produzidas por ferramentas automatizadas.

O nanoda deveria ser uma segunda barreira. Uma versão antiga dele também aceitou o artefato, mas por outro defeito, relacionado a nós de projeção. Segundo o postmortem, a coincidência temporal não basta para concluir que o modelo conhecia esse bug anterior. A explicação prática é bem menos misteriosa: dois verificadores só ajudam quando são realmente independentes e estão atualizados.

Outro verificador, o lean4lean, ainda não tinha suporte completo a tipos indutivos e herdava a falha da implementação de referência. Então não dá para dizer que o Lean seja inteiramente verificado por ele mesmo. O incidente foi uma falha de implementação, não um buraco conhecido na metateoria do Lean.

Recentemente, falamos do uso do Lean para verificar achados de segurança. Desta vez, o caso é desconfortavelmente concreto: a fronteira confiável falhou, a correção veio rápido e um verificador independente desatualizado também deixou o artefato passar. Prova gerada por IA continua precisando de verificação. E verificação também é software.

Fontes: postmortem de Leonardo de Moura, issue 14576 do Lean e release 4.32.2.

AMOS transforma texto colado no Terminal em instalador

No macOS, uma página que promete um “toolkit” pede que o usuário copie um texto e cole no Terminal. A pessoa vê uma sequência de caracteres que talvez nem reconheça, aperta Enter e autoriza o shell a buscar o restante. O SANS Internet Storm Center reproduziu essa cadeia num laboratório em 31 de julho e publicou o diário, atualizado em 2 de agosto. No lugar da ferramenta prometida, o texto instalou o Atomic macOS Stealer, ou AMOS.

A amostra veio da isca getmacouscloud[.]com. O código baixou outros estágios, colocou executáveis Mach-O em /tmp e criou persistência em diretórios ocultos com nomes parecidos com componentes da Apple, dentro de ~/Library/Application Support. Entre eles estavam .com.apple.accountsd/AccountsHelper e .com.apple.metadata.mds/mdworker_shared.

Os binários eram universais, com suporte a x86_64 e arm64, portanto podiam rodar nativamente em Macs Intel e Apple Silicon. Já o prefixo .com.apple.* era só camuflagem plausível. Nome com cara de Cupertino não transforma malware em componente do sistema.

No tráfego observado, os nomes dos estágios de comando e controle indicavam coleta de mensageiros, credenciais, navegadores, carteiras e dados locais. Tudo seguia por HTTP para um único IP. Foi uma infecção controlada pelo SANS, não uma medição do tamanho da campanha ou do número de vítimas.

A defesa começa antes do antivírus: colar no Terminal é executar código. Como a própria vítima inicia o comando, o shell pode buscar, decodificar e rodar os estágios seguintes. A instrução de uma página aleatória não fica segura só porque veio acompanhada de “copie e cole”.

Equipes que administram Macs podem procurar processos de shell abrindo conexões de rede e novos caminhos ocultos, com aparência de Apple, no diretório Application Support do usuário. Estes são os hashes SHA-256 observados pelo SANS:

  • 9f25ec533cb23d020e568fb771500d7776b1300f07119ad9d0876f4329ce22ab, para /tmp/helper;
  • 0a03cf18de28017c0ea591dffc380a6b41fedd2acc3a39e901e58d9188c01836, para o AccountsHelper persistente;
  • 01a0d5332b09bb299f7784bf0d0c43c4199269ed6a0712377279eeb999847d20, para o mdworker_shared persistente.

Outros indicadores publicados foram render65[.]com, grove-89[.]com e 188[.]166[.]78[.]138. Nenhum deles deve ser aberto para “dar uma olhadinha”. Texto suspeito deve ser decodificado, e qualquer download deve ocorrer somente num ambiente isolado de análise, nunca na estação de trabalho.

Fonte: SANS Internet Storm Center, diário 33208.

Coldcard entregou 32 bytes sem entregar a entropia esperada

Uma função chamada random.bytes(32) devolveu exatamente 32 bytes. A aplicação ainda verificou se havia mais de quatro valores distintos, aplicou um hash e seguiu em frente. O formato estava certo. A propriedade de segurança, a imprevisibilidade, não.

Uma análise publicada em 1º de agosto reconstrói o caminho usado pelo firmware 4.0.0 da carteira de hardware Coldcard. Em 2021, o commit 37e4af5451c260c1e7d429fe8972c4cb5e68ee59, com o pouco informativo título “runs”, mexeu em mais de 1.500 linhas, adicionou bindings personalizados de geração aleatória e definiu MICROPY_HW_ENABLE_RNG como 0.

Com a fonte de hardware desabilitada, o caminho analisado do MicroPython fazia rng_get() cair no gerador Yasmarang, inadequado para esse uso criptográfico. O override personalizado de pyb.rng() não era chamado por random.bytes() durante a criação da carteira. A aplicação atravessava Python e C por uma rota diferente da usada pelo binding personalizado.

É assim que uma API pode cumprir o contrato sintático e quebrar o contrato de segurança. Testes superficiais conferem tamanho, tipo e alguma variedade, mas não descobrem de onde vieram os bytes. Aplicar hash sobre uma entrada com pouca entropia também não produz a aleatoriedade que faltava. Só transforma o valor fraco de maneira determinística.

A reconstrução sustenta esse caminho no código. A evidência aberta aqui, porém, não estabelece uma contagem de perdas nem prova sozinha a causa de todos os comprometimentos discutidos em torno da Coldcard.

Código que cria chaves ou seeds precisa ser testado pela chamada real da aplicação, confirmando a fonte de aleatoriedade usada de ponta a ponta. Testes estatísticos simples podem denunciar uma regressão catastrófica, mas não provam que um gerador seja criptograficamente seguro. O controle mais forte é monitorar a fonte de hardware e falhar de forma explícita quando ela não estiver disponível.

Fontes: análise do bitcoin++ Insider, commit do firmware Coldcard e código histórico do RNG no MicroPython.

PostgreSQL pode estar saudável com o mapa de usuários ausente ou velho

O PostgreSQL pode iniciar, aceitar consultas e parecer saudável mesmo sem carregar o arquivo de mapeamento usado na autenticação. Também pode recusar um reload malformado e continuar aplicando os mapas antigos em silêncio. O processo está vivo, mas a configuração no disco talvez não seja a configuração em vigor.

Christophe Pettus descreveu os dois comportamentos num experimento publicado em 1º de agosto. O pg_ident.conf associa identidades do sistema operacional ou de provedores externos a roles do banco. Ele participa de regras de autenticação com map=, entre elas ident, peer, GSSAPI, SSPI, certificados e, no PostgreSQL 18, OAuth.

A primeira armadilha é o caminho. Se ident_file recebe um valor relativo, o PostgreSQL o resolve a partir do diretório de trabalho do processo que iniciou o servidor, não automaticamente de PGDATA nem da pasta de configuração. Um hba_file ausente impede a inicialização. Já um ident_file ausente deixa o servidor anunciar que está pronto, mas sem mapas. Os logins que dependem deles falham.

A segunda aparece no reload. Se o novo pg_ident.conf estiver malformado, o PostgreSQL mantém na memória os mapas antigos. A view pg_ident_file_mappings, disponível desde o PostgreSQL 15, lê e analisa o arquivo no disco a cada consulta. Por isso, ela pode exibir erros ou conteúdo diferente do mapa antigo que o postmaster ainda aplica.

Não é uma nova CVE. É uma diferença operacional entre o estado do arquivo e o estado carregado. Use caminho absoluto, gere alerta para falhas de reload e faça um teste real de autenticação mapeada depois do deploy. Debian e Ubuntu normalmente já usam um caminho absoluto em /etc/postgresql/NN/main/pg_ident.conf, o que evita a primeira surpresa.

Fonte: Christophe Pettus, The Build.

Agentes precisam saber se estão explorando ou entregando

Parte do excesso produzido por agentes nasce antes do primeiro token de código: ninguém definiu se a tarefa é descobrir uma solução ou executar uma solução já escolhida. Aaron Brethorst deu dois nomes a essa diferença.

No modo “greenhouse”, ou estufa, experimentar custa pouco. O agente cria alternativas, protótipos e evidências para uma decisão posterior. O resultado pode ir para o lixo sem cerimônia, porque a tarefa era reduzir a incerteza.

No modo “lens”, ou lente, o alvo já é conhecido. Saídas que não aproximam o trabalho desse alvo devem ser rejeitadas. Aqui entram limites de escopo, testes de aceitação e uma definição de pronto melhor do que “o build passou”. Compilar prova que o código compila. Não prova que o agente preservou as invariantes do domínio ou deixou de construir aquele painel administrativo que ninguém pediu.

O autor apresenta isso como um modelo de engenharia baseado na própria experiência, não como benchmark ou comparação controlada. Ainda assim, o vocabulário ajuda no contrato da tarefa: diga quando você quer alternativas descartáveis e quando quer uma mudança restrita, com critérios objetivos. Depois, vigie a deriva. Um agente pode começar numa lente e transformar a demanda numa estufa particular de abstrações.

Coberturas recentes mostraram várias falhas de verificação em agentes. Aqui, a contribuição não é outra pontuação de modelo, mas uma pergunta curta para fazer durante o trabalho: estamos explorando ou entregando?

Fonte: Aaron Brethorst, The Greenhouse and the Lens.

RFC 10015 aposenta trocas de chave antigas no TLS 1.2

A RFC 10015, publicada na trilha de padrões da IETF em julho de 2026, endurece as regras para TLS e DTLS 1.2. Clientes não devem oferecer, e servidores não devem selecionar, suites com troca estática de chaves RSA, Diffie-Hellman não efêmero ou Diffie-Hellman efêmero de campo finito, conhecido como FFDHE ou DHE. Para ECDH estático, a recomendação é SHOULD NOT, menos categórica que o MUST NOT dos demais casos.

Entre os motivos estão a falta de sigilo futuro no RSA estático, falhas recorrentes no estilo Bleichenbacher e problemas de negociação, grupos pequenos, temporização e reutilização de segredos no Diffie-Hellman de campo finito. O sigilo futuro limita a chance de descriptografar tráfego antigo caso uma chave privada de longo prazo seja comprometida mais tarde.

Isso não proíbe certificados RSA. Autenticação e troca de chaves são partes diferentes do handshake. Um certificado RSA ainda pode assinar uma troca efêmera ECDHE e preservar sigilo futuro. A proibição mira a troca estática nas suites TLS_RSA_*.

A mesma proibição não se aplica ao FFDHE do TLS 1.3, cujo desenho não compartilha esses problemas do TLS 1.2. TLS 1.0 e 1.1 já haviam sido depreciados pela RFC 8996.

Quem mantém proxies, balanceadores, servidores, clientes embarcados ou perfis antigos de conformidade precisa inventariar a troca de chaves realmente negociada, em vez de olhar apenas para o tipo do certificado. A preferência é TLS 1.3. Onde a compatibilidade ainda exigir TLS 1.2, a opção prática são suites ECDHE.

Fonte: IETF RFC 10015.

NetBSD 11.0 chega com três correções de segurança pendentes

O NetBSD 11.0 saiu em 1º de agosto, e o próprio projeto destacou três correções de segurança que ainda aguardam integração. A PR 60492 trata de uma checagem de privilégio local no hdaudio. A PR 60484 cobre uma desreferência de ponteiro nulo no IPFilter que pode ser disparada remotamente. A PR 60485 corrige um use-after-free na remontagem de fragmentos do PF.

IPFilter e PF não vêm habilitados nos kernels lançados por padrão, e o PF está depreciado. Isso reduz a exposição inicial, mas não protege kernels personalizados ou instalações que ativaram esses componentes. Para o problema local do áudio, o workaround publicado é remover /dev/hdaudio*; o áudio continua funcionando.

O projeto pretende incluir as correções no NetBSD 11.1 em até dois meses. É uma meta, não uma data garantida. Quem adotar a nova versão deve avaliar os subsistemas que realmente usa, acompanhar a branch estável e o 11.1 e não tomar “major release” como sinônimo de “fila de segurança zerada”.

Há também um detalhe bem terreno na instalação: as imagens .iso servem para CD e DVD. Em pendrives, use os arquivos .img depois de descompactá-los. O projeto oferece ISOs separadas de CD com menos de 700 MB e uma imagem completa de DVD.

Fonte: anúncio do NetBSD 11.0.

NeuralGuard combina triagem local e segunda opinião no pull request

O projeto brasileiro NeuralGuard apresenta, numa série de 14 artigos, um classificador de vulnerabilidades em C# baseado em CodeBERT e TorchSharp. Ele procura cinco classes: injeção de SQL, XSS, injeção de comandos, travessia de caminhos e desserialização insegura. O detector é empacotado como ferramenta .NET e executado sobre as linhas alteradas em pull requests do GitHub.

O autor relata acurácia de 77,3% depois de corrigir um vazamento entre os dados de treino e teste que havia inflado o resultado inicial. O próprio projeto reconhece que esse número não basta para bloquear merges sozinho. Na arquitetura proposta, o modelo local faz uma triagem barata e envia cada alerta ao Claude, pelo SDK oficial de C#, para obter uma segunda opinião estruturada.

Esse padrão pode reduzir o volume antes de uma revisão mais cara, mas não valida o classificador de forma independente. Acurácia isolada não mostra balanceamento das classes, precisão, recall, desempenho por categoria ou o efeito da troca de repositório. Claude também é um revisor probabilístico, não um oráculo fora da categoria “IA”.

Analisar somente o diff reduz custo e ruído, mas pode deixar passar uma vulnerabilidade cuja origem ou destino esteja em código não alterado. Antes de adotar a ferramenta, cada equipe ainda precisa medir falsos positivos e falsos negativos no próprio código. Para achados de alto risco, analisadores determinísticos, testes e revisão humana continuam necessários.

Fontes: série NeuralGuard no DevFullStack.Net e anúncio do autor no TabNews.

sizeof ainda obriga o parser de C a olhar além do parêntese

Para fechar, uma pequena maldade da gramática de C. sizeof aceita uma expressão unária ou um nome de tipo entre parênteses. Assim, sizeof 67, sizeof(67) e sizeof(int) são válidos, embora os parênteses sejam obrigatórios apenas na forma com tipo.

A tentação de um parser é olhar o primeiro token depois de ( e decidir se encontrou um tipo. Literais compostos e operadores postfixos estragam o atalho: construções como sizeof(T){}.x[0]() continuam sendo expressões. Do outro lado, reaproveitar sem cuidado o parser de casts pode consumir demais e interpretar errado sizeof(int)+1, que deve continuar sendo uma soma depois do operando de tipo.

A distinção ainda depende da tabela de símbolos, pois o lexer nem sempre sabe sozinho se um identificador nomeia um tipo. Parsers, formatadores, linters, realçadores de sintaxe e ferramentas de reescrita precisam de backtracking cuidadoso ou de uma rotina gramatical que preserve essa fronteira. O futuro C2Y repete a ambiguidade no novo _Countof. Não é uma vulnerabilidade nova. É só C lembrando que um parêntese nunca vem sozinho.

Fonte: nota de sebsite sobre sizeof.

Nota: gerado por IA (The Paper LLM), com fontes originais listadas por bloco.

Comentários

No seu e-mail

Newsletter

Junte-se a centenas de outros desenvolvedores e receba dicas e conteúdo técnico diretamente na sua caixa de entrada. Sem SPAM ou publicidade. Apenas conteúdo de qualidade.