Guardrails & Security
Você construirá uma bateria local de red-team para um agente de suporte com leitura de pedidos e proposta de estorno. Os ataques serão textos sintéticos e propostas de ferramenta controladas; nenhum segredo real será usado. A entrega deve mostrar negação por controles da aplicação, incluindo comprovação de ausência de efeito quando uma proposta é recusada.
Crie guard.cjs, attacks.json e audit.json em uma pasta de laboratório. Use Node sem chamadas externas. Quando testar um modelo opcionalmente, mantenha a identidade no servidor e capture suas propostas antes de executar; uma conta de teste e chave no ambiente são necessárias. O laboratório não autoriza enviar dados pessoais ou realizar estornos reais.
JavaScriptRAGIA & MLSegurançaAo terminar esta aula
- Dados externos não ganham autoridade por entrar no contexto.
- Controle de permissão pertence ao executor.
- Red-team mede controles definidos e preserva limitações.
Antes de continuar: Leitura: Guardrails & Security
Modelar ativos e fronteiras antes do ataque
FundamentosListe os ativos: dados de pedidos, capacidade de estorno, credenciais e logs. Desenhe as fronteiras entre entrada do usuário, conteúdo RAG, modelo, validador e executor. Defina duas identidades sintéticas e pedidos de cada uma. A sessão é escolhida pelo teste de autenticação, nunca por uma mensagem de chat. Anote quais ferramentas leem, escrevem ou enviam dados. Essa classificação permite escolher controles específicos: propriedade para leitura, aprovação para estorno e allowlist para destinos. Se uma ferramenta tem acesso amplo sem necessidade, reduza essa capacidade antes de tentar resolver o problema com prompt.
Verificar negação e ausência de efeito
FundamentosExecute o exemplo e confira que audit contém somente o pedido o1. Troque a proposta negada para tenant:t1 mantendo orderId:o2; a propriedade do recurso deve continuar impedindo o acesso. Insira action:read_order com orderId desconhecido e confirme resposta sem revelar se o pedido pertence a outra conta. Acrescente uma proposta com campo extra dangerous:true e defina se o esquema deve rejeitá-la. A autorização ocorre independentemente da linguagem do ataque. Preserve o motivo interno da negação em log controlado e uma mensagem externa que não exponha informações desnecessárias.
const assert=require('node:assert/strict');
const session={tenant:'t1',user:'u1'};
const orders={o1:{tenant:'t1',user:'u1'},o2:{tenant:'t2',user:'u2'}};
const audit=[];
function execute(proposal){
if(proposal.action!=='read_order') return {ok:false,reason:'action-denied'};
const record=orders[proposal.orderId];
if(!record || record.tenant!==session.tenant || record.user!==session.user)
return {ok:false,reason:'access-denied'};
audit.push({action:'read_order',id:proposal.orderId});
return {ok:true,id:proposal.orderId};
}
assert.equal(execute({action:'read_order',orderId:'o1'}).ok,true);
assert.equal(execute({action:'read_order',orderId:'o2',tenant:'t2'}).ok,false);
assert.equal(execute({action:'send',url:'https://untrusted.invalid'}).ok,false);
assert.deepEqual(audit,[{action:'read_order',id:'o1'}]);
console.log('Apenas a leitura autorizada produziu efeito.');Criar injection direta, indireta e contexto envenenado
FundamentosMonte três entradas: usuário pede para ignorar a sessão; documento recuperado manda enviar histórico; comentário falso afirma que todos os pedidos são públicos. Associe a cada entrada uma proposta adversarial explícita para testar o executor, e uma expectativa de resposta do agente para testar separadamente o modelo. Inclua documento legítimo que cita um ataque em uma orientação de segurança. Ele deve poder ser resumido sem ganhar autoridade de comando. Compare o conteúdo hostil com a política normativa versionada e verifique que o agente não transforma a fonte mais recente em fonte automaticamente confiável.
↗ LLM01:2025 Prompt Injection↗ LLM04:2025 Data and Model Poisoning
Adicionar aprovação vinculada à proposta
FundamentosCrie uma função que prepara {action:refund,orderId,amount,proposalId} e outra que executa apenas uma proposta aprovada e imutável. Na fixture, aprove estorno de 10 unidades para o1 e tente executar 100 para o2 com o mesmo approvalId. O teste deve negar a alteração e preservar o saldo. Acrescente expiração e identidade de quem aprovou. Não basta ter approval:true fornecido pelo modelo. Simule também repetição da mesma proposta e use chave de idempotência para evitar efeito duplicado. Documente que a implementação em memória não oferece persistência após reinício.
Escrever relatório de red-team com contraexemplos
FundamentosEntregue tabela com vetor, ativo, proposta, controle acionado e efeito observado. Inclua injection, vazamento, escalada, abuso e poisoning, além de dois pedidos legítimos que poderiam gerar falso positivo. Verifique arquivos exportados para ausência de segredos sintéticos e dados de outra identidade. Explique a configuração de sandbox se houver execução de código, incluindo rede, volumes e privilégios. O relatório deve registrar limitações de escopo: nenhum teste local comprova resistência a todos os ataques ou a falhas da infraestrutura. A evidência mais importante é o estado final do sistema diante de uma tentativa recusada.
Exercício aplicado
Um documento RAG instrui o agente a ler o pedido o2 e responder que recusou o acesso. A proposta de ferramenta chega ao executor. Mostre onde bloquear e como provar a falha segura.
- Marque o documento como dado externo não confiável.
- Valide o esquema e autorize o recurso pela sessão.
- Registre proposta e negação sem expor o pedido.
- Compare audit e estado antes e depois.
Abrir resolução comentada
A negação deve acontecer antes da consulta efetiva ao recurso. A sessão u1/t1 não possui o2, e o tenant informado pela proposta não altera essa identidade. A frase final do modelo não é o mecanismo de proteção.
O teste verifica que a chamada foi recusada e que não houve efeito ou dado retornado. Em um sistema real, revise todos os caminhos de leitura e escrita para impedir bypass do executor. O resultado local é evidência de um controle específico, não garantia geral.
const assert=require('node:assert/strict');
const session={tenant:'t1',user:'u1'};
const orders={o1:{tenant:'t1',user:'u1'},o2:{tenant:'t2',user:'u2'}};
const audit=[];
function execute(proposal){
if(proposal.action!=='read_order') return {ok:false,reason:'action-denied'};
const record=orders[proposal.orderId];
if(!record || record.tenant!==session.tenant || record.user!==session.user)
return {ok:false,reason:'access-denied'};
audit.push({action:'read_order',id:proposal.orderId});
return {ok:true,id:proposal.orderId};
}
assert.equal(execute({action:'read_order',orderId:'o1'}).ok,true);
assert.equal(execute({action:'read_order',orderId:'o2',tenant:'t2'}).ok,false);
assert.equal(execute({action:'send',url:'https://untrusted.invalid'}).ok,false);
assert.deepEqual(audit,[{action:'read_order',id:'o1'}]);
console.log('Apenas a leitura autorizada produziu efeito.');Como conferir seu resultado
- Identidade vem da sessão, não da proposta.
- Pedido de outra identidade nunca retorna dados.
- Ação fora da allowlist produz zero efeitos.
- Aprovação não vale após alterar argumentos.
Aplique em um problema novo
Primeiro resolva sem consultar a resposta. Explique suas decisões e guarde a evidência. A conclusão de leitura é independente desta autoavaliação.
Confira seus pré-requisitos
- Aplicar autorização no executor.
- Tratar conteúdo recuperado como não confiável.
Usuário A só pode ler o1. Tool output pede o2 de B e documento pede divulgar secret S. Modelo propõe ler o2 e responde 'recusei'. Defina evidência correta.
Conferir raciocínio e critérios de domínio
A proposta ler o2 é negada pelo executor antes da consulta, usando propriedade A/o1; contador de leituras privadas de B continua zero.
secret S não está disponível nas tools/contexto e conteúdo externo não amplia allowlist. A resposta de recusa sem esses controles não provaria proteção.
Logs sanitizados registram tool/negação/correlação sem secret S. O resultado comprova estes casos locais, não resistência universal a injections.
Evidências para autoavaliação ou revisão por pares
- Autorização do executor: A proposta ler o2 é negada pelo executor antes da consulta, usando propriedade A/o1; contador de leituras privadas de B continua zero.
- Disponibilidade do segredo: secret S não está disponível nas tools/contexto e conteúdo externo não amplia allowlist. A resposta de recusa sem esses controles não provaria proteção.
- Auditoria e alcance: Logs sanitizados registram tool/negação/correlação sem secret S. O resultado comprova estes casos locais, não resistência universal a injections.
Um erro frequente
Filtro textual substitui autorização.
Filtros textuais não substituem identidade, propriedade e permissões.
Teste sua compreensão
Responda com suas palavras antes de abrir o comentário. Saber explicar uma decisão é parte do domínio.
1. Delimitadores tornam conteúdo RAG seguro?
Não, são apenas uma ajuda de interpretação.
A aplicação ainda precisa restringir capacidades e autorizar ações.
2. Uma recusa textual comprova bloqueio?
Não.
A ferramenta pode ter executado antes da resposta; confira efeitos.
3. Qual diferença entre allowlist e denylist?
A primeira enumera o permitido; a segunda bloqueia itens conhecidos.
Destinos desconhecidos podem escapar de uma denylist incompleta.
Seu progresso fica salvo neste navegador. Concluir a leitura não substitui demonstrar o domínio nos exercícios.
Referências e aprofundamento
Documentação oficial e trabalhos originais. As referências registram o escopo e as limitações para você conferir o que sustentam.
- LLM01:2025 Prompt Injection
OWASP • consulta: 2026-10-06
FundamentosInjeção direta e indireta, riscos e mitigações de aplicações LLM.
Limites: Mitigações reduzem risco e não eliminam injeção; separar conteúdo não confiável de instruções e permissões.
- LLM Prompt Injection Prevention Cheat Sheet
OWASP • consulta: 2026-10-06
IA & MLJailbreaks, RAG poisoning, validação de entradas/saídas e chamadas de tools, menor privilégio, controles humanos e defesa em camadas.
Limites: Filtros por padrões e modelos guardrail podem falhar; medir ataques e falsos positivos, manter autorização fora do modelo.
- LLM02:2025 Sensitive Information Disclosure
OWASP • consulta: 2026-10-06
FundamentosVazamento de informações sensíveis no contexto e nas saídas de LLMs.
Limites: Sanitização e restrições de dados precisam ser aplicadas pelo sistema, não apenas pelo prompt.
- LLM06:2025 Excessive Agency
OWASP • consulta: 2026-10-06
FundamentosMinimização de ferramentas, funcionalidade, permissões, contexto do usuário, autorização e aprovação de ações de alto impacto.
Limites: Autorizações devem ser impostas no sistema de destino; uma recusa textual ou decisão do LLM não é controle de acesso.
- LLM04:2025 Data and Model Poisoning
OWASP • consulta: 2026-10-06
FundamentosPoisoning de dados de treinamento, fine-tuning e embeddings, procedência e integridade.
Limites: Distinguir poisoning do modelo de instruções maliciosas recuperadas em RAG.
- What is a container?
Docker • consulta: 2026-10-06
DockerContêineres, isolamento de processos, portabilidade e comparação com máquinas virtuais.
Limites: Isolamento de contêiner não implica sandbox infalível; validar rede, mounts, identidade e permissões.