Segurança · Engenharia de IA · Cadeia de Suprimentos
Prompt injection faz sua IA recusar — de propósito
Prompt injection quase sempre nega uma resposta ao seu time, não seus dados. Um script em produção esconde 1.275 caracteres invisíveis.

O uso mais comum de prompt injection no mundo real não é roubar seus dados. É fazer sua IA dizer não.
Se o seu time integra script antifraude ou anti-bot de terceiros — e em fintech e e-commerce brasileiros isso é regra, não exceção — você já viveu a cena. Você cola o JavaScript minificado do fornecedor no assistente e pergunta o que aquele arquivo faz. O modelo enrola, menciona alguma coisa sobre conteúdo perigoso, e não entrega nada. Você dá de ombros, supõe que a ferramenta está sendo frouxa com código ofuscado, e vai ler o arquivo na mão.
Esse dar de ombros é o ataque funcionando. Um script de detecção de bot servido a usuários reais agora mesmo carrega 1.275 caracteres Unicode invisíveis, num único bloco contíguo, a 0,39% do começo do arquivo. Decodificados, formam um system prompt falso exigindo guias passo a passo sobre armas biológicas, evasão fiscal e dosagem de entorpecentes. Nada ali foi escrito para ser respondido. Foi escrito para ser recusado.
A recusa é o produto
Esta é a parte que todo mundo reproduziu e ninguém leu com atenção. No print do próprio pesquisador, o modelo não caiu no golpe. Ele avisou, em texto claro, que manteria o texto dirigido à IA e os nomes-isca fora da análise. Rodou seis comandos. Terminou o trabalho. Aí o filtro de saída trocou a resposta pronta por "This content can't be shown. We take extra caution with requests involving biological research."

A análise terminou. O filtro comeu o resultado. Fonte: nullpt.rs.
O modelo fez o trabalho certo e a camada de segurança suprimiu o resultado. Isso é um ataque diferente de jailbreak, e é o que funciona contra um modelo cuidadoso: você nunca precisa enganar o assistente, basta contaminar o assunto até o filtro disparar.
Agora coloque preço nisso. Se qualquer etapa de como vocês entregam software assume que um modelo consegue ler código que vocês não escreveram — revisão de dependência, auditoria de segurança antes de um aporte ou de uma aquisição, resposta a incidente em cima de um bundle minificado às duas da manhã, migração de um SDK legado — essa suposição passa a ter um modo de falha adversarial sem nenhum alarme junto. Uma recusa é indistinguível de "o modelo não é bom nisso". Sem exceção, sem 500, sem linha em log. O engenheiro dá de ombros, a hora vai para outro lugar, e no seu plano continua parecendo que o trabalho foi feito.
Dois dos custos caem no colo de quem não escreve código. O primeiro é risco de estimativa: "revisamos o bundle do fornecedor com IA" é cobertura que você já contabilizou e talvez não tenha. O segundo é cobertura de auditoria: se alguém perguntar como o código de terceiro foi revisado e a resposta honesta for "o modelo recusou e a gente seguiu", isso é lacuna, não controle.
O que verificamos e o que estamos aceitando sob palavra
A história tem duas metades e elas não têm a mesma força.
Baixamos o script nós mesmos em 29 de outubro de 2026: HTTP 200, 420.741 bytes, last-modified: Mon, 26 Oct 2026 19:06:57 GMT — atualizado dois dias antes da divulgação e ainda servido sem alteração depois dela. Contamos os caracteres escondidos (1.275, dos quais 1.002 ficam no bloco Unicode Tags propriamente dito). Decodificamos e recuperamos o payload inteiro, incluindo nove linhas de gatilho político em chinês que somem do bloco de código renderizado do pesquisador por falta de glifo. Conferimos um a um os seis nomes de função usados como isca de recusa: só dois aparecem em texto puro no build servido hoje, então a lista publicada cobre mais de um build ou mais de um arquivo. Tudo isso nós conseguimos mostrar.
O que não confirmamos: quais modelos recusaram e quais obedeceram (teste de um pesquisador, não reproduzido por nós), os números do crawl que originou a descoberta, e o vínculo de propriedade entre o domínio que serve o script e uma empresa russa de anti-DDoS, que se apoia numa única consulta. E o mais importante: a intenção é inferência. O pesquisador levanta o ponto como pergunta — seria isso ofuscação anti-LLM? — e nenhuma declaração do fornecedor confirma. A ServicePipe não se manifestou publicamente.
Leia a tese nesse registro. O mecanismo está verificado e o efeito é reproduzível; a intenção é a leitura mais razoável da evidência, não um achado. O argumento não depende dela. O arquivo se comporta assim independentemente de alguém ter querido, e seu pipeline tem que sobreviver aos dois casos.
Como 1.275 caracteres invisíveis chegam na janela de contexto
A codificação não tem nada de exótico. Cada caractere do payload é texto comum deslocado em 0xE0000, o que joga ASCII imprimível dentro do bloco Unicode Tags — uma faixa depreciada que o aviso de segurança da Microsoft de setembro de 2026 descreve como "uma cópia sombra dos caracteres ASCII imprimíveis", em que U+E0041 espelha A e U+E0061 espelha a.

Cada quadradinho é um caractere de instrução endereçado à sua IA, não a você.
A fonte não tem glifo para essa faixa, então o renderizador mostra nada ou quadradinhos vazios. O diff não mostra nada. O revisor não vê nada. grep -c 'SYSTEM OVERRIDE' no arquivo ao vivo retorna zero, e o grep pelo nome da variável também. Mas tokenizador não consulta fonte. Para o modelo, é texto.

Os mesmos bytes, decodificados. Nada ali foi feito para ser respondido — só recusado.
A metade visível da técnica é mais grosseira e funciona igual: funções batizadas para que qualquer modelo que leia o arquivo corra para a recusa. Esta está em texto puro no build servido hoje, e não calcula nada parecido com isso. O nome é o payload inteiro.

Uma função num script de detecção de bot em produção, batizada só para que sua IA não leia o arquivo.
A posição é o detalhe operacional. O bloco começa no byte 1.635 de 420.741. Qualquer coisa que leia os primeiros 2 KB desse arquivo já ingeriu o payload inteiro.
Negar é o caso comum, não o exótico

Mais de um terço das injeções reais só quer que a resposta do seu agente não sirva para nada. Fonte: Palo Alto Unit 42, março de 2026.
A telemetria da Unit 42 (Palo Alto) de março de 2026 sobre prompt injection indireta via web classifica as intenções observadas pelo que o atacante queria conseguir. A maior categoria isolada é "irrelevant-output", de baixa severidade, com 28,6%; "ai-access-restriction" soma outros 8,1%. Juntas, mais de um terço das injeções reais não quer nada do seu agente além de que a resposta dele não preste. Destruição de dados é 14,2%. Transação não autorizada, 6,2%.
Esse ranking é exatamente o que a maioria dos programas de segurança tem de cabeça para baixo. Exfiltração leva o orçamento; degradação é o que aparece.
O que decidir nesta semana
Três coisas, e só a primeira é trabalho de engenharia. Aplicamos as três nas auditorias que fazemos ao levar software feito com IA para produção.
- Canonicalize na fronteira de ingestão, não no prompt. Remova ou rejeite codepoints em U+E0000–U+E007F, e nos planos não atribuídos acima, em tudo que chega ao modelo de fora: páginas baixadas, código de dependência, tickets de suporte, documentos enviados. Isso é lugar de pipeline, onde vira um filtro que você consegue testar, e não de system prompt pedindo que o modelo tome cuidado. É a mesma fronteira que desenhamos em contendo código escrito por IA.
- Conte suas recusas. Taxa de recusa é telemetria. Se seus agentes se negam a trabalhar, alguém precisa saber com que frequência e em quais entradas, do mesmo jeito que você notaria 5xx subindo. A maioria dos times joga esse sinal fora como ruído — que é justamente a propriedade de que esse ataque depende. Batemos no mesmo ponto cego pelo outro lado em quando um agente de IA fica em silêncio.
- Pare de contabilizar "revisamos com IA" como cobertura em código que você não escreveu enquanto não souber o que o modelo recebeu de fato — não o que você colou, mas o que chegou depois da canonicalização, com a contagem do que foi removido.
Principais pontos
- A intenção mais comum observada em prompt injection real é degradar a saída do agente (28,6% de irrelevant-output mais 8,1% de restrição de acesso na telemetria da Unit 42), não roubar dados.
- Um script de detecção de bot em produção carrega 1.275 caracteres Unicode invisíveis, a 0,39% do início do arquivo, que decodificam para um "SYSTEM OVERRIDE" falso com lista de tópicos proibidos. Verificamos o arquivo, a contagem e a decodificação; a finalidade é inferência e o fornecedor não se manifestou.
- O payload é invisível para renderizador, diff, code review e grep, e continua sendo texto comum para o tokenizador.
- O modo de falha é recusa depois de uma análise correta — o filtro de saída suprimindo um resultado pronto — e não jailbreak. Não gera código de erro nem alarme.
- Corrija na fronteira de ingestão, conte recusas como telemetria, e não contabilize revisão por IA como cobertura de auditoria em código de terceiro.