Summary

  • RFC 9931 aclara que terminar una solicitud Upgrade o CONNECT es condición necesaria, pero no suficiente, para cambiar de protocolo en HTTP/1.1. Un éxito reciente puede alimentar una estimación; la respuesta de esta solicitud es la que fija el estado de esta conexión.
  • Si un cliente de confianza suelta antes de tiempo bytes elegidos por un tercero no confiable, un rechazo puede hacer que el servidor los interprete como otra solicitud HTTP autenticada. La prueba que falta no es el contenido: es el registro de qué se retuvo, qué respuesta llegó, qué regla abrió la compuerta y qué analizador quedó activo.

Ahorrar una espera no elimina la decisión

El envío optimista tiene una lógica económica comprensible. Si el servidor suele aceptar el cambio, aguardar la respuesta parece un viaje de ida y vuelta improductivo. El cliente termina su solicitud y empieza a transmitir datos del protocolo esperado. Cuando acierta, la sesión útil comienza antes.

RFC 9931 estudia lo que ocurre cuando la predicción falla en HTTP/1.1. Fue publicado en marzo de 2026 como documento de estándares de la IETF y actualiza RFC 9112 y RFC 9298. Su hallazgo operativo es más fino que «optimizar es peligroso»: dos sucesos contiguos deben conservar identidades distintas.

El primero es la solicitud. Con Upgrade, el cliente propone cambiar el protocolo de aplicación sobre la conexión existente. Con CONNECT, solicita a un proxy que forme un túnel. El segundo suceso es la respuesta que resuelve la propuesta. 101 Switching Protocols expresa que el servidor acepta Upgrade y señala qué protocolo regirá después. Un 2xx a CONNECT pone la conexión en modo túnel al terminar los encabezados. Cualquier otra respuesta significa que el túnel todavía no existe.

HTTP ya exigía completar el mensaje de solicitud antes de hablar el protocolo nuevo. RFC 9931 añade la precisión decisiva: acabar de pedir no equivale a haber obtenido respuesta. El servidor puede no reconocer el token, exigir autenticación, rechazar el puerto o el destino, no resolverlo o preferir seguir en HTTP/1.1.

Por eso el límite no es una superstición temporal. El cliente no espera porque el protocolo valore la paciencia. Espera porque, antes de la respuesta, los dos extremos todavía pueden asignar gramáticas diferentes a los mismos bytes.

La tasa de aciertos pertenece al pronóstico

Sería absurdo borrar la memoria operativa. Un sistema debe conocer qué servidores soportan una transición, cuánto tarda la respuesta y con qué frecuencia se rechaza. Esa información ayuda a decidir si conviene desplegar una optimización, en qué cohorte y con qué reserva de capacidad.

Pero la estadística no ocupa el lugar del evento. Desde el último éxito pudieron cambiar la ruta, las credenciales, el backend, la política de destino o el intermediario. También puede no haber cambiado nada perceptible y aun así fracasar la conexión remota. La semántica del protocolo atribuye al servidor actual la resolución de la solicitud actual.

La confusión suele aparecer en el lenguaje de operaciones. «El proxy soporta CONNECT» se desliza hasta «este CONNECT fue aceptado». «El token está registrado» se convierte en «el servidor ya cambió». «Siempre funciona» acaba funcionando como una autorización para liberar datos. Cada frase elimina un identificador: conexión, solicitud, respuesta o instante.

Una gobernanza sobria conserva esos identificadores. El resultado histórico es evidencia predictiva. La respuesta de la conexión es evidencia de estado. La política de la aplicación decide después qué se puede hacer dentro del protocolo confirmado. Ninguna capa necesita apropiarse de la autoridad de las otras.

El problema no está solo en los bytes, sino en su autor

Con dos participantes que ya aceptan datos arbitrarios entre sí, equivocarse sobre la transición no crea necesariamente la amenaza descrita por RFC 9931. La frontera se vuelve crítica cuando un tercero no confiable elige los datos y un cliente HTTP de confianza decide cuándo entregarlos al servidor.

Imaginemos una aplicación local sin privilegios que solicita conectividad a través de un proxy autenticado. Prepara de inmediato datos para el supuesto túnel TCP. El cliente proxy los reenvía antes de recibir el 2xx. Si el destino no existe, el servidor rechaza CONNECT y continúa esperando la siguiente solicitud HTTP/1.1 en esa misma conexión.

El tercero puede construir sus datos para que formen una solicitud HTTP válida al proxy. El servidor la verá en una conexión asociada al cliente de confianza, quizá autenticada con un certificado a nivel de conexión. La aplicación acaba de emitir una acción con una identidad que no controla. RFC 9112 describe el contrabando de solicitudes como el aprovechamiento de diferencias de análisis para ocultar peticiones que una política habría bloqueado.

Conviene separar tres diagnósticos. El pronóstico fue incorrecto: no hubo transición. El encuadre fue ambiguo: cliente y servidor eligieron analizadores distintos. La atribución fue falsa: los bytes del tercero heredaron la confianza del cliente. Un contador de fallos de Upgrade o CONNECT solo responde al primer diagnóstico.

Incluso cuando los bytes no forman una solicitud completa, pueden alcanzar un analizador escrito bajo una hipótesis de confianza que ya no se cumple. Las fuentes no prueban que exista una vulnerabilidad en un producto concreto. Sí prueban que la liberación previa a la confirmación cambia quién puede alimentar el viejo analizador.

Cada diseño compra latencia de una manera distinta

WebSocket no permite el atajo. Después del saludo de apertura, el cliente espera la respuesta antes de enviar más datos. Además, sus tramas cliente-servidor usan enmascaramiento de alta entropía. Son dos decisiones de diseño que evitan ofrecer al analizador HTTP una secuencia fácilmente reutilizable como petición.

RFC 9298 había permitido empezar a enviar paquetes UDP antes de la respuesta del proxy. RFC 9931 limita esa posibilidad a HTTP/2 o posterior y la prohíbe en HTTP/1.x. La especificación de IP sobre HTTP adopta el mismo corte: permite optimismo en HTTP/2 y HTTP/3, no en HTTP/1.x. Si un intermediario convierte una solicitud moderna a HTTP/1.1, debe retener las cápsulas hasta analizar una respuesta exitosa.

La diferencia no es una etiqueta de superioridad. En HTTP/1.1 las solicitudes son secuenciales y su separación se deduce del cierre de la anterior. En HTTP/2 y HTTP/3 cada solicitud usa un flujo explícito. Esa estructura impide que los datos de una transición rechazada caigan sin más en el hueco de la siguiente solicitud HTTP/1.1. No certifica el resto de la implementación, el destino ni la política interna del túnel.

RFC 9931 ofrece más opciones para futuros tokens: prohibir el envío anticipado, comenzar el protocolo nuevo con un preámbulo fijo que obligue a fallar al analizador HTTP/1.1 o enmascarar los datos. Si el método HTTP deja de tener sentido tras el cambio, usar GET sin contenido reduce todavía más la superficie ambigua.

El registro IANA de tokens de Upgrade aporta nomenclatura y referencias. No observa conexiones. Que un token exista en el registro no indica que un servidor lo acepte hoy ni que la solicitud presente haya cambiado de estado.

Dos lados deben contener el rechazo de CONNECT

RFC 9931 impone al cliente proxy HTTP/1.1 que actúa para un cliente TCP no confiable al menos una de dos medidas. Puede esperar el 2xx antes de reenviar datos. O puede enviar Connection: close, de modo que un rechazo termine la conexión y no deje un espacio para otra solicitud interpretada. Puede aplicar ambas.

El servidor proxy también recibe una obligación: al rechazar CONNECT, debe cerrar la conexión subyacente y no procesar más solicitudes en ella. Así contiene a clientes que ya adelantaron datos. El coste es real. Ante un 407 de autenticación, cerrar obliga a establecer otra conexión y puede degradar el tiempo de respuesta.

La norma permite desactivar esa mitigación cuando se sabe que el cliente espera el 2xx. Menciona User-Agent y la documentación del proveedor como forma de reconocerlo. RFC 9110, sin embargo, define User-Agent como información del producto, no como prueba criptográfica. También desaconseja que un producto se haga pasar por otro, lo cual muestra una expectativa de comportamiento, no una garantía de identidad.

Una excepción operativa necesita caducidad. Debe nombrar producto y versión, documento examinado, ensayo local, intermediarios cubiertos, propietario, fecha de revisión y condición de reversión. La frase «cliente conocido» no debería sobrevivir intacta a una actualización que cambie el orden de los envíos.

La constancia mínima del límite

El mensaje de respuesta ya viaja por el protocolo. Lo que suele faltar es una constancia que una la respuesta al momento en que el cliente liberó datos ajenos. Daniel Kade propone una constancia de confirmación de transición, compacta y sin contenidos sensibles.

Primero registra la época de conexión y la versión HTTP. Identifica Upgrade o CONNECT, el token o tipo de túnel y una referencia protegida al objetivo. Clasifica la fuente de datos como propia, subsistema acotado o tercero no confiable, sin copiar los bytes.

Después describe la compuerta: versión de implementación, política de liberación, espera por 101 o 2xx, uso de cierre, preámbulo, máscara o flujo explícito. Indica si algo se envió antes de la respuesta y cuál era la base normativa de esa decisión, no solo su tasa histórica de éxito.

El último bloque conserva la respuesta, el protocolo seleccionado, el analizador o túnel finalmente activo y el destino de la conexión tras un rechazo. Las excepciones incluyen evidencia, alcance, responsable, vencimiento y disparadores de invalidez.

No guarda tráfico, certificados de cliente, contraseñas, encabezados de autorización ni secretos del túnel. Tampoco convierte un 2xx en permiso de negocio: confirma la formación del túnel. La aplicación y el servicio remoto aún deben tomar sus propias decisiones.

La constancia es una propuesta editorial, no un requisito de RFC 9931 ni un campo nuevo de HTTP. Su función es modesta: impedir que «casi siempre» suplante a la respuesta individual cuando el sistema decide qué analizador recibirá datos de un tercero.

Lo que no sabemos

No hay en estas fuentes una medición de despliegue ni un incidente atribuible a un proveedor. No sabemos cuántos clientes aplican mal la frontera ni qué combinación domina en producción. Tampoco se desprende que retener todos los datos sea la mejor solución para cualquier arquitectura.

Cerrar conexiones y añadir esperas puede consumir recursos. Cambiar a una versión nueva de HTTP tiene costes de compatibilidad y no elimina riesgos distintos. La pregunta correcta no es qué opción parece más moderna, sino si el fallo de la opción elegida conserva una interpretación inequívoca y una ruta de corrección.

El hallazgo verificable permanece: un éxito previo describe el pasado. El 101 o 2xx actual determina si esta conexión cruzó la frontera.

Sources

  1. RFC 9931: consideraciones de seguridad para transiciones optimistas en HTTP/1.1
  2. Ficha de RFC 9931 en RFC Editor
  3. RFC 9110: semántica HTTP
  4. RFC 9112: HTTP/1.1
  5. RFC 9298: proxy UDP mediante HTTP
  6. RFC 6455: protocolo WebSocket
  7. RFC 9484: proxy IP mediante HTTP
  8. RFC 9113: HTTP/2
  9. RFC 9114: HTTP/3
  10. Registro IANA de tokens HTTP Upgrade
  11. Heng Lu, «The Policy Mirror»
  12. Heng Lu, «Minimum Initial Specification, Localized Future Decision, Voluntary Adoption»
  13. Heng Lu, «On Why BTW Media Exists, and Why Reality, Not Advocacy, Is the Product»