8 min de lectura

Confusión del tipo de contenido en llamadas autenticadas de agentes

La confusión del tipo de contenido puede permitir que las llamadas autenticadas de agentes eludan la intención. Prueba JSON, formularios, multipart y cuerpos vacíos contra un único esquema.

Confusión del tipo de contenido en llamadas autenticadas de agentes

Las llamadas autenticadas de los agentes deben tener una única interpretación desde el borde de la red hasta el manejador de acciones. Si la pasarela ve una solicitud JSON inofensiva, la capa de autorización ve un conjunto de campos y el manejador ve un envío de formulario privilegiado, la credencial cumplió su función, pero la API falló.

No es un problema limitado a los antiguos formularios del navegador. Los agentes generan HTTP directamente, reintentan de forma agresiva, reutilizan ejemplos de las descripciones de herramientas y suelen operar con credenciales capaces de cambiar sistemas reales. El cuerpo de una solicitud forma parte de la decisión de autorización cuando selecciona un destino, una cantidad, un entorno, un comando o un permiso. Antes de decidir si el emisor puede actuar, debes hacer inequívocos su tipo de contenido, su sintaxis y su esquema.

Una solicitud autenticada todavía debe significar una sola cosa

La autenticación responde quién presentó una credencial. La autorización responde si ese emisor puede realizar una acción. Ninguna de las dos respuestas indica si todos los componentes coincidieron en los argumentos de la acción.

Considera un endpoint que cambia el destino de un despliegue:

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

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

El código de autorización puede permitir la promoción a staging, pero denegarla en producción. Ese código solo es correcto si recibe el mismo valor de environment que usa el manejador de acciones. Si una capa de middleware lee JSON, un manejador consulta después los parámetros del formulario y ambos pueden rellenar un mismo objeto de solicitud, has creado dos fuentes de verdad.

El fallo no necesita un token criptográfico defectuoso. Un agente con una sesión legítima puede enviar un cuerpo que una capa ignore y otra acepte. Un agente comprometido puede hacer lo mismo. El resultado es una omisión de autorización expresada como formato de entrada.

RFC 9110 indica que Content-Type señala el tipo de contenido de la representación asociada y define tanto el formato de los datos como la manera en que el receptor debe procesarlos. Por eso, el encabezado forma parte de la semántica de la solicitud, no es un adorno. La misma RFC permite que un receptor sin Content-Type suponga octet-stream o inspeccione los datos. Eso puede ser útil para manejar archivos genéricos, pero es un mal valor predeterminado para APIs de acciones protegidas.

Para un endpoint de acciones, establece esta invariante:

Exactamente un tipo de contenido aceptado convierte los bytes de la solicitud en exactamente un objeto de comando validado. Todas las decisiones de seguridad y todos los efectos secundarios usan ese objeto.

El endpoint puede admitir más de una representación, pero cada representación necesita su propio contrato y su propia batería de pruebas. No trates varios analizadores como simples comodidades intercambiables.

Un encabezado Content-Type no es un esquema

Content-Type: application/json no significa «esta es la forma de solicitud que esperaba». Significa que el emisor afirma que el cuerpo usa un tipo de contenido JSON. Aún debes decidir si ese tipo es compatible con la ruta, si se permiten parámetros, si el cuerpo tiene una sintaxis válida y si el valor decodificado cumple el contrato de la operación.

Un endpoint protegido debe mantener deliberadamente pequeño el conjunto de representaciones permitidas. Muchos endpoints de comandos deberían aceptar solo JSON. Un endpoint de carga puede aceptar únicamente multipart. Una acción sin argumentos debería aceptar ningún cuerpo. Cuanto más amplio sea el conjunto aceptado, más rutas de análisis tendrás que mantener.

La guía REST Security Cheat Sheet de OWASP ofrece una recomendación práctica clara: documenta los tipos de contenido compatibles y rechaza los tipos inesperados o ausentes, aunque permite omitir el tipo de contenido cuando la solicitud tiene una longitud de cero. También advierte que el cuerpo y el tipo declarado deben coincidir para evitar interpretaciones distintas entre productor y consumidor.

Esa recomendación necesita una precisión para las acciones autenticadas. No «hagas coincidir» un tipo declarado inspeccionando el primer carácter y eligiendo un analizador. Que un cuerpo comience por { no autoriza a tratar como JSON una solicitud declarada como datos de formulario. La inspección convierte un contrato claro en una suposición de implementación.

Un contrato de ruta útil sería este:

RutaTipo de contenido permitidoRegla del cuerpo
POST /v1/deployments/promoteapplication/jsonObjeto JSON obligatorio que cumple PromoteRequest
POST /v1/artifactsmultipart/form-dataPartes obligatorias que cumplen ArtifactUpload
POST /v1/sessions/revokeningunoDebe contener cero bytes

Sé preciso con los parámetros del tipo de contenido. Si tu analizador JSON acepta application/json; charset=utf-8, documéntalo y normaliza los parámetros mediante una sola biblioteca. Si solo acepta application/json sin parámetros, rechaza el parámetro en lugar de permitir que el proxy y la aplicación difieran. La elección importa menos que aplicarla una sola vez.

Separa también la preferencia de respuesta Accept del Content-Type de la solicitud. Un cliente puede pedir una respuesta JSON mientras envía un cuerpo inválido. Nunca dejes que un encabezado Accept amplíe los formatos de solicitud que analizará un endpoint de acciones.

JSON necesita reglas más allá de una sintaxis válida

Un analizador JSON puede procesar correctamente una entrada que tu API debe rechazar. Los nombres de miembros duplicados son el ejemplo más evidente:

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

RFC 8259 dice que los nombres de objeto deberían ser únicos y explica por qué: los receptores no coinciden en el tratamiento de nombres duplicados. Muchos conservan el último valor, algunos fallan y otros exponen cada par. Es un problema documentado de interoperabilidad, no una preferencia de estilo teórica.

Supón que un middleware de autorización usa un analizador que conserva el primer valor de environment, mientras que un decodificador posterior conserva el último. El middleware aprueba staging y el manejador promociona producción. No puedes arreglarlo con mejores nombres de roles ni con otra afirmación del token. Rechaza la solicitud antes de que cualquiera de los dos componentes tome una decisión.

Haz lo mismo con los valores que parecen inofensivos en un lenguaje de tipos flexibles:

  • Rechaza los miembros de objeto desconocidos en las solicitudes de acciones, salvo que exista una razón de compatibilidad documentada para conservarlos.
  • Exige el tipo JSON esperado. Un booleano no es una cadena que casualmente dice true, y un identificador entero no es un número de coma flotante.
  • Establece un tamaño máximo del cuerpo antes de analizarlo. Un validador de esquemas no puede proteger la memoria que ya agotaste al leer un cuerpo enorme.
  • Decide si un campo puede omitirse, ser null o ser una cadena vacía. Son tres estados distintos.
  • Rechaza los datos posteriores y las extensiones del analizador, como comentarios, NaN o nombres sin comillas, si tu biblioteca las ofrece.

No autorices directamente desde un mapa genérico. Decodifica en un tipo de solicitud con un esquema explícito, realiza la validación semántica y construye después un tipo de comando interno que no conserve artefactos del analizador. Un manejador que recibe PromoteCommand { environment, release } tiene menos margen para reinterpretar la entrada que uno que recibe un mapa, una colección de consultas, un objeto de solicitud y el cuerpo sin procesar.

Los números requieren especial cuidado. La gramática JSON permite literales numéricos grandes, pero muchos entornos convierten los números en una representación de coma flotante si no los configuras de otro modo. Si un valor identifica dinero, cuotas, registros de base de datos o un contenido firmado, usa un formato de cadena o un analizador de enteros con un rango documentado. No permitas que una capa redondee un número antes de que otra lo compare.

Los cuerpos de formulario crean reglas ocultas para arrays y anidamiento

application/x-www-form-urlencoded parece sencillo porque se parece a una cadena de consulta. Deja de serlo cuando las bibliotecas empiezan a asignar significado a los nombres repetidos, la notación con corchetes, los signos más y los valores vacíos.

Considera estos cuerpos:

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

Distintos frameworks pueden tratarlos como un escalar final, un escalar inicial, un array, un objeto, nombres de campo literales o un error de análisis. Algunos middlewares analizan formularios para todos los métodos de solicitud. Algunos frameworks fusionan los parámetros de consulta y los parámetros de formulario en un objeto práctico. Es ahí donde las APIs protegidas pierden la pista de lo que realmente envió el emisor.

La guía de pruebas de OWASP sobre la contaminación de parámetros HTTP señala que el comportamiento depende de las interacciones entre la aplicación, el servidor web, el WAF y el middleware. Precisamente por eso hay que probar parámetros repetidos sin procesar, en lugar de confiar en la documentación del analizador de un único framework.

La recomendación popular de aceptar JSON y formularios codificados en URL en todos los endpoints «por compatibilidad con los clientes» suele ser equivocada. Se mantiene porque facilita escribir un cliente de demostración y porque muchos frameworks lo activan de forma predeterminada. También duplica los contratos de representación de cada acción y añade silenciosamente un tercer contrato cuando los campos de consulta se fusionan con el cuerpo.

Si debes admitir un endpoint de formulario, dale una política de análisis específica:

  1. Rechaza los nombres repetidos, salvo que el esquema defina ese campo como una lista.
  2. Rechaza la sintaxis con corchetes, salvo que el esquema defina su codificación exacta y el analizador la implemente de forma coherente.
  3. Mantén separados los parámetros de consulta y los campos del formulario. No permitas que una fuente sobrescriba la otra.
  4. Convierte los campos analizados en el mismo comando interno tipado que usa la ruta JSON, pero solo después de validarlos.
  5. Prueba la codificación porcentual, + frente a %20, los valores vacíos, la ausencia de = y los campos duplicados a través de la ruta de solicitudes de producción.

No resuelvas esto eligiendo «gana el primero» o «gana el último». Eso produce una respuesta determinista dentro de un componente y conserva el desacuerdo en los demás. Un campo escalar protegido debe aparecer una sola vez.

Multipart es un protocolo de carga, no un JSON flexible

Revoca una ejecución del agente
Sessions journal registra cada ejecución del agente y te permite revocar de inmediato una sesión activa.

multipart/form-data tiene una función legítima: transportar varias partes con encabezados independientes, a menudo con contenido de archivos. RFC 7578 lo define para valores de formularios y exige un parámetro boundary que separe las partes. Cada parte también puede incluir sus propios encabezados y metadatos de nombre de archivo.

Esa estructura convierte multipart en una mala representación alternativa para comandos autenticados normales. Tiene más sintaxis, más gestión de tamaños, más lugares donde pueden aparecer nombres de campo duplicados y más oportunidades para que una pasarela inspeccione una parte mientras la aplicación elige otra.

Un diseño problemático habitual acepta una parte JSON metadata junto a un archivo y también acepta campos de formulario de nivel superior que pueden sobrescribir los metadatos:

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

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

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

public

Un componente puede autorizar basándose en metadata.visibility. Otro puede asociar la parte de formulario posterior con el parámetro visibility del manejador. La solicitud tiene dos valores para una propiedad sensible, expresados en dos gramáticas.

Diseña los endpoints multipart alrededor de partes con nombres y funciones distintos. Por ejemplo, acepta exactamente una parte file y exactamente una parte manifest. Exige que manifest sea JSON con su propio esquema estricto. Rechaza cualquier nombre de parte que no figure en el contrato de carga, rechaza las partes singleton duplicadas, establece límites independientes para el tamaño total del cuerpo y el tamaño del archivo, y decide si son necesarios los valores Content-Type de cada parte.

No confíes en un nombre de archivo como ruta, en una afirmación MIME como clasificación del archivo ni en el comportamiento de archivos temporales del analizador multipart como control de seguridad. Son problemas independientes de las cargas. La regla contra la confusión del analizador es más sencilla: las entradas de autorización deben proceder de una única fuente identificada y validada. Si manifest.project determina dónde se guarda un archivo, ninguna otra parte, parámetro de consulta o encabezado puede cambiar ese proyecto.

Cuando un comando no contiene archivos, no aceptes multipart. Cada tipo de contenido adicional es una forma más de que dos componentes discrepen.

Un cuerpo vacío es un contrato, no la ausencia de validación

Algunas acciones autenticadas no necesitan argumentos. Revocar la sesión actual, rotar un nonce generado por el servidor o confirmar un evento fijo puede usar un cuerpo vacío. En esos casos, haz que el vacío sea obligatorio.

Un endpoint con contrato sin cuerpo debe rechazar todo lo siguiente:

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

El último ejemplo no contiene datos, pero sigue usando un mecanismo de encuadre que el contrato sin cuerpo quizá prohíba. Que lo rechaces depende de tu pila HTTP, pero debes decidirlo y probarlo en el borde. No permitas que un proxy transmita un encuadre que la aplicación interprete de otra manera.

En una ruta sin cuerpo, aplica estas reglas antes de la lógica de negocio:

  • La solicitud no contiene bytes de contenido.
  • La ruta no acepta Content-Type, salvo cuando una regla de compatibilidad lo permita explícitamente.
  • La ruta no fusiona parámetros de consulta con el comando, salvo que cada nombre permitido aparezca en su propio esquema.
  • El servidor registra la acción como una acción sin argumentos, en lugar de guardar un objeto de solicitud genérico que otros lectores puedan confundir después con una entrada.

RFC 9110 describe el contenido de la solicitud según la semántica del método y no concede un significado universal al cuerpo solo porque la solicitud use POST. Ese significado lo proporciona el contrato del recurso.

El caso incómodo es una biblioteca de cliente que siempre envía {}. No amplíes el endpoint solo para adaptarte a ella. Corrige el cliente o dale una ruta independiente y documentada. Un cuerpo que ahora no tiene efecto puede convertirse en un canal de entrada accidental después de un cambio posterior del manejador.

Valida antes de autorizar y ejecuta el comando validado

Autoriza cada proceso nuevo
Usa por defecto la autorización por sesión en lugar de confiar implícitamente en cada nuevo proceso del agente.

La canalización más segura avanza en una sola dirección. Entran bytes sin procesar. La ruta selecciona un analizador permitido. El analizador produce un valor tipado. La validación produce un comando canónico. La autorización evalúa ese comando. El ejecutor recibe el mismo 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

No inviertas las dos etapas centrales. La autorización suele necesitar campos como el ID del proyecto, el entorno, el destinatario o el modo del comando, así que los equipos se sienten tentados a inspeccionar pronto una entrada analizada de forma flexible. Eso crea un analizador previo a la autorización cuyo comportamiento debe ser idéntico al del decodificador final para siempre. Pocos sistemas mantienen esa promesa.

El comando canónico es un límite práctico, no un patrón para diagramas. Debe contener solo los valores que necesita el ejecutor y excluir el texto original del cuerpo, las colecciones de formularios, los objetos de solicitud del framework y los alias. Si el ejecutor recibe target_environment, no debe consultar después req.query.environment porque faltaba el destino o resultaba incómodo obtenerlo.

Esto también mejora los registros de auditoría. Registra el principal autenticado, el endpoint, el tipo de contenido aceptado, un resumen de la solicitud, los campos del comando canónico que sea seguro conservar, la decisión de autorización y el resultado. Registrar por defecto los cuerpos sin procesar crea otro problema, porque pueden contener credenciales, archivos subidos y datos de usuarios. Un resumen permite relacionar un evento con evidencias conservadas sin convertir los registros en un almacén de secretos.

La firma de solicitudes requiere la misma disciplina. Si el cliente firma bytes, pero el servidor autoriza un objeto normalizado, registra tanto las reglas de representación firmada como las de canonicalización. Si el cliente firma un objeto canónico, rechaza todas las codificaciones alternativas antes de verificar la firma. De lo contrario, dos secuencias de bytes pueden contener la misma solicitud de negocio, o una secuencia puede adquirir un significado distinto después del análisis.

Prueba el desacuerdo, no solo el analizador correcto

Las pruebas unitarias que deserializan un único fixture JSON válido demuestran muy poco sobre la coincidencia entre analizadores. Tu objetivo de prueba es la ruta pública de solicitudes: balanceador o proxy inverso, pasarela, middleware del framework, manejador de ruta y cualquier servicio que vuelva a analizar el cuerpo.

Construye un corpus compacto de casos negativos para cada operación autenticada. Debe ejecutarse en CI contra un entorno desechable y comprobar tanto la respuesta como la ausencia de efectos secundarios. Una respuesta 400 no basta si ya se creó un mensaje en una cola, un evento de auditoría o una escritura parcial de archivo.

Empieza con este arnés de shell. Envía deliberadamente cuerpos sin procesar en lugar de depender de un cliente generado que rechace entradas mal formadas:

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'

La forma esperada de la salida debe ser un éxito y tres rechazos del cliente:

valid_json                   200
 duplicate_json               400
form_body                    415
false_json                   400

Tu convención de estados puede devolver 422 para una solicitud sintácticamente válida que no cumple el esquema. Conserva la distinción importante: un tipo de contenido incompatible nunca debe llegar a un analizador alternativo y un miembro JSON duplicado nunca debe llegar a la autorización.

Amplía el corpus con casos que apunten a los límites entre componentes:

CasoQué debe ocurrir
Falta Content-Type con un cuerpo no vacíoRechazar antes de analizar
Objeto JSON con un campo desconocidoRechazar o aplicar un comportamiento de compatibilidad documentado
Campo escalar de formulario repetidoRechazar
El valor de consulta entra en conflicto con el valor JSONRechazar o ignorar la consulta según el contrato de la ruta
Multipart contiene dos partes manifestRechazar
Una ruta sin cuerpo recibe {}Rechazar

Después, inspecciona el registro de auditoría. Cada entrada rechazada debe tener un rastro que identifique la ruta y la clase de rechazo sin registrar el contenido sensible de la solicitud. Cada entrada aceptada debe producir un único comando canónico. Si los registros muestran que la pasarela vio un destino y el manejador registró otro, has encontrado un desacuerdo aunque la prueba haya recibido una respuesta 2xx.

Los proxies y middlewares también son analizadores

Conserva un registro de cada llamada
Revisa las llamadas HTTP individuales en el registro de actividad después de que el agente haya actuado.

Los equipos suelen señalar el analizador de la aplicación y olvidar los componentes anteriores. Los proxies inversos pueden normalizar encabezados. Las pasarelas de API pueden inspeccionar JSON para aplicar una regla. Los WAF pueden analizar datos de formularios. El middleware de observabilidad puede leer y reconstruir un cuerpo. Un framework puede rellenar campos de consulta, formulario y JSON antes de que se ejecute el manejador de ruta.

La guía de OWASP sobre request smuggling describe la versión más amplia de este problema: los intermediarios y los servidores backend pueden interpretar de forma distinta los límites de una solicitud, especialmente durante la traducción de protocolos y el encuadre. La confusión del tipo de contenido no necesita request smuggling para ser peligrosa, pero ambos fallos surgen cuando distintas capas toman decisiones de análisis incompatibles.

Haz un inventario de cada lector de cuerpos en la ruta de acciones. Para cada uno, anota qué tipos de contenido analiza, si conserva valores duplicados, si descomprime contenido, si impone un límite de tamaño y si puede reescribir el cuerpo. Si nadie puede responder esas preguntas, el endpoint todavía no está listo para credenciales de agentes.

Mantén limitado el papel de la pasarela. Puede aplicar límites de cuerpo por ruta y bloquear tipos de contenido que una ruta nunca acepta. También puede rechazar encabezados mal formados antes de que lleguen a la aplicación. Pero no uses una transformación de la pasarela para convertir datos de formulario en JSON ni para «limpiar» campos duplicados. La aplicación debe rechazar la ambigüedad usando exactamente la semántica que ejecutará.

Prueba las versiones HTTP y las rutas de despliegue que realmente usa producción. Una solicitud que funciona correctamente contra un servidor local de desarrollo puede cambiar cuando un cliente HTTP/2 llega a un proxy que reenvía HTTP/1.1 a la aplicación. El objetivo no es construir un laboratorio de investigación de ataques. Es demostrar que la cadena de producción produce un único objeto de comando por cada solicitud aceptada.

Las pasarelas de agentes deben conservar el límite

Una pasarela de agentes debe mantener las credenciales alejadas del modelo y conservar un registro de la acción, pero no puede hacer segura por sí sola una API de destino permisiva. La pasarela debe enviar una representación que la ruta de destino admita explícitamente, y el destino debe validar esa representación antes de evaluar la autoridad.

El canal HTTP de Sallyport inyecta las credenciales y mantiene las claves de API fuera del agente, de modo que el agente puede solicitar una acción sin recibir el secreto. Es un límite de credenciales útil. Combínalo con contratos de endpoint que rechacen cuerpos ambiguos, porque las credenciales protegidas siguen autorizando la solicitud que llega a la API.

Proporciona a los agentes herramientas que reflejen el contrato en lugar de exponer una acción genérica de «hacer cualquier solicitud HTTP» para sistemas sensibles. Una herramienta de promoción debe aceptar argumentos tipados environment y release. Su implementación debe serializar un único objeto JSON, establecer un solo tipo de contenido y rechazar las entradas de la herramienta que no cumplan el esquema de la API. El servicio receptor debe repetir la validación. Los esquemas de herramientas reducen errores, pero no sustituyen la desconfianza del servidor.

Cuando un agente necesite cargar un archivo, conviértelo en una herramienta independiente con un archivo identificado y un manifiesto identificado. Cuando necesite una acción sin argumentos, no le proporciones ningún campo de cuerpo. Estas pequeñas restricciones facilitan inspeccionar, aprobar, reproducir en un entorno de pruebas y auditar después la solicitud prevista por el agente.

No apruebes una capacidad vaga esperando que los analizadores aporten la precisión que falta. Haz que el endpoint acepte un único significado, que el agente envíe ese significado y que rechace cualquier forma alternativa antes de que una credencial pueda autorizarlo.

FAQ

¿Qué es la confusión del tipo de contenido en una API?

Es un desacuerdo entre componentes sobre el significado de una solicitud HTTP autenticada. La pasarela, el validador del esquema, el analizador del framework, el control de autorización y el manejador pueden interpretar de forma distinta los mismos bytes. Así, una solicitud puede superar un control con un significado y ejecutarse con otro.

¿Por qué la confusión del tipo de contenido es peligrosa para los agentes de IA?

El impacto es mayor con los agentes porque pueden enviar rápidamente muchas solicitudes autenticadas y quizá reciban una amplia autoridad de acción durante una sesión. La API debe tratar cada llamada como una entrada no confiable, aunque una persona haya aprobado el proceso del agente que la realizó.

¿`application/json` garantiza una solicitud JSON segura?

No. application/json solo indica el tipo de contenido declarado. No garantiza que el JSON sea válido, que los miembros del objeto sean únicos, que los tipos de campo sean correctos ni que la forma de la solicitud esté permitida. Analízalo de forma estricta, rechaza los nombres duplicados y valida después el valor resultante contra el esquema del endpoint.

¿Debe una API JSON aceptar solicitudes `application/x-www-form-urlencoded`?

Recházalo, salvo que el endpoint acepte expresamente datos de formulario y tenga un contrato completo e independiente para ellos. No conviertas los campos del formulario en un objeto con forma JSON antes de autorizar, porque los campos repetidos y la sintaxis con corchetes pueden cambiar de significado según la biblioteca.

¿Cuándo debe una API autenticada permitir `multipart/form-data`?

Solo si el endpoint necesita subir archivos o si un protocolo de cliente existente exige multipart. Trátalo como una ruta independiente de análisis y esquema, limita los nombres y encabezados de las partes y no lo aceptes en silencio como otra forma de escribir una acción JSON.

¿Puede un endpoint POST autenticado exigir un cuerpo vacío?

Sí, cuando la operación no tenga una representación de solicitud. Una solicitud con Content-Length: 0 debe tener un contrato explícito de cuerpo vacío y rechazar tipos de contenido, codificaciones de transferencia y bytes que intenten convertirla en otra operación.

¿Qué código de estado debe devolver una API para un `Content-Type` incorrecto?

Un endpoint estricto devuelve un error del cliente antes de evaluar la autorización o ejecutar la lógica de negocio. Usa 415 para un tipo de contenido no compatible, 400 para una sintaxis incorrecta y 422 cuando una sintaxis válida no cumple el esquema del endpoint, siempre que esas distinciones encajen con las convenciones de tu API.

¿Cómo pruebo una API para detectar desacuerdos entre analizadores?

Prueba solicitudes sin procesar a través de la misma periferia pública, pasarela y ruta de aplicación que se usan en producción. Para cada operación protegida, varía el tipo de contenido, los campos duplicados, los parámetros repetidos, los encabezados de las partes multipart, la longitud del cuerpo y la codificación. Comprueba que cada variante inválida falle antes de llegar a la capa de acciones.

¿Puede una pasarela de API o un WAF resolver por sí solo la confusión del analizador?

No. Un WAF o una pasarela de API puede rechazar entradas evidentemente incorrectas, pero también es otro analizador de la cadena y puede introducir una interpretación diferente. La aplicación que autoriza y ejecuta la acción debe analizar y validar una representación canónica.

¿Debe la aprobación humana sustituir la validación del esquema en cada solicitud?

La aprobación debe abarcar el proceso del agente y la capacidad que recibe, pero la API debe seguir validando cada cuerpo como si procediera de código hostil. La aprobación humana no valida formatos ni puede corregir una ambigüedad introducida después de que el agente envíe la solicitud.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov