# Uploads de arquivos por agentes de IA precisam de limites rígidos

Um endpoint de upload é um canal de saída de dados, mesmo quando os engenheiros o chamam de recurso de anexos. Quando um agente de IA pode anexar um log, uma exportação, uma captura de tela ou um arquivo de cliente, uma instrução vaga como «envie isto ao suporte» pode se transformar em uma divulgação irreversível.

Uploads de arquivos por agentes de IA precisam de limites rígidos para bytes, conteúdo e receptores. Coloque esses limites na ação que faz o upload, não no prompt do agente e nem na capacidade de um revisor perceber um nome de arquivo inadequado no fim de um dia corrido.

## Uma ação de upload deve declarar o que pode sair

Um fluxo de upload seguro começa tratando cada arquivo como um objeto com uma finalidade declarada. A finalidade determina o tamanho máximo, os formatos aceitos, o receptor permitido, o prazo de retenção esperado e se uma pessoa precisa aprovar o envio. Se sua API aceita um corpo multipart arbitrário e uma URL fornecida pelo chamador, você criou uma rota genérica para exfiltração de dados com uma interface agradável para desenvolvedores.

A distinção que costuma ser ignorada é entre receber arquivos de um cliente não confiável e enviar arquivos em nome de um agente. As orientações tradicionais sobre upload se concentram em proteger o servidor contra arquivos maliciosos. Os uploads de agentes também precisam dessa proteção, mas o risco mais imediato é proteger os dados contra um envio amplo demais. Um PDF pode ser perfeitamente seguro para análise e totalmente inadequado para entrega a um sistema de tickets.

Defina finalidades de upload nomeadas em vez de uma ação genérica `upload_file`. Uma finalidade como `diagnostic_bundle` pode permitir um pacote de suporte compactado para um único receptor de suporte. Uma finalidade como `invoice_export` pode permitir um CSV para o receptor contábil. Nenhuma das duas deve aceitar um caminho, uma URL de receptor e um arquivo arbitrário na mesma solicitação.

Um contrato pequeno torna o limite visível:

```json
{
  "purpose": "diagnostic_bundle",
  "file_path": "/private/tmp/app-diagnostics-2025-03-08.zip",
  "destination_id": "support-case",
  "case_reference": "CASE-1842"
}
```

O chamador escolhe uma finalidade aprovada e fornece os metadados necessários para a ação de negócio. O serviço de upload associa `support-case` a um receptor sob seu controle. Ele não permite que o chamador substitua esse receptor por uma URL inserida em um comentário de issue, documento ou resposta de ferramenta.

Mantenha os caminhos de arquivos sob controle também. Um agente deve selecionar arquivos apenas de diretórios de preparação designados, ou o serviço deve criar o anexo a partir de entradas conhecidas. Permitir que um agente indique qualquer caminho legível transforma uma solicitação para anexar diagnósticos em uma solicitação para ler arquivos de configuração, material de SSH, dados do navegador ou a exportação de outro usuário.

## Os limites de tamanho precisam de duas medições

Um limite de arquivo deve rejeitar um corpo excessivo antes que o serviço o armazene, escaneie ou encaminhe. Aplique o limite na borda HTTP usando `Content-Length` quando ele estiver presente, mas conte os bytes durante a leitura, porque um cliente pode omitir ou mentir sobre esse cabeçalho.

O limite precisa ser adequado à finalidade. Um limite de 25 MB para um CSV de clientes e um limite de 25 MB para um pacote de diagnóstico compactado não são decisões equivalentes. O CSV pode se expandir e consumir uma alocação de memória muito maior quando um parser o lê. O arquivo compactado pode ser descomprimido para muitas vezes o seu tamanho durante o transporte. Defina um limite para o tamanho transmitido e outro para o tamanho processado.

Não permita que um agente divida um arquivo rejeitado em várias solicitações válidas, a menos que o receptor ofereça suporte explícito a uploads em partes e seu serviço acompanhe o total. Caso contrário, uma regra de 10 MB vira uma transferência de 100 partes sem nenhuma das proteções que você imaginava ter.

Rejeite cedo e devolva uma resposta que permita ao agente se recuperar com segurança:

```json
{
  "error": "attachment_too_large",
  "purpose": "diagnostic_bundle",
  "observed_bytes": 12582911,
  "max_bytes": 8388608,
  "safe_alternatives": [
    "create_redacted_diagnostic_bundle",
    "attach_selected_log_window"
  ]
}
```

Essa resposta importa. Se a rejeição disser apenas «falha no upload», o agente pode tentar outro destino, compactar o arquivo ou continuar repetindo a tentativa. Diga qual ação pode ser realizada em seguida, mas não exponha o arquivo rejeitado por meio de uma mensagem de depuração.

O armazenamento em buffer é outra falha silenciosa. Muitos frameworks analisam uma solicitação multipart na memória ou em um diretório temporário antes que o código da aplicação veja o tamanho. Configure o servidor web, o parser do framework, o proxy reverso e o leitor da aplicação para concordarem com um limite. O menor limite vence, mas uma camada inesperadamente maior ainda pode consumir espaço em disco antes que a camada menor rejeite a solicitação.

Meça o tamanho após o processamento para normalização de texto, conversão de imagens, extração de documentos e descompactação de arquivos. Um limite que cobre apenas o anexo original não controla o uso de recursos nem o potencial de divulgação do material que você gera depois.

## Um nome de arquivo e um cabeçalho MIME quase não provam nada

As verificações de tipo de arquivo precisam de evidências independentes, porque a extensão e o cabeçalho `Content-Type` vêm de quem envia. Um agente pode encaminhar um rótulo enganoso sem intenção maliciosa. Uma ferramenta de suporte pode chamar todos os anexos de `application/octet-stream`. Em qualquer caso, o receptor precisa decidir com base nos bytes e na estrutura permitida.

A lista de verificação de uploads de arquivos da OWASP recomenda permitir extensões por lista de permissões, não confiar no cabeçalho `Content-Type`, gerar nomes de arquivos no servidor e armazenar uploads fora da raiz pública da web. Essa orientação continua válida, mas os fluxos de agentes precisam de uma regra extra: validar o tipo de acordo com a finalidade nomeada antes que o serviço entre em contato com o receptor remoto. Um PDF válido não é automaticamente válido para qualquer finalidade de upload.

Use várias verificações, cada uma respondendo a uma pergunta diferente:

- A extensão informa o que o remetente afirma ter.
- Os bytes de assinatura indicam se o conteúdo começa como o formato declarado.
- Um parser limitado indica se os bytes atendem a uma parte suficiente do formato para serem tratados com segurança.
- A inspeção do conteúdo indica se o arquivo contém material proibido para aquela finalidade.

Para uma exportação CSV, aceite uma lista curta de permissões, como `.csv` e texto UTF-8, analise uma amostra limitada e rejeite dados binários incorporados ou linhas inesperadamente largas. Para um PDF, verifique a assinatura `%PDF-`, aplique um limite de tamanho e use um parser com limites de tempo e memória se precisar inspecionar as páginas. Para imagens, decodifique as dimensões antes do processamento. Uma imagem com tamanho de arquivo modesto ainda pode consumir memória demais quando decodificada.

Evite um tipo genérico «arquivo compactado». ZIP, TAR e GZIP são diferentes, e cada um exige seu próprio trabalho de inspeção. Se um processo de negócio não precisa de um arquivo compactado, recuse-o. Aceitar um formato porque os usuários às vezes o querem é como endpoints genéricos de anexos acabam sendo criados.

Renomeie os arquivos aceitos no lado do serviço. Preserve o nome original como metadado de exibição depois de sanitizá-lo, mas não o use como caminho do sistema de arquivos, chave de armazenamento de objetos ou valor de `Content-Disposition` sem aplicar escape. Os nomes podem conter caracteres de controle, Unicode enganoso, separadores de caminho e strings que alteram logs posteriores.

## As verificações de destino precisam sobreviver aos redirecionamentos

Uma lista de permissões de receptores deve identificar o local exato que pode receber o arquivo. Permitir `https://example.com` é incompleto se o cliente HTTP seguir redirecionamentos para outro host, resolver um endereço interno ou aceitar uma porta diferente.

Armazene os destinos como registros no servidor, com esquema, host, porta, prefixo de caminho, identidade da credencial e finalidades aceitas definidos. A ação recebe `destination_id`, nunca um endpoint livre. Se um receptor exige um ID de caso no caminho, construa-o a partir de um identificador restrito, em vez de receber uma URL completa do agente.

A cada envio, o cliente HTTP deve aplicar estas verificações:

1. Exija HTTPS, a menos que exista uma exceção interna documentada.
2. Compare o host e a porta solicitados com o registro do destino antes de conectar.
3. Desative redirecionamentos por padrão. Se um receptor precisar deles, valide cada destino de redirecionamento contra o mesmo registro antes de enviar outro byte.
4. Rejeite literais de IP, endereços de loopback, endereços link-local e faixas privadas, a menos que esse destino exista explicitamente para um serviço interno controlado.
5. Fixe o prefixo de caminho e o método HTTP permitidos, em vez de permitir um host inteiro.

O quarto ponto costuma ser descrito como proteção contra SSRF, e é isso mesmo. Ele também evita divulgações acidentais causadas por um agente que segue uma URL presente na descrição de uma tarefa. Um cliente de upload com acesso a redes internas nunca deve tratar o texto de uma tarefa como autoridade para entrar em contato com um endereço.

Não encaminhe o contexto de autorização original. A credencial usada para enviar dados a uma API de gerenciamento de casos deve pertencer apenas àquele receptor e àquela ação. Um gateway de upload que copia cabeçalhos arbitrários do agente cria um caminho mais fácil para injeção de cabeçalhos e permite que um agente selecione credenciais indiretamente.

Registre a URL final após os redirecionamentos, mas oculte os valores de consulta nos logs operacionais. Strings de consulta frequentemente carregam tokens de upload assinados. Registrar o destino é útil; reproduzir um token de autorização utilizável é descuidado.

## Os logs precisam de um caminho de exportação planejado

Logs são a classe de anexos que as equipes mais subestimam. Eles capturam cabeçalhos de solicitações, identificadores de clientes, trechos de SQL, rastreamentos de pilha, nomes de hosts internos e, às vezes, corpos completos de solicitações ou respostas. O fato de um log estar em um diretório de desenvolvimento não o torna seguro para envio por e-mail ou upload.

Não resolva isso com uma instrução que diga ao agente para «remover segredos». Agentes podem não reconhecer formatos, aplicar uma redação excessiva ou decidir que uma string suspeita é apenas contexto inofensivo. Crie um gerador de pacotes de diagnóstico que leia arquivos conhecidos, aplique filtros determinísticos e produza um novo artefato em um diretório de preparação.

Uma política prática de filtros pode remover campos inteiros, em vez de procurar todos os padrões possíveis de segredos. Remova `Authorization`, `Cookie`, `Set-Cookie`, campos de chaves de API, identificadores de sessão e corpos de solicitações por padrão. Substitua identificadores de clientes por tokens locais estáveis quando a correlação for importante. Limite os horários à janela do incidente, em vez de enviar semanas de histórico.

Por exemplo, este é um formato mais seguro para um registro de diagnóstico do que um rastreamento HTTP bruto:

```json
{
  "time": "2025-03-08T14:22:11Z",
  "request_id": "local-7f3c",
  "method": "POST",
  "route": "/v1/reports",
  "status": 502,
  "upstream": "reporting-service",
  "authorization": "[removed]",
  "body": "[omitted]"
}
```

O gerador do pacote deve produzir um manifesto com nomes de arquivos, contagens de bytes, hashes e filtros aplicados. Isso oferece ao revisor algo concreto para examinar sem abrir cada anexo. Também permite que o receptor identifique um upload truncado ou modificado.

As exportações de banco de dados precisam de uma regra mais rígida. Um agente não deve anexar uma exportação de produção apenas porque um ticket diz «envie uma amostra». Gere um artefato contendo apenas o esquema, uma consulta criada para esse fim com colunas aprovadas ou uma reprodução sintética. Se um incidente exigir registros reais de clientes, transforme isso em uma ação separada, com destino, escopo e aprovação humana explícitos.

Capturas de tela merecem a mesma desconfiança. Elas podem incluir contas de clientes, mensagens, abas do navegador, notificações e caminhos locais. Recorte ou gere uma captura focada por meio de uma ferramenta controlada, em vez de entregar ao agente um diretório amplo de capturas de tela.

## Arquivos compactados e documentos de escritório escondem mais de um arquivo

Um arquivo compactado cria um segundo conjunto de uploads dentro do primeiro. Antes de enviá-lo, inspecione a lista de membros e imponha limites para a quantidade de membros, bytes compactados, bytes expandidos, profundidade dos caminhos e aninhamento. Rejeite entradas que usem caminhos absolutos, travessia com `..`, nomes duplicados ou links simbólicos.

Um arquivo ZIP de 2 MB no disco pode se expandir até um tamanho capaz de esgotar um worker ou um receptor. Isso costuma ser chamado de bomba de descompressão, mas a falha não se limita a entradas maliciosas. Sistemas de build podem produzir arquivos compactados enormes por engano, e um agente pode anexar o primeiro arquivo que se pareça com uma exportação.

Documentos de escritório exigem cuidado semelhante. Formatos modernos de documentos costumam conter contêineres ZIP, mídia incorporada, metadados, comentários, alterações controladas e relações externas. Um documento pode parecer redigido na página e ainda conservar texto anterior ou informações do autor em seu pacote. Se o fluxo precisa apenas do conteúdo renderizado, produza um novo PDF a partir de dados aprovados, em vez de encaminhar o original editável.

Não tente «sanitizar» recursivamente documentos arbitrários no caminho da solicitação. Analisar e reescrever formatos complexos tem seus próprios custos de segurança e confiabilidade. Para um fluxo restrito, aceite um conjunto restrito de artefatos gerados. Para um documento excepcional, encaminhe-o a um processo de revisão humana capaz de inspecionar o arquivo real e seu destino.

## O contrato da ação deve tornar solicitações inseguras impossíveis

Uma ferramenta voltada para agentes deve oferecer escolhas que correspondam aos seus controles, não um construtor de solicitações HTTP brutas. Se a ferramenta oferece `url`, `headers`, `file_path` e `method`, a política já perdeu grande parte de sua forma.

Use um esquema de solicitação em que os campos não confiáveis descrevam a intenção, enquanto registros confiáveis forneçam a autoridade. Este exemplo mantém o destinatário, as credenciais e a classe de arquivo permitida fora do controle do agente:

```json
{
  "action": "send_attachment",
  "purpose": "customer_export",
  "destination_id": "finance-import",
  "artifact_id": "exp_8c4e1a",
  "note": "March reconciliation correction"
}
```

O serviço resolve `artifact_id` para um objeto preparado que ele próprio criou ou aceitou por meio de um fluxo de entrada separado. Ele calcula o digest e o tipo detectado por conta própria. Resolve `destination_id` para um registro de receptor fixo. Adiciona a credencial do destinatário no momento do envio. O agente nunca vê essa credencial e não pode substituir o receptor depois da aprovação.

O resultado da verificação prévia deve expor detalhes suficientes para uma decisão informada:

```json
{
  "decision": "approval_required",
  "artifact": {
    "name": "reconciliation-2025-03.csv",
    "bytes": 482913,
    "detected_type": "text/csv",
    "sha256": "a4d1...c09e"
  },
  "destination": {
    "label": "Finance import",
    "host": "imports.example.internal",
    "path": "/v2/reconciliation"
  },
  "reason": "customer_export requires approval"
}
```

Não mostre ao revisor apenas o nome do arquivo e um botão de aprovação. Mostre o tamanho medido, o tipo detectado, o host do destino, o rótulo do destino e a finalidade. Se o arquivo for sensível, mostre um resultado de classificação por amostragem ou um manifesto, não seu conteúdo completo na tela de aprovação.

Faça com que os IDs de artefatos tenham vida curta e uma única finalidade. Um pacote de diagnóstico preparado não deve continuar reutilizável como objeto genérico de upload depois que o caso de suporte for encerrado. Associe-o à finalidade e ao receptor quando o criar e faça-o expirar após uma janela operacional curta.

As novas tentativas precisam de idempotência. Falhas de rede são comuns, e agentes repetem solicitações agressivamente. Gere um token de idempotência na camada da ação, associe-o ao digest do artefato e ao destino e reutilize-o apenas para o mesmo envio pretendido. Não permita que uma nova tentativa com caminho ou digest alterado herde a autorização anterior.

## A aprovação humana funciona quando marca um limite real

A aprovação não substitui a validação. Uma pessoa não consegue identificar com segurança uma bomba de descompressão, um arquivo disfarçado ou uma falha de redirecionamento em uma janela modal. A aprovação serve para a decisão que a política não pode tomar automaticamente: se aquela exportação específica de cliente deve ir para aquele receptor específico por causa daquele incidente.

Use aprovação por chamada para envios de alta sensibilidade, novos receptores, exportações de produção e artefatos de diagnóstico amplos. Permita que artefatos rotineiros e restritos avancem sob uma finalidade aprovada quando o destino e o conteúdo estiverem limitados. Pedir que alguém aprove cada relatório de teste faz com que a pessoa clique sem ler.

O registro de aprovação deve estar associado ao digest do artefato, à finalidade declarada e ao registro do destino. Se qualquer um desses elementos mudar, descarte a aprovação. Um nome de arquivo não é suficiente, porque dois arquivos podem ter o mesmo nome e bytes diferentes.

O Sallyport pode manter o agente longe da credencial usada em um upload HTTP, e sua opção de aprovação por chave individual é adequada para envios que merecem uma decisão humana a cada uso. Isso não elimina a necessidade de um contrato de artefato no nível da aplicação, porque o gateway não consegue inferir se um CSV de clientes pertence a um caso de suporte.

Mantenha duas visões de auditoria: uma que informe qual execução do agente recebeu autoridade para agir e outra que registre cada tentativa e resultado de transferência. Um registro de auditoria deve incluir digest, bytes medidos, veredito do tipo, finalidade, registro do destinatário, decisão, status da resposta e horário. Armazene segredos e conteúdos completos dos arquivos em outro local, se decidir mantê-los.

## Teste os caminhos de rejeição antes que um agente os encontre

Uma política que só funciona no caminho feliz está incompleta. Crie um receptor isolado que registre a solicitação exata que recebeu e use fixtures que façam cada limite ser acionado.

Comece com uma solicitação de upload simples para seu receptor de testes:

```bash
curl -i -X POST https://receiver.test/attachments \\
  -H 'Authorization: Bearer test-token' \\
  -F 'file=@fixtures/diagnostic.zip;type=application/zip' \\
  -F 'case_reference=CASE-1842'
```

Um teste bem-sucedido deve confirmar o método, o host final, o caminho, o digest e o tamanho. Os testes úteis são os que provam que o receptor não recebeu nada. Verifique que um corpo acima do limite seja rejeitado antes do encaminhamento, que um cabeçalho `text/plain` falsificado não consiga passar uma carga binária e que um destino não listado nunca receba uma conexão.

Inclua estes casos no conjunto de fixtures de teste:

- Uma extensão válida com bytes de assinatura incompatíveis.
- Um arquivo compactado cujo tamanho expandido exceda a regra.
- Um redirecionamento de um host permitido para um host não permitido.
- Um fixture de log contendo um cabeçalho de autorização e um endereço de e-mail de cliente.
- Uma nova tentativa que use o mesmo token de idempotência com bytes de arquivo diferentes.

Inspecione os logs do servidor durante esses testes. Você está verificando duas coisas: que a transferência não aconteceu e que seus próprios logs não preservaram o corpo rejeitado, o token bearer ou a URL assinada. As equipes costumam corrigir o caminho de rede e deixar o mesmo material sensível nos rastreamentos de exceção.

Execute os testes pela mesma interface de ferramenta de agente usada pelos agentes de produção. Um cliente HTTP interno seguro não ajuda se o wrapper voltado para o agente puder selecionar uma URL bruta ou ignorar o caminho de preparação de artefatos.

## Torne o caminho seguro mais fácil que o caminho bruto

As equipes ignoram os controles de upload quando o caminho aprovado é lento, ambíguo ou não consegue lidar com o trabalho comum de suporte. Crie um pequeno conjunto de artefatos de que as pessoas realmente precisam: um pacote de diagnóstico redigido, uma exportação restrita, um relatório gerado e uma captura de incidente com limites definidos. Facilite para o agente solicitar cada um pelo nome.

Mantenha o uploader bruto genérico fora da lista de ferramentas do agente. Se um engenheiro precisar dele em um caso incomum, exija um caminho operacional interativo em que ele escolha o arquivo e o receptor com todo o contexto. Esse inconveniente é adequado, porque a ação não tem uma classificação automatizada confiável.

Analise os envios rejeitados com a mesma seriedade dos bem-sucedidos. Um padrão de pacotes grandes demais indica que seu artefato de diagnóstico está mal definido. Tentativas repetidas de enviar logs para um novo host podem significar que a lista de destinos precisa de uma adição justificada, ou podem indicar que um prompt de agente está tentando contornar seus controles. A diferença só aparece no registro se você capturar juntos a finalidade, o veredito do arquivo e a decisão do receptor.

A primeira mudança que eu faria é simples: remova URLs livres e caminhos de arquivos arbitrários da ação de upload do agente. Quando a ação aceita apenas artefatos preparados, finalidades nomeadas e IDs de destino, os limites de tamanho e as verificações de conteúdo passam a ter um lugar confiável para operar.
