O registro passava recadinhos entre sandboxes
A Check Point publicou em 8 de setembro uma pesquisa mostrando que dois contêineres de execução de código do ChatGPT, rodando sob duas contas diferentes e sem nenhum caminho de rede entre eles, conseguiam passar dados um para o outro pela instância interna do JFrog Artifactory que lhes servia pacotes. Nada cedeu na porta da frente. A credencial de leitura que esses contêineres tinham também podia escrever, então um campo de metadados em um pacote armazenado funcionou como caixa de correio. O Bromure Agentic Coding não dá ao convidado conta alguma no espelho e permite que você escreva read-only em uma regra que o fio aplica.
O isolamento se manteve, os conectores se comportaram como documentado, e o serviço no meio havia sido instalado por segurança, para começo de conversa. O e-mail da vítima ainda assim chegou à conta de um estranho, por um campo de metadados em um pacote armazenado.
Em junho, pesquisadores da Check Point escreveram uma propriedade em um arquivo
dentro de um repositório de pacotes. A propriedade se chamava chatgpt_test_ts e
seu valor era um carimbo de tempo. Eles a escreveram de dentro do sandbox que
executa código para uma conversa do ChatGPT. Depois abriram uma conversa sob outra
conta, em seu próprio contêiner, e leram a mesma propriedade de volta. O valor
chegou intacto.
Esse carimbo de tempo é a descoberta inteira. A Check Point publicou o achado em 8 de setembro sob um título que vence qualquer resumo: The Shared Clipboard Inside the Sandbox. A OpenAI já havia desativado o serviço a essa altura. Os pesquisadores reportaram no fim de junho e ouviram que a instância interna do Artifactory tinha sido descomissionada, então não há correção a aplicar e nada a fazer do lado do usuário. A forma disso permanece.
O serviço no meio
Uma conversa do ChatGPT que executa código recebe seu próprio contêiner, isolado
dos contêineres de outras conversas. Essa parte funcionou. Um contêiner rodando
Python também precisa de pip install, e um time de plataforma cuidadoso não vai
deixar um sandbox alcançar pypi.org por conta própria. Então o sandbox ganha um
intermediário controlado: uma instância interna do
JFrog Artifactory que se posiciona diante dos
registros públicos e serve pacotes homologados para dentro.
Isso é bom projeto. Um banco coloca a mesma coisa diante do npm, e uma empresa de saúde regulada coloca diante do PyPI. O espelho existe para reduzir a exposição do sandbox, e é o que ele faz.
Ele também dá a cada contêiner uma conta no espelho.
A API REST do Artifactory inclui um grupo Item Management, acessível em
/api/storage/{repoKey}/{itemPath}, que permite a um cliente anexar propriedades
nomeadas de texto arbitrárias a um item armazenado e lê-las de volta: Set Item
Properties e Get Storage Item Information. Definir uma propriedade exige a
permissão Annotate. Ler uma, não. A Check Point descobriu que a credencial
emitida para os contêineres do sandbox, pensada como leitora, carregava as duas
coisas. Como
o Cybersecurity News resumiu,
“as credenciais de leitura entregues aos contêineres tinham permissão suficiente
para escrever e ler essas propriedades”, e “essas propriedades não eram isoladas
por conta”.
Valores de propriedade aceitam texto, ou Base64 para qualquer coisa binária, e uma carga grande demais para uma única propriedade se divide em várias e se remonta do outro lado. Dois contêineres pertencentes a clientes sem relação entre si, sem nenhum caminho de rede entre eles, passam a ter um canal bidirecional com um teto de banda que não vale a pena mencionar.
Duas conversas no mesmo turno
As instruções do atacante chegam à vítima por rotas comuns: um prompt colado, um link de conversa compartilhada, ou um GPT personalizado cujas instruções de construção o usuário não vê. A vítima então manda uma mensagem normal, e esse é o gatilho inteiro.
No modo Thinking, o modelo processou dois fluxos independentes de trabalho em um único turno. Na prova de conceito da Check Point, a vítima fazia uma pergunta de culinária e recebia uma resposta correta, enquanto ao lado dessa resposta o modelo lia a conta do Gmail conectada da vítima e escrevia o que encontrava em uma propriedade do Artifactory, para o contêiner do atacante recolher. Pedro Drimel Neto, que lidera o time de análise de malware da Check Point, disse ao The Register: “Uma instrução construída podia fazer o ChatGPT processar um segundo fluxo de tarefas ao lado da conversa visível.” O Gmail foi a demonstração. Google Drive, Microsoft Teams e GitHub estavam ao mesmo alcance.
A vítima viu um único sinal, um pequeno rótulo “Talked to Gmail”, e ele apareceu depois do fato. Os conectores vêm por padrão na configuração Important actions, que aprova leituras de baixo risco sem perguntar; a mais estrita Always ask teria produzido um aviso. Essa configuração classifica a leitura de e-mail como baixo risco sem perguntar quem a pediu.
A descrição que a Check Point faz do modelo: ele “pode, portanto, agir como um insider coagido: não malicioso, mas persuadido a agir em nome do atacante”.
A parte que se generaliza
Tire o ChatGPT da história e ela passa a ser sobre um agente de código, porque a estrutura é idêntica.
Um sandbox de agente tem de instalar pacotes. Deixá-lo alcançar os registros
públicos sem mediação é justamente o que você estava evitando, então você coloca
um espelho na frente: Artifactory, Nexus, um proxy npm privado, o que sua
organização padronizou. O sandbox agora se autentica nesse espelho, logo tem uma
credencial, e alguém decidiu o que essa credencial podia fazer muito antes de este
agente existir. Registros de pacotes aceitam uploads, tags, anotações e regras de
retenção, o que faz de Annotate uma permissão pequena assentada sobre uma
superfície ampla.
Pergunte, então, duas coisas à sua própria configuração, em vez de perguntar se o sandbox está isolado. Nomeie em que ele tem conta. Depois nomeie quais verbos funcionam nessa conta.
Dentro de um espaço de trabalho Bromure
O Bromure Agentic Coding executa cada agente de código em uma VM Linux virtualizada por hardware no seu Mac, e mantém os segredos reais do lado do host dessa linha. Passe os três ingredientes da Check Point por um espaço de trabalho.
Um serviço compartilhado. Não existe nenhum. Cada espaço de trabalho corresponde a uma VM, com seu próprio disco de sistema, sua própria imagem de home, seu próprio IP e seu próprio listener de proxy MITM no host. Dois espaços de trabalho não compartilham VM alguma, e a descrição que o manual dá de um par deles é que eles “nunca compartilham um byte”. Nenhum espelho de frota fica por baixo dos espaços de trabalho com um plano de metadados em que os dois possam escrever. O que fica por baixo de um espaço de trabalho é um processo no seu próprio Mac, um por espaço de trabalho.
Uma credencial no espelho. O agente não tem nenhuma. As instalações de pacotes
em um espaço de trabalho Bromure saem por um socket virtio até o proxy do host, e
é o proxy que fala com o registro. O Bromure mantém as chaves de API dos serviços
de reputação do lado do host e não as exporta para VM alguma. O caminho do Depi é
o caso mais nítido: o proxy anexa a sua chave de registro como cabeçalho
Authorization: Bearer no host e remove, de passagem, qualquer cabeçalho
Authorization que o convidado tenha enviado. Nenhuma credencial de leitura
existe no convidado, então nenhuma pode carregar um verbo a mais.
Um verbo de escrita que sobreviveu ao seu motivo. Aqui é você quem escreve a
restrição. O painel Guardrails de um espaço de trabalho carrega um firewall de
saída ordenado, e as regras para o protocolo web aceitam uma coluna Methods.
Sob allow, os métodos formam uma lista de permissão, e read-only é atalho para
GET, HEAD e OPTIONS. O manual diz por que a coluna existe: a dimensão do método “é
o que permite a um espaço de trabalho ler uma API que ele não tem permissão de
escrever”, no fio, independentemente de qual ferramenta dentro da VM faz a
requisição. Duas camadas aplicam isso. O switch de rede virtual compara cada fluxo
por IP de destino e por nome de host capturado do DNS, e o proxy compara de novo
por nome de servidor TLS e por método HTTP individual, de modo que um agente
comprometido não tem rota para contornar nem um nem outro. As edições alcançam
sessões em execução sem reboot, e cada veredito aparece como uma linha Firewall na
Security Timeline.
O segundo fluxo, e o caminho de volta para fora
O segundo fluxo de tarefas do atacante chegou como conteúdo que o modelo leu. Em
um espaço de trabalho Bromure, tudo o que um agente ingere e devolve em fluxo ao
modelo (conteúdo de arquivos, páginas web, saída de comandos, qualquer coisa que
uma ferramenta retorne) viaja como spans tool_result pelo mesmo proxy do host. O
detector de código-fonte pontua esses spans com um classificador PromptGuard local
antes de o modelo agir sobre eles, e então registra o acerto, pausa para a sua
decisão, ou bloqueia a requisição. O detector vem desligado e baixa um modelo de
298 MB na primeira vez que você o habilita, então habilite-o antes da sessão em
que vai precisar dele.
A leitura de conector não aprovada tem aqui o seu inverso. Os tokens bearer de MCP
de um espaço de trabalho Bromure aparecem dentro da VM como marcadores
brm-mcp_. O token real fica fora do convidado, e o proxy o substitui no fio em
direção ao único host para o qual aquele token foi emitido. Ligue Ask before
use para uma credencial e o primeiro uso dela em uma sessão pausa para um
diálogo do lado do host oferecendo uma concessão de 5 minutos, de 1 hora ou pelo
resto da sessão. É o aviso que “Important actions” se recusou a mostrar, por
credencial, na máquina em que você está sentado.
Se algo na VM levar um marcador para onde ele não pertence, o proxy recusa a
requisição sem encaminhar um byte, pausa a VM e levanta um alerta nomeando a
prévia do token, a credencial, o host para o qual ele foi emitido e o host para o
qual estava indo. Sob esse fio de armadilha, o tracing em Activity only
escreve uma linha de metadados por requisição: host, método, caminho, status,
bytes, quais credenciais o proxy trocou, e um aviso de vazamento para qualquer
token no estilo bearer que o Bromure não tenha emitido. Rode
bromure-cli trace hostnames depois de uma sessão e cada host distinto que o
agente contatou é impresso com uma contagem.
Se você opera um espelho para seus agentes
Verifique a identidade com que seus sandboxes se autenticam, antes do caminho
de rede entre eles. No Artifactory, procure Annotate em um token que você
considera leitor, e um alvo de permissão mais amplo que os repositórios de que
o sandbox instala. A API de propriedades é um plano de metadados gravável; as
regras de retenção, as tags e as informações de build são outros. Um leitor que
pode anotar pode postar.
A regra que responde isso em uma linha
No painel Guardrails do espaço de trabalho, adicione uma regra de saída
para o registro com o protocolo web e read-only na coluna Methods, depois
ponha Unmatched traffic em Deny e liste o que o trabalho precisa. A
exibição em formato pf no rodapé do painel imprime o que você construiu:
allow web registry.npmjs.org read-only, allow web api.github.com,
default deny. Vale para sessões em execução sem reiniciar.
Um serviço compartilhado transforma inquilinos em vizinhos
O instinto depois de uma história como esta é conferir as paredes. As paredes estavam bem. Dois contêineres sob duas contas não tinham rota um para o outro, e a Check Point não encontrou nenhuma. Encontraram um terceiro com quem os dois contêineres tinham direito de falar, e o usaram do jeito que as pessoas usam discos compartilhados e registros DNS TXT há trinta anos.
A Check Point enuncia a lição no relatório: “um serviço interno compartilhado, pensado puramente como infraestrutura, pode se tornar uma camada de comunicação não intencional entre ambientes que deveriam permanecer isolados”. A infraestrutura que você instala por segurança continua sendo infraestrutura, e seus inquilinos ficam a um salto de distância. Encolha o conjunto de coisas em que um sandbox tem conta, e mova a decisão sobre o que essas contas podem fazer para cada requisição, tirando-a de um ticket de provisionamento que alguém fechou dois anos atrás.
Um sandbox de agente que valha a pena rodar terá um caminho controlado até os pacotes de que precisa, porque a alternativa é pior. Trate esse caminho como uma relação com permissões anexadas, e trate essas permissões como o seu perímetro. Decida-as em algum lugar onde você ainda consiga vê-las. Instale o Bromure Agentic Coding e não dê ao seu agente nada com que fazer login.