HTTP Origins - El comienzo de un protocolo revolucionario
Comienzos
El protocolo HTTP es sin lugar a dudas, una de las convenciones y estandarizaciones más importantes en lo que refiere a la World Wide Web, es decir, el internet que todas y todos utilizamos el día de hoy.
Sin embargo, esto no se concretó de un día para otro, pues el desarrollo del protocolo ha sufrido significativas modificaciones, en donde el foco principal se ha encontrado en mejorar la eficiencia de las comunicaciones.
Su origen remonta al año 1989, en donde a quien podríamos llamar el padre de la web, Tim Berners-Lee, establece la primera definición del protocolo de comunicaciones HTTP. En ella se mencionan cuatro bloques, estos son el lenguaje de hipertexto (HTML), el protocolo de red HTTP, un cliente o browser y un servidor distribuidor de archivos cargado vía FTP o NFS.
Es entonces cuando el año 1991 se convenciona la primera versión oficial, el HTTP 0.9.
Esta antigua y minimalista implementación, permitía la transferencia de archivos HTML planos, es decir sin ninguna funcionalidad ni interacción con el usuario, por medio de lo que se conoce como un "one line protocol", las peticiones eran realizadas unicamente con el método GET y la ruta del archivo solicitado. No existían cabeceras adicionales ni verbos, ni mucho menos parámetros.
Su estructura era la siguiente.
Cabe mencionar, que durante esta versión, en el año 1994, se implementa además el protocolo HTTPS, añadiendo una capa de seguridad a la transmisión de información.
Versión 1
Un par de años mas tarde se introduce la primera actualización (HTTP 1.0), que esta vez si consideraba la transmisión de imagenes, metadata y en definitiva algo más de dinamismo al hiper texto plano anterior.
Junto a ello, se definen los verbos HTTP POST, HEAD, PUT y DELETE, así como los códigos de estado y algunas cabeceras.
Si bien, se implementaron mejoras y que hoy en día forman parte del esqueleto axial de las peticiones web, estas tenían un problema estructural en la capa de transporte, ya que cada petición debía generar un handshake nuevo, no existía una reutilización de la conexión por lo que eran tremendamente ineficientes.
Esta dificultad se resolvió rápidamente un año mas tarde, con la introducción del HTTP 1.1. Con él se introducen los verbos OPTIONS y TRACE, el Transfer-encoding, la segmentación de dominios (característica que nos permite realizar peticiones simultaneas a un mismo host bajo dominios diferentes), y por su puesto, las cabeceras "Connection" y "Keep-alive", ya que como mencionabamos antes, optimizaron los recursos y las conexiones TCP, que ahora son persistentes. En otras palabras, solo es necesario un handshake para mantener la conexión viva, pero esta debe cerrarse explícitamente mediantes estas cabeceras.
Durante este periodo se intentó establecer el "pipelining", técnica que pretendía mejorar en rendimineto, permitiendo no esperar por la respuesta del servidor para mandar la siguiente petición. Sin embargo, esto llevó consigo varios problemas como el "head-of-line blocking", que retrasaba todas las peticiones si es que una tomaba demasiado tiempo en procesarse, por lo que fue rápidamente descartado.
Sin lugar a dudas, esta versión fue tremendamente exitosa ya que perduró por al rededor de 18 años sin modificaciones sustanciales, y continúa siendo la versión predominante.
Versión 2
Después de un replanteamiento por parte de la comunidad, Google movilizó su mano "invisible" para destrabar el debate respecto a una nueva y más moderna versión, para lo cual, el año 2012 creó su propio protocolo SPDY, quien sería el primer bosquejo del HTTP2.
Con SPDY se añadieron varias carácteristicas nuevas, que tenían como foco el repensar las ideas iniciales del protocolo HTTP y fueron una tremenda influencia para esta nueva versión. Cabe mencionar, que SPDY si bien, fue una gran innovación, esta era vulnerable a ataques de decompresión de datos, conocido como CRIME, en donde era posible extraer información de las cabeceras como lo son las cookies de sesión, permitiendo el robo de sesiones por medio del hijacking.
El año 2015 se oficializa en el RFC 7540 la segunda versión del protocolo, en la cual incorporó la compresión HPACK, que resultaba ser resiliente a los ataques CRIME, dado que las cabeceras son comprimidas utilizando diccionarios estáticos y dinámicos, eliminando la redundancia de estas y reduciendo el contenido de las cabeceras más frecuentes (diccionario estático) o reutilizadas (diccionario dinámico) a solo un par de bytes. Hay que precisar que esta compresión, tiene su sentido en la reducción de la cantidad de información que hoy en día tienen estas cabeceras, pero el cuerpo de la petición se comprime con el algoritmo Huffman.
En esta oportunidad las cabeceras pueden representarse de la siguiente forma:
Además, se introducen carácteristicas más complejas del anteriormente mencionado pipelining, este el el multiplexing, que permite generar multiples streams por medio de identificadores, que ahora si creaban la posibilidad de mantener peticiones en cola. Por su parte, también se implementa el "Server Push", que da la posibilidad de responder proactivamente y enviar data previa a su solicitud.
Versión 3
Nuevamente, Google no conforme con los cambios introducidos, el año 2019 creó y replanteo un nuevo protocolo llamado QUIC (Quick UDP Internet Connection), y este fue la base para lo que hoy en día es el HTTP 3, el cual consiste basicamente en HTTP2 corriendo sobre QUIC
Dentro de las carácterísticas más novedosas de QUIC, son la integración la encriptación TLS 1.3 por defecto en el mismo protocolo, la reducción de la latencia por medio de conexiones UDP y la migración de la conexión, que por medio de identificadores de los streams según ID en vez de IP, nos deja conservar la integridad de las peticiones (lo cual es un problema estructural de UDP), a pesar por ejemplo, de cambiarnos de una red a otra.
También mencionamos que la compresión HPACK es mejorada con QPACK, que si bien es similar, es pensado de acuerdo a las nuevas introducciones respecto al uso de UDP y resuelve problemas de congestión por cuello de botella (head-of-line blocking).
Conclusión
Si bien, el protocolo HTTP se ha mantenido con una gran estabilidad por un par de decadas, dada la constante y creciente complejidad de la Web, ha sufrido cambios vertiginosos en los últimos años, mejorando significativamente en rendimiento de las comunicaciones, pero no excento de polémicas, ni de vulnerabilidades. Y en ese sentido, es justamente muy intererante como la introducción de estas características traen consigo un mundo entero de posibilidades en cuanto a nuevas superficies de ataque, que nos fuerza a repensar e investigar de que somos capaces en esta inexplorada tierra.
Referencias:
https://developer.mozilla.org/en-US/docs/Web/HTTP
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
https://blog.cloudflare.com/hpack-the-silent-killer-feature-of-http-2/
https://blog.cloudflare.com/announcing-support-for-http-2-server-push-2/
https://www.stackpath.com/edge-academy/what-is-domain-sharding/
https://portswigger.net/daily-swig/http-request-smuggling-http-2-opens-a-new-attack-tunnel
https://portswigger.net/research/http2
http://python-hyper.org/projects/h2/en/stable/basic-usage.html
https://www.w3.org/People/Berners-Lee/1991/08/art-6484.txt