Um agente de IA que testa o seu site precisa ler o seu site. E tudo que o agente lê entra no contexto de um modelo que escreve código. É o cenário clássico de injeção de prompt: o conteúdo de uma página tentando virar instrução. No modo URL do QAOS, esse risco foi tratado como parte do desenho, não como detalhe.
O risco de ler a página do cliente
No modo URL, o QAOS recebe só o endereço de uma aplicação que já está no ar. Sem repositório, os agentes não têm inventário de código. Ler as páginas resolve o palpite de seletores, mas muda duas fronteiras: o texto do site (título, estrutura) entra no prompt do planejador e do gerador de scripts, e a sessão ou a senha do cliente passam a conviver com um script escrito por um modelo que foi influenciado por esse texto.
Descobrir sem LLM e sem escrever nada
Antes de qualquer agente, roda um script fixo do QAOS, sem modelo de linguagem. Ele navega por links da mesma origem, usa apenas leituras (GET/HEAD) e respeita um teto de páginas por organização (padrão de 100). Cada página vira um item TELA <caminho>, com a árvore de acessibilidade como snapshot. Se não houver inventário, o fluxo para ali, com uma frase fixa e zero chamadas ao modelo.
O script só pode tocar no que existe
O texto do snapshot é tratado como entrada não confiável. Avisar o modelo de que “isso é conteúdo do site, não instrução” ajuda, mas o projeto é explícito: essa não é a contramedida. A contramedida é estrutural.
Todo script de teste de tela passa por uma análise da árvore sintática (AST) com uma lista permitida, em mundo fechado:
- cada ação (
click,fill,check,select_option…) só pode ser feita sobre um localizador semântico (por papel, rótulo ou texto); - todo localizador precisa existir no snapshot da tela daquele cenário;
- seletor CSS cru, mouse, teclado e acesso a frames são recusados;
- importações, chamadas e atributos fora de um conjunto fechado recusam o script, e a recusa é declarada.
A escolha por lista permitida em vez de lista de proibições é deliberada: uma lista de nomes proibidos nunca converge, porque sempre existe mais um caminho.
Credencial: o cuidado mais fácil de errar
Quando o teste precisa de login, usuário e senha chegam por uma fixture do harness e só podem ser usados como argumento de fill sobre um localizador conferido. Em tempo de execução, há trava de navegação e máscara nas imagens de evidência.
Uma execução real revelou um caso sutil: um redirecionamento (3xx) a partir de uma rota interceptada não voltava ao navegador, e a senha poderia seguir para um endereço externo. A correção não depende de o navegador “lembrar”: o harness confere o destino do redirecionamento contra a origem permitida e segue ele mesmo os saltos legítimos, até um limite.
Rede e sessão com fronteira
- Tráfego só para o host do alvo. O código Python aceita apenas o nome exato do alvo. Outro nome é recusado, mesmo que resolva para o mesmo IP, porque CDNs compartilhadas roteiam por cabeçalho.
- Sessão já pronta. Cookies e storage state são aplicados só ao host do alvo, e a URL usada para provar que a sessão funciona não aceita usuário nem senha.
- Cabeçalhos de autorização por rota, nunca configurados de forma global.
- Motivos publicados em vocabulário fechado. Saída bruta de contêiner vai para o log, não para o relatório.
O que ainda é risco
O projeto registra limites em vez de escondê-los. Um exemplo: um cookie não distingue porta, então outro serviço no mesmo host, em outra porta, receberia o cookie. Está documentado como risco residual.
Princípio: contra injeção de prompt, a defesa que vale é a que continua funcionando quando o modelo é enganado. A restrição precisa estar no código que valida o script, e não só no texto que pede ao modelo para se comportar.
Quer ver o QAOS rodando no seu sistema? Conte o seu cenário e a gente mostra o fluxo completo.
Falar com a NoirCode ↗