8 min de leitura

Confusão de tipo de conteúdo em chamadas autenticadas de APIs de agentes

A confusão de tipo de conteúdo pode permitir que chamadas autenticadas de agentes contornem a intenção. Teste JSON, formulários, multipart e corpos vazios contra um único esquema.

Confusão de tipo de conteúdo em chamadas autenticadas de APIs de agentes

Chamadas autenticadas de agentes precisam ter uma única interpretação, da borda da rede até o handler da ação. Se o gateway vê uma solicitação JSON inofensiva, a camada de autorização enxerga um conjunto de campos e o handler recebe um envio de formulário privilegiado, a credencial cumpriu seu papel e a API ainda assim falhou.

Essa não é uma preocupação restrita a formulários antigos de navegador. Agentes geram HTTP diretamente, repetem solicitações de forma agressiva, reutilizam exemplos das descrições de ferramentas e muitas vezes operam com credenciais capazes de alterar sistemas reais. O corpo da solicitação faz parte da decisão de autorização sempre que seleciona um destino, valor, ambiente, comando ou permissão. Antes de decidir se o chamador pode agir, você precisa tornar inequívocos o tipo de mídia, a sintaxe e o esquema desse corpo.

Uma solicitação autenticada ainda precisa significar uma única coisa

A autenticação responde quem apresentou uma credencial. A autorização responde se esse chamador pode executar uma ação. Nenhuma das duas respostas informa se todos os componentes concordaram com os argumentos da ação.

Considere um endpoint que altera o destino de uma implantação:

POST /v1/deployments/promote HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json

{"environment":"staging","release":"2026.07.22"}

O código de autorização pode permitir a promoção para staging, mas negar a produção. Esse código só é confiável se receber o mesmo valor de environment usado pelo handler da ação. Se uma camada de middleware ler JSON, um handler consultar depois parâmetros de formulário e ambos puderem preencher o mesmo objeto de solicitação, você criou duas fontes de verdade.

A falha não exige um token criptográfico quebrado. Um agente com uma sessão legítima pode enviar um corpo que uma camada ignora e outra considera válido. Um agente comprometido pode fazer o mesmo. O resultado é um bypass de autorização expresso como formatação de entrada.

A RFC 9110 diz que Content-Type indica o tipo de mídia da representação associada e define tanto o formato dos dados quanto a forma como o destinatário deve processá-los. Isso torna o cabeçalho parte da semântica da solicitação, não um detalhe decorativo. A mesma RFC também permite que um destinatário sem Content-Type assuma octet-stream ou inspecione os dados. Isso é útil para o tratamento genérico de arquivos, mas é um padrão ruim para APIs de ações protegidas.

Para um endpoint de ação, estabeleça esta invariante:

Exatamente um tipo de mídia aceito transforma os bytes da solicitação em exatamente um objeto de comando validado. Toda decisão de segurança e todo efeito colateral usam esse objeto.

O endpoint pode aceitar mais de uma representação, mas cada representação precisa de seu próprio contrato e conjunto de testes. Não trate vários analisadores como conveniências intercambiáveis.

Um cabeçalho Content-Type não é um esquema

Content-Type: application/json não significa «este é o formato de solicitação que eu esperava». Significa que o remetente declara que o corpo usa um tipo de mídia JSON. Ainda é preciso decidir se esse tipo é aceito pela rota, se parâmetros são permitidos, se o corpo é sintaticamente válido e se o valor decodificado corresponde ao contrato da operação.

Um endpoint protegido deve manter deliberadamente pequeno o conjunto de representações permitidas. Muitos endpoints de comando deveriam aceitar apenas JSON. Um endpoint de upload pode aceitar apenas multipart. Uma ação sem argumentos não deveria aceitar corpo algum. Quanto maior o conjunto aceito, mais caminhos de análise você terá de manter.

A recomendação prática do OWASP REST Security Cheat Sheet é direta: documente os tipos de conteúdo aceitos e rejeite tipos inesperados ou ausentes, permitindo um Content-Type omitido quando a solicitação tiver comprimento zero. O documento também alerta que o corpo e o tipo declarado precisam corresponder, para evitar interpretações diferentes entre produtor e consumidor.

Essa orientação precisa de uma ressalva para ações autenticadas. Não «combine» um tipo declarado examinando o primeiro caractere e escolhendo um analisador. Um corpo que começa com { não autoriza tratar como JSON uma solicitação declarada como dados de formulário. A inspeção por conteúdo transforma um contrato claro em um palpite de implementação.

Um contrato útil de rotas se parece com este:

RotaTipo de mídia permitidoRegra do corpo
POST /v1/deployments/promoteapplication/jsonObjeto JSON obrigatório que corresponde a PromoteRequest
POST /v1/artifactsmultipart/form-dataPartes obrigatórias que correspondem a ArtifactUpload
POST /v1/sessions/revokenenhumDeve conter zero bytes

Seja preciso com os parâmetros do tipo de mídia. Se o analisador JSON aceitar application/json; charset=utf-8, documente isso e normalize os parâmetros por meio de uma única biblioteca. Se aceitar apenas application/json sem parâmetros, rejeite o parâmetro, em vez de permitir que o proxy e a aplicação tenham comportamentos diferentes. A escolha importa menos do que aplicá-la uma única vez.

Também separe a preferência de resposta Accept do Content-Type da solicitação. Um cliente pode pedir uma resposta JSON enquanto envia um corpo inválido. Nunca deixe o cabeçalho Accept ampliar os formatos de solicitação que um endpoint de ação pode analisar.

JSON precisa de regras além da sintaxe válida

Um analisador JSON pode processar com sucesso uma entrada que sua API ainda precisa rejeitar. Nomes de membros duplicados são o exemplo mais evidente:

{"environment":"staging","environment":"production","release":"2026.07.22"}

A RFC 8259 diz que os nomes dos objetos devem ser únicos e explica o motivo: os destinatários não concordam sobre como tratar nomes duplicados. Muitos mantêm o último valor, alguns falham e outros expõem todos os pares. Esse é um problema documentado de interoperabilidade, não uma preferência de estilo teórica.

Suponha que um middleware de autorização use um analisador que mantém o primeiro valor de environment, enquanto um decodificador posterior mantém o último. O middleware aprova staging e o handler promove production. Não é possível corrigir isso com nomes de funções melhores ou outra declaração no token. Rejeite a solicitação antes que qualquer componente tome uma decisão.

Faça o mesmo para valores que parecem inofensivos em uma linguagem de tipagem flexível:

  • Rejeite membros desconhecidos do objeto em solicitações de ação, salvo quando houver uma razão de compatibilidade documentada para mantê-los.
  • Exija o tipo JSON esperado. Um booleano não é uma string que por acaso diz true, e um identificador inteiro não é um número de ponto flutuante.
  • Defina um tamanho máximo para o corpo antes da análise. Um validador de esquema não protege a memória que você já esgotou lendo um corpo enorme.
  • Decida se um campo pode ser omitido, null ou uma string vazia. Esses são três estados diferentes.
  • Rejeite dados posteriores e extensões do analisador, como comentários, NaN ou nomes sem aspas, se a biblioteca oferecer essas opções.

Não autorize diretamente a partir de um mapa genérico. Decodifique em um tipo de solicitação com esquema explícito, faça a validação semântica e então construa um tipo de comando interno que não retenha artefatos brutos do analisador. Um handler que recebe PromoteCommand { environment, release } tem menos espaço para reinterpretar a entrada do que um que recebe um mapa, uma coleção de consultas, um objeto de solicitação e o corpo bruto.

Números exigem atenção especial. A gramática JSON permite literais numéricos grandes, mas muitos ambientes decodificam números como ponto flutuante, a menos que sejam configurados de outra forma. Se um valor identifica dinheiro, cotas, registros de banco de dados ou um conteúdo assinado, use uma representação em string ou um analisador de inteiros com intervalo documentado. Não permita que uma camada arredonde um número antes de outra compará-lo.

Corpos de formulário criam regras ocultas para arrays e aninhamento

application/x-www-form-urlencoded parece simples porque lembra uma string de consulta. Ele deixa de ser simples quando as bibliotecas começam a atribuir significado a nomes repetidos, à notação com colchetes, aos sinais de mais e aos valores vazios.

Considere estes corpos:

role=user&role=admin
role[]=user&role[]=admin
role[user]=1&role[admin]=1
role=user%26role%3Dadmin

Frameworks diferentes podem tratar isso como um escalar final, um escalar inicial, um array, um objeto, nomes de campos literais ou um erro de análise. Alguns middlewares analisam formulários para todos os métodos de solicitação. Alguns frameworks de aplicação mesclam parâmetros de consulta e parâmetros de formulário em um objeto conveniente. É nesse objeto que APIs protegidas perdem a noção do que o chamador realmente enviou.

As orientações de teste do OWASP para HTTP parameter pollution observam que o comportamento depende das interações entre aplicação, servidor web, WAF e middleware. Essa é exatamente a razão para testar parâmetros repetidos brutos, em vez de confiar na documentação do analisador de um único framework.

A recomendação popular de aceitar JSON e formulários codificados em URL em todos os endpoints «para compatibilidade com clientes» costuma estar errada. Ela persiste porque facilita escrever um cliente de demonstração e porque muitos frameworks a habilitam por padrão. Também duplica os contratos de representação para cada ação e depois acrescenta silenciosamente um terceiro contrato quando os campos de consulta se mesclam ao corpo.

Se precisar oferecer um endpoint de formulário, dê a ele uma política de análise própria:

  1. Rejeite nomes repetidos, a menos que o esquema defina esse campo como uma lista.
  2. Rejeite a sintaxe com colchetes, a menos que o esquema defina sua codificação exata e o analisador a implemente de modo consistente.
  3. Mantenha os parâmetros de consulta separados dos campos do formulário. Não permita que uma fonte substitua a outra.
  4. Converta os campos analisados no mesmo comando interno tipado usado pela rota JSON somente depois da validação.
  5. Teste codificação percentual, + versus %20, valores em branco, ausência de = e campos duplicados pelo caminho de solicitação usado em produção.

Não resolva isso escolhendo «o primeiro vence» ou «o último vence». Isso produz uma resposta determinística dentro de um componente, mas mantém a divergência em outros lugares. Um campo escalar protegido deve aparecer uma única vez.

Multipart é um protocolo de upload, não um JSON flexível

Controle chamadas HTTP sensíveis
Exija Touch ID ou um clique para cada uso de uma chave de API que precise de um controle mais rigoroso.

multipart/form-data tem uma finalidade legítima: transportar várias partes com cabeçalhos independentes, geralmente com conteúdo de arquivo. A RFC 7578 o define para valores de formulário e exige um parâmetro boundary que separe as partes. Cada parte também pode trazer seus próprios cabeçalhos e metadados de nome de arquivo.

Essa estrutura torna multipart uma representação de fallback ruim para comandos autenticados comuns. Há mais sintaxe, mais tratamento de tamanho, mais lugares para nomes de campos duplicados e mais oportunidades para que um gateway inspecione uma parte enquanto a aplicação escolhe outra.

Um design problemático comum aceita uma parte JSON metadata junto com um arquivo e também aceita campos de formulário de nível superior que podem substituir os metadados:

Content-Disposition: form-data; name="metadata"

{"project":"alpha","visibility":"private"}

Content-Disposition: form-data; name="visibility"

public

Um componente pode autorizar com base em metadata.visibility. Outro pode vincular a parte de formulário posterior ao parâmetro visibility do handler. A solicitação tem dois valores para uma propriedade sensível, expressos em duas gramáticas.

Projete endpoints multipart em torno de partes nomeadas, cada uma com uma função distinta. Por exemplo, aceite exatamente uma parte file e exatamente uma parte manifest. Exija que manifest seja JSON com seu próprio esquema estrito. Rejeite qualquer nome de parte que não esteja listado no contrato de upload, rejeite partes únicas duplicadas, defina limites separados para o tamanho total do corpo e o tamanho do arquivo e decida se os valores de Content-Type das partes são obrigatórios.

Não confie em um nome de arquivo como caminho, em uma declaração MIME como classificação do arquivo ou no comportamento de arquivos temporários do analisador multipart como controle de segurança. Esses são problemas separados de upload. A regra da confusão entre analisadores continua simples: as entradas de autorização devem vir de uma única fonte nomeada e validada. Se manifest.project determina onde um arquivo será colocado, nenhuma outra parte, parâmetro de consulta ou cabeçalho pode alterar esse projeto.

Quando um comando não tiver arquivo, não aceite multipart. Cada tipo de mídia adicional aceito é uma forma extra de fazer dois componentes discordarem.

Um corpo vazio é um contrato, não ausência de validação

Algumas ações autenticadas não precisam de argumentos. Revogar a sessão atual, alternar um nonce gerado pelo servidor ou confirmar um evento fixo pode usar um corpo de solicitação vazio. Nesses casos, torne o vazio obrigatório.

Um endpoint com contrato sem corpo deve rejeitar tudo a seguir:

POST /v1/sessions/revoke HTTP/1.1
Content-Type: application/json
Content-Length: 2

{}
POST /v1/sessions/revoke HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

scope=other
POST /v1/sessions/revoke HTTP/1.1
Transfer-Encoding: chunked

0

O último exemplo não contém conteúdo, mas ainda usa um mecanismo de enquadramento que seu contrato sem corpo pode proibir. A rejeição depende da sua pilha HTTP, mas decida e teste isso na borda. Não deixe um proxy passar um enquadramento que a aplicação trate de outra forma.

Para uma rota sem corpo, aplique estas regras antes da lógica de negócio:

  • A solicitação não tem bytes de conteúdo.
  • A rota não aceita Content-Type, exceto quando uma regra de compatibilidade permitir isso explicitamente.
  • A rota não mescla parâmetros de consulta ao comando, a menos que cada nome de consulta permitido apareça em seu próprio esquema.
  • O servidor registra a ação como livre de argumentos, em vez de registrar um objeto genérico de solicitação que leitores posteriores possam confundir com uma entrada.

A RFC 9110 descreve o conteúdo da solicitação de acordo com a semântica do método e não atribui significado universal a um corpo apenas porque a solicitação usa POST. É o contrato do recurso que fornece esse significado.

O caso incômodo é uma biblioteca de cliente que sempre envia {}. Não amplie o endpoint apenas para acomodá-la. Corrija o cliente ou forneça uma rota separada e documentada. Um corpo que atualmente não tem efeito pode se tornar um canal de entrada acidental depois de uma alteração no handler.

Valide antes da autorização e execute a partir do comando validado

Mantenha as chaves de API fora dos agentes
O Sallyport injeta as credenciais HTTP, para que o agente nunca receba a chave da API.

O pipeline de solicitação mais seguro tem uma única direção. Bytes brutos entram. Uma rota seleciona um analisador permitido. O analisador produz um valor tipado. A validação produz um comando canônico. A autorização avalia esse comando. O executor recebe o mesmo comando.

raw HTTP request
  -> route and media-type check
  -> bounded body read
  -> one strict parser
  -> schema and semantic validation
  -> canonical command
  -> authorization
  -> execution and audit record

Não inverta as duas etapas centrais. A autorização costuma precisar de campos como ID do projeto, ambiente, destinatário ou modo do comando, e por isso as equipes são tentadas a inspecionar entradas analisadas de forma flexível antes. Isso cria um analisador pré-autorização cujo comportamento precisa permanecer idêntico ao do decodificador final para sempre. Poucos sistemas conseguem manter essa promessa.

O comando canônico é um limite prático, não um padrão para diagramas. Ele deve conter apenas os valores necessários ao executor e excluir texto bruto do corpo, coleções de formulários, objetos de solicitação do framework e aliases. Se o executor recebe target_environment, ele não deve consultar depois req.query.environment porque o destino estava ausente ou era inconveniente.

Isso também melhora os registros de auditoria. Registre o principal autenticado, o endpoint, o tipo de mídia aceito, um resumo da solicitação, os campos do comando canônico que podem ser mantidos com segurança, a decisão de autorização e o resultado. Registrar corpos brutos por padrão cria outro problema, porque eles podem conter credenciais, arquivos enviados e dados de usuários. Um resumo permite correlacionar um evento com evidências preservadas sem transformar os logs em um depósito de segredos.

A assinatura de solicitações exige a mesma disciplina. Se o cliente assina bytes, mas o servidor autoriza um objeto normalizado, registre as regras da representação assinada e as regras de canonização. Se o cliente assina um objeto canônico, rejeite todas as codificações alternativas antes de verificar a assinatura. Caso contrário, duas sequências de bytes podem carregar a mesma solicitação de negócio, ou uma sequência pode ganhar outro significado depois da análise.

Teste a divergência, não apenas o analisador no caminho feliz

Testes unitários que desserializam um único fixture JSON válido provam muito pouco sobre a concordância entre analisadores. O alvo do teste é o caminho público da solicitação: balanceador de carga ou proxy reverso, gateway, middleware do framework, handler da rota e qualquer serviço que analise novamente o corpo.

Monte um corpus compacto de casos negativos para cada operação autenticada. O corpus deve rodar na CI em um ambiente descartável e verificar tanto a resposta quanto a ausência de efeitos colaterais. Uma resposta 400 não basta se uma mensagem de fila, um evento de auditoria ou uma gravação parcial de arquivo já tiver ocorrido.

Comece com este harness de shell. Ele envia corpos brutos de propósito, em vez de depender de um cliente gerado que se recuse a enviar entradas inválidas:

base=https://api.test.example
bearer='test-token'

send() {
  name=$1
  type=$2
  body=$3
  code=$(curl -sS -o "/tmp/${name}.out" -w '%{http_code}' \
    -X POST "$base/v1/deployments/promote" \
    -H "Authorization: Bearer $bearer" \
    -H "Content-Type: $type" \
    --data-binary "$body")
  printf '%-28s %s\n' "$name" "$code"
}

send valid_json 'application/json' \
  '{"environment":"staging","release":"2026.07.22"}'
send duplicate_json 'application/json' \
  '{"environment":"staging","environment":"production","release":"2026.07.22"}'
send form_body 'application/x-www-form-urlencoded' \
  'environment=production&release=2026.07.22'
send false_json 'application/json' \
  'environment=production&release=2026.07.22'

O formato esperado da saída deve ser um sucesso e três rejeições do cliente:

valid_json                   200
 duplicate_json               400
form_body                    415
false_json                   400

Sua convenção de status pode retornar 422 para uma solicitação sintaticamente válida que não atende ao esquema. Preserve a distinção importante: uma incompatibilidade de tipo de mídia nunca deve chegar a um analisador de fallback, e um membro JSON duplicado nunca deve chegar à autorização.

Amplie esse corpus com casos que atinjam os limites entre componentes:

CasoO que deve acontecer
Content-Type ausente com corpo não vazioRejeitar antes da análise
Objeto JSON com campo desconhecidoRejeitar ou registrar um comportamento de compatibilidade documentado
Escalar de formulário repetidoRejeitar
Valor de consulta em conflito com valor JSONRejeitar ou ignorar a consulta conforme o contrato da rota
Multipart com duas partes manifestRejeitar
Rota sem corpo recebe {}Rejeitar

Depois, examine o rastro de auditoria. Cada entrada rejeitada deve ter um trace que identifique a rota e a classe da rejeição sem registrar conteúdos sensíveis da solicitação. Cada entrada aceita deve gerar um comando canônico. Se os logs mostrarem que o gateway viu um destino e o handler registrou outro, você encontrou uma divergência, mesmo que o teste tenha recebido uma resposta 2xx.

Proxies e middlewares também são analisadores

Separe a intenção das credenciais
O Sallyport executa ações HTTP a partir do cofre criptografado e devolve apenas o resultado ao agente.

As equipes costumam apontar para o analisador da aplicação e esquecer os componentes anteriores. Proxies reversos podem normalizar cabeçalhos. Gateways de API podem inspecionar JSON para aplicar uma regra. WAFs podem analisar dados de formulário. Middlewares de observabilidade podem ler e reconstruir um corpo. Um framework pode preencher campos de consulta, formulário e JSON antes da execução do handler da rota.

As orientações do OWASP sobre HTTP request smuggling descrevem a versão mais ampla desse problema: intermediários e servidores de backend podem interpretar os limites da solicitação de formas diferentes, especialmente durante a tradução de protocolos e o enquadramento. A confusão de tipo de conteúdo não precisa de request smuggling para ser perigosa, mas as duas falhas surgem quando camadas diferentes podem tomar decisões de análise incompatíveis.

Faça um inventário de todos os leitores de corpo no caminho da ação. Para cada um, registre quais tipos de mídia ele analisa, se mantém valores duplicados, se descompacta o conteúdo, se impõe um limite de tamanho e se pode reescrever o corpo. Se ninguém souber responder a essas perguntas, o endpoint não está pronto para credenciais de agentes.

Mantenha o papel do gateway restrito. Ele pode impor limites de corpo por rota e bloquear tipos de mídia que a rota nunca aceita. Também pode rejeitar cabeçalhos inválidos antes da aplicação. Mas não use uma transformação do gateway para converter dados de formulário em JSON ou «limpar» campos duplicados. A aplicação ainda precisa rejeitar a ambiguidade usando exatamente a semântica que executará.

Teste as versões HTTP e os caminhos de implantação realmente usados em produção. Uma solicitação que funciona corretamente em um servidor local de desenvolvimento pode mudar quando um cliente HTTP/2 chega a um proxy que encaminha HTTP/1.1 para a aplicação. O objetivo não é montar um laboratório de pesquisa de ataques. É fazer a cadeia de produção provar que produz um único objeto de comando para cada solicitação aceita.

Gateways de agentes devem preservar esse limite

Um gateway de agente deve manter as credenciais longe do modelo e preservar um registro da ação, mas não consegue tornar segura sozinho uma API de destino permissiva. O gateway precisa enviar uma representação explicitamente aceita pela rota de destino, e o destino precisa validar essa representação antes de avaliar a autoridade.

O canal HTTP do Sallyport injeta credenciais enquanto mantém as chaves de API fora do agente, permitindo que ele solicite uma ação sem receber o segredo. Esse é um limite útil para as credenciais. Combine-o com contratos de endpoint que rejeitem corpos ambíguos, porque credenciais protegidas ainda autorizam a solicitação que chega à API.

Ofereça aos agentes ferramentas que reflitam o contrato, em vez de expor para sistemas sensíveis uma ação genérica de «fazer qualquer solicitação HTTP». Uma ferramenta de promoção deve aceitar argumentos tipados environment e release. A implementação deve serializar um único objeto JSON, definir um único tipo de mídia e rejeitar entradas que não atendam ao esquema da API. O serviço receptor deve repetir a validação. Esquemas de ferramentas reduzem erros, mas não substituem a desconfiança no servidor.

Quando um agente precisar fazer um upload, crie uma ferramenta separada com um arquivo nomeado e um manifesto nomeado. Quando precisar de uma ação sem argumentos, não ofereça nenhum campo de corpo. Essas pequenas restrições tornam a intenção da solicitação mais fácil de inspecionar, aprovar, repetir em um ambiente de teste e auditar depois.

Não aprove uma capacidade vaga esperando que os analisadores forneçam a precisão que falta. Faça o endpoint aceitar um único significado, faça o agente enviar esse significado e rejeite qualquer grafia alternativa antes que uma credencial possa autorizá-la.

FAQ

O que é confusão de tipo de conteúdo em uma API?

É uma discordância entre componentes sobre o significado de uma solicitação HTTP autenticada. Um gateway, um validador de esquema, um analisador do framework, uma verificação de autorização e um handler podem interpretar os mesmos bytes de formas diferentes. Assim, a solicitação passa por um controle com um significado e é executada com outro.

Por que a confusão de tipo de conteúdo é perigosa para agentes de IA?

Os agentes tornam o impacto mais grave porque podem enviar rapidamente muitas solicitações autenticadas e talvez recebam ampla autoridade de ação durante uma sessão. A API deve tratar cada chamada como uma entrada não confiável, mesmo quando uma pessoa aprovou o processo do agente que a realizou.

application/json garante uma solicitação JSON segura?

Não. application/json apenas informa o tipo de mídia declarado. Ele não garante JSON válido, nomes de membros únicos, tipos corretos para os campos ou um formato de solicitação permitido. Analise o conteúdo de forma estrita, rejeite nomes duplicados e valide o valor resultante de acordo com o esquema do endpoint.

Uma API JSON deve aceitar solicitações application/x-www-form-urlencoded?

Rejeite, a menos que o endpoint aceite expressamente dados de formulário e tenha um contrato completo e próprio para isso. Não converta campos de formulário em um objeto semelhante a JSON antes da autorização, porque campos repetidos e a sintaxe com colchetes podem mudar de significado entre bibliotecas.

Quando uma API autenticada deve permitir multipart/form-data?

Somente quando o endpoint precisar enviar arquivos ou quando um protocolo de cliente existente exigir multipart. Trate multipart como um caminho próprio de análise e esquema, restrinja os nomes e cabeçalhos das partes e não o aceite silenciosamente como outra forma de escrever uma ação JSON.

Um endpoint POST autenticado pode exigir um corpo vazio?

Sim, quando a operação não tiver uma representação de solicitação. Uma solicitação com Content-Length: 0 deve ter um contrato explícito de corpo vazio e rejeitar tipos de conteúdo, codificações de transferência e bytes que tentem transformá-la em outra operação.

Qual código de status uma API deve retornar para o Content-Type incorreto?

Um endpoint estrito retorna um erro do cliente antes de avaliar a autorização ou executar a lógica de negócio. Use 415 para tipo de mídia não suportado, 400 para sintaxe inválida e 422 quando a sintaxe válida não atender ao esquema do endpoint, desde que essas distinções sejam compatíveis com as convenções da sua API.

Como testar uma API em busca de divergências entre analisadores?

Teste solicitações brutas pelo mesmo caminho público, gateway e aplicação usado em produção. Para cada operação protegida, varie o tipo de mídia, os campos duplicados, os parâmetros repetidos, os cabeçalhos das partes multipart, o tamanho do corpo e a codificação do conteúdo. Depois, confirme que toda variante inválida falha antes da camada de ação.

Um gateway de API ou WAF pode resolver sozinho a confusão entre analisadores?

Um WAF ou gateway de API pode rejeitar entradas obviamente inválidas, mas também é outro analisador na cadeia e pode introduzir uma interpretação diferente. A aplicação que autoriza e executa a ação ainda precisa analisar e validar uma representação canônica.

A aprovação humana deve substituir a validação do esquema em cada solicitação?

A aprovação deve abranger o processo do agente e a capacidade que ele recebe, enquanto a API continua validando cada corpo de solicitação como se viesse de código hostil. A aprovação humana não valida formatos nem corrige ambiguidades introduzidas depois que o agente envia a solicitação.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov