Em Produção · AI · Backend · Frontend

Prompt injection é o XSS da nossa geração

XSS e XSRF são a mesma falha: um sistema que não separa dado de instrução, ou que age com uma autoridade que ninguém pediu. Os LLMs herdaram as duas.

Por Publicado em 7 min de leitura1 figura interativa

Imagine uma aplicação web que guarda um JWT no localStorage, válido por duas horas. Uma das páginas tem um input, e o que você digita aparece para todo mundo que visitar depois. Um atacante digita um script ali. Daí em diante o navegador de cada visitante roda esse script e entrega o token, e o atacante pode usar a conta dessas pessoas por até duas horas.

A correção é quase sem graça: escrever o texto com textContent em vez de innerHTML, ou sanitizar antes de chegar ao DOM. O navegador tem um jeito confiável de dizer “isto é texto, não código”, e o buraco fecha.

O primo dele, o XSRF, é sobre outro erro. Cookies vão junto com qualquer requisição para um site, mesmo quando outro site a dispara, e até por um iframe invisível que faz você clicar em algo que nunca viu. O navegador age com uma autoridade que o usuário não deu naquele clique.

Agora olhe para um assistente com LLM. Ele lê texto de fora, tickets, e-mails, documentos, páginas web, e normalmente tem ferramentas: enviar e-mail, consultar dados, criar registros. Dado e instrução viajam no mesmo canal, e a autoridade vai junto sem ninguém pedir. É a mistura antiga, as duas falhas de uma vez.

Fig. 1 — Um assistente que resume ticketssimulação determinística · sem modelo real, sem e-mail real

Carregando a figura interativa…

Versão estática: sem defesas, o texto do ticket vira instrução e o assistente tenta chamar send_email; com a ferramenta fora da lista permitida, a chamada é bloqueada.

Sem defesa nenhuma, o ticket vira ordem. Cercar o texto não confiável ajuda até o atacante fechar a cerca ele mesmo; teste o terceiro exemplo. O que segura de verdade é tirar a ferramenta da tarefa. Resumir não precisa de send_email, e qualquer efeito colateral espera uma pessoa confirmar.

Nada com que escapar

O XSS foi resolvido porque o navegador consegue traçar uma linha firme em volta do texto. Um modelo não consegue. Você pode pedir, cercar, repetir e avisar, e ainda assim não existe escape garantido. Então a defesa precisa sair da entrada e ir para o privilégio. O que o modelo pode fazer importa mais do que o que ele leu.

Na minha demonstração de XSS, um token roubado durava duas horas. Para um agente com ferramentas, a janela é uma chamada. Trato tudo o que um modelo lê como não confiável, inclusive os nossos próprios documentos. Dou a cada tarefa o menor número de ferramentas de que ela precisa. E a saída do modelo é renderizada como texto, nunca jogada em innerHTML, SQL ou shell.