Rodar LLM localmente não garante privacidade: falha de autorização no llama.cpp permite roubar conversas de outros usuários
Um estudo sistemático de quatro fronteiras de confidencialidade em sistemas de LLM local (carregamento de modelo, memória em tempo de execução, persistência do wrapper e interface de servimento) encontrou uma falha de autorização não documentada no llama.cpp que permite a um cliente autenticado restaurar o estado de conversa salvo de outro usuário, com sucesso em 200 de 200 tentativas controladas. Os pesquisadores também mostram que texto puro do prompt sobrevive na memória após a inferência e que o cache compartilhado de prefixo cria um oráculo de temporização explorável remotamente.
A premissa que o artigo desafia é bastante intuitiva e amplamente aceita: se o modelo roda no seu próprio computador, seus prompts nunca saem dali, logo são privados. Os autores mostram que essa lógica ignora o software de servimento que fica em volta do modelo — o processo que carrega os pesos, gerencia memória, salva sessões e expõe uma API local — e que esse software introduz suas próprias falhas de confidencialidade, independentemente de o modelo estar na nuvem ou na máquina do usuário. Para investigar isso de forma sistemática, os autores desenvolvem o LLAnalyzer, um framework de medição que testa separadamente quatro fronteiras: carregamento de modelo, memória de runtime, persistência em nível de wrapper e a interface de servimento (API local).
Os resultados variam bastante entre essas fronteiras. No carregamento de modelo, uma campanha de fuzzing de 24 horas com mais de 12 milhões de execuções contra o parser de arquivos GGUF não encontrou crashes nem carregamentos malformados bem-sucedidos — ou seja, essa camada específica se mostrou robusta no espaço de estados explorado. Já a memória de runtime conta uma história bem diferente: os pesquisadores conseguem recuperar prompts inteiros depois da inferência, porque múltiplas representações em texto puro do prompt sobrevivem em memória gerenciada pelo alocador, e mesmo quando existe sanitização, ela reduz o resíduo sem eliminá-lo por completo. Wrappers de consumo (as camadas de conveniência que muitos usuários instalam sobre o motor de inferência) também podem estender artificialmente o tempo de vida do prompt ao persistir cópias em texto plano em disco.
A descoberta mais grave, porém, está na interface de servimento: os autores encontram uma falha de autorização até então não documentada no llama.cpp que permite que um cliente autenticado restaure o estado de conversa salvo de outro tenant/usuário — ou seja, quebra completamente o isolamento entre diferentes sessões ou usuários de uma mesma instância de servimento. O ataque funcionou em 200 de 200 tentativas controladas, uma taxa de sucesso de 100% que indica um problema estrutural de controle de acesso, não uma condição de corrida rara. Separadamente, os pesquisadores também identificam que o cache compartilhado de prefixo de prompt (uma otimização comum para acelerar inferência repetida) expõe um oráculo de temporização remotamente distinguível mesmo sob condições de rede WAN, permitindo inferir informação sobre prompts de outros usuários pela diferença de latência de resposta.
O llama.cpp é uma das bases de inferência local mais usadas do ecossistema open-source, frequentemente embutida em produtos de terceiros que anunciam privacidade como diferencial justamente por rodarem localmente. Essa pesquisa mostra que essa promessa de privacidade não é automática: qualquer produto multiusuário ou multi-tenant construído sobre motores de inferência local precisa auditar explicitamente isolamento de sessão, tempo de vida de dados em memória e canais laterais de temporização, exatamente como faria para qualquer outro serviço multiusuário — a localidade da computação não substitui controles de acesso e isolamento adequados.