Los headers que debemos evitar

Los encabezados o headers HTTP son una forma importante de controlar de qué modo procesan tu contenido web las memorias caché y los navegadores. Sin embargo, muchos se emplean de forma incorrecta o sin sentido, lo cual incrementa la carga de tu página en momentos críticos, y quizás no funcionen del modo que tenías previsto. En esta primera parte de una serie de entradas de blog sobre buenas prácticas en los headers, examinaremos los que son innecesarios.


La mayoría de los desarrolladores recurre a una serie de HTTP headers para sacar adelante sus contenidos. Los más conocidos incluyen Content-Type y Content-Length, que son prácticamente universales. No obstante, headers como Content-Security-Policy y Strict-Transport-Security han empezado a mejorar la seguridad más recientemente, y los headers Link rel=preload, a mejorar el rendimiento. Son pocos los sitios que utilizan estos últimos, a pesar de la amplia compatibilidad que presentan los navegadores.


De forma paralela, hay un montón de headers que gozan de una tremenda popularidad pero que no son nuevos ni realmente son tan útiles. Podemos probar estas afirmaciones a través de HTTP Archive, proyecto dirigido por Google y promocionado por Fastly que carga 500.000 sitios web al mes por medio de WebPageTest y publica los resultados en BigQuery.


A partir de los datos de HTTP Archive, exponemos los 30 encabezados de respuesta más populares (en función del número de dominios del archivo que estén prestando servicios a cada header) y el grado de utilidad aproximada de todos y cada uno:



























































































































































































Nombre del encabezadoPeticionesDominiosEstado
date48779277535621Protocolo obligatorio
content-type47185627533636Navegador obligatorio habitual
server43057807519663No necesario
content-length42388435519118Útil
last-modified34424562480294Útil
cache-control36490878412943Útil
etag23620444412370Útil
content-encoding16194121409159Obligatorio para comprimir contenido
expires29869228360311No necesario
x-powered-by4883204211409No necesario
pragma7641647188784No necesario
x-frame-options3670032105846No necesario
access-control-allow-origin11335681103596Útil
x-content-type-options1107156094590Útil
link121232987475Útil
age740141559242Útil
x-cache527534356889No necesario
x-xss-protection977390651810Útil
strict-transport-security425912151283Útil
a través de402011747102No necesario
p3p828284044308No necesario
expect-ct268528040465Útil
content-language33408137927Debatible
x-aspnet-version67612833473No necesario
access-control-allow-credentials280438230346Útil
x-robots-tag17917724911No pertinente para navegadores
x-ua-compatible48905624811No necesario
access-control-allow-methods162612920791Útil
access-control-allow-headers120573519120Útil

Echemos un vistazo a los headers innecesarios y analicemos por qué no los necesitamos y qué podemos hacer al respecto.


Vanidad (server, x-powered-by, via)


Podrás estar orgulloso/a del software de servidor que hayas elegido, pero a la mayoría de las personas esto no les interesa en absoluto. En el peor de los casos, estos encabezados quizás divulguen datos sensibles que podrían dejar a tu sitio expuesto a ciberataques.


Server: apache
X-Powered-By: PHP/5.1.1
Via: 1.1 varnish, 1.1 squid

La norma RFC 7231 permite que los servidores incluyan un header Server en la respuesta, con lo que se identifica el software utilizado para proporcionar el contenido. Esto suele adoptar en la mayoría de los casos la forma de una cadena del tipo "apache" o "nginx". Aunque está permitido, no es obligatorio y ofrece muy poco valor a desarrolladores o usuarios finales. No obstante, se trata del tercer HTTP response header en popularidad a día de hoy en Internet.


X-Powered-By es el header más popular de nuestra lista que no viene definido en norma alguna y cumple un fin parecido, aunque suele aludir a la plataforma de aplicaciones que subyace al servidor web. Los valores habituales incluyen "ASP.net", "PHP" y "Express". Insisto: esta información no aporta ventaja tangible alguna y ocupa espacio.


Más debatible quizás sea el caso de via; según la norma RFC 7230, todo proxy a través del cual pase este header deberá agregarlo a la solicitud con fines de identificación. Posiblemente se trate del nombre de host del proxy, pero es más probable que sea un identificador genérico como "vegur", "varnish" o "squid". La supresión de este encabezado (o su no definición) respecto de una solicitud puede provocar que el proxy reenvíe bucles. Sin embargo, es interesante comprobar que este header también se copia en la respuesta que se devuelve al navegador y que, como tal, cumple fines meramente informativos que ningún navegador aprovecha; por lo tanto, es razonablemente seguro deshacerse del encabezado si así lo deseas.


Normas censuradas (P3P, Expires, X-Frame-Options, X-UA-Compatible)


Otra categoría de headers es la de aquellos que afectan al navegador pero que no son (o han dejado de ser) la mejor forma de lograr tal efecto.


P3P: cp="this is not a p3p policy"
Expires: Thu, 01 Dec 1994 16:00:00 GMT
X-Frame-Options: SAMEORIGIN
X-UA-Compatible: IE=edge

P3P es un espécimen curioso. No tenía ni idea de lo que era y, lo que resulta más curioso aún, uno de sus valores más habituales es "this is not a p3p policy" (esta no es una política P3P). O sea, ¿lo es o no lo es?


En este caso, la historia se remonta a un intento de normalizar una política de privacidad de lectura mecánica. Había divergencias sobre cómo hacer aflorar los datos en los navegadores y un solo navegador llegó a implementar el encabezado: Internet Explorer. Y, sin embargo, ni siquiera con IE P3P activaba efectos visuales para el usuario; solo tiene que estar presente para permitir el acceso a cookies de terceros en iframes. Algunos sitios incluso establecen una política P3P no conforme, como la anterior, a pesar de que hacerlo supone adentrarse en arenas movedizas desde el punto de vista jurídico.


Ni que decir tiene que la lectura de cookies de terceros es en general una mala idea, así que, si no es una práctica que sigas, ¡no tendrás por qué definir un header P3P!


Expires es increíblemente popular, sobre todo teniendo en cuenta que Cache-Control ha estado por delante de Expires en preferencia durante 20 años. En los casos en que el header Cache-Control incluya una directiva del tipo max-age, todo header Expires que figure en la misma respuesta será ignorado. Sin embargo, existe un número ingente de sitios que definen ambos headers. De hecho, el valor más habitual de Expires es Thu, 01 Dec 1994 16:00:00 GMT (jueves 1 de diciembre de 1994 a las 16.00 GMT); la razón: nadie quiere que su contenido se almacene en caché, de modo que copiar y pegar la fecha de ejemplo recogida en las especificaciones es sin duda una forma de conseguir este objetivo.


Captura de pantalla del 2018-05-10 a las 21.49.25


Pero no hay razón alguna para hacerlo. Si tienes un encabezado Expires definido con una fecha del pasado, sustitúyelo con esto:


Cache-Control: no-store, private

(no-store es una directiva muy rigurosa por la que se impide la escritura de contenido en el almacenamiento persistente; así que, en función de tu caso, quizás prefieras en realidad no-cache para lograr un mejor rendimiento, por ejemplo, al utilizar los botones atrás/siguiente en la navegación o al volver a utilizar pestañas hibernadas).


Algunas de las herramientas que auditan tu sitio tienden a pedirte que incluyas un header X-Frame-Options con un valor del tipo "SAMEORIGIN". Se indica así a los navegadores que rechazas ser integrado/a mediante marcos por otro sitio y, en líneas generales, es una buena estrategia de defensa frente al clickjacking. Sin embargo, se puede conseguir el mismo efecto, aunque con una compatibilidad más sistemática y una definición de comportamiento más sólida, haciendo lo siguiente:


Content-Security-Policy: frame-ancestors 'self'

Se logra así la ventaja complementaria de formar parte de un header CSP, que en cualquier caso deberías tener por otros motivos (veremos detalles al respecto más adelante). Por tanto, probablemente puedas prescindir de X-Frame-Options en la actualidad.


Por último, en la época de IE9, Microsoft lanzó la función "Vista de compatibilidad", que permitía presentar un página que utilizara el motor de IE8 o IE7 aun navegando con IE9 si el navegador consideraba que la página podría necesitar la versión anterior para una presentación adecuada. Esa heurística no siempre daba en el clavo, y los desarrolladores fueron capaces de reemplazarla mediante el header o la meta etiqueta X-UA-Compatible. De hecho, esta práctica pasó a emplearse habitualmente en marcos de trabajo como Bootstrap. En la actualidad, la función de este header apenas tiene utilidad: muy pocos usuarios utilizan navegadores que lo entenderían y, si mantienes tu sitio de forma activa, es muy improbable que utilices tecnologías que fueran a activar la vista de compatibilidad.


Datos de depuración (X-ASPNet-Version, X-Cache)


Resulta algo sorprendente que algunos de los headers cuyo uso se ha popularizado más no vengan recogidos en norma alguna. Esto quiere decir, fundamentalmente, que por alguna razón miles de sitios web parecen haber acordado de forma espontánea utilizar un header particular de un modo concreto.


X-Cache: HIT
X-Request-ID: 45a336c7-1bd5-4a06-9647-c5aab6d5facf
X-ASPNet-Version: 3.2.32
X-AMZN-RequestID: 0d6e39e2-4ecb-11e8-9c2d-fa7ae01bbebc

La realidad es que los desarrolladores de sitios web no acuñan estos headers "desconocidos" de forma aislada e independiente. Suelen tratarse de artefactos que guardan relación con el uso de marcos de trabajo de servidores concretos, software o servicios de distribuidores específicos (en este ejemplo, set, el último header, es un header AWS habitual).


Fastly y otras CDN añaden concretamente X-Cache junto con otros headers relacionados con Fastly, como X-Cache-Hits y X-Served-By. Cuando se activa la depuración, añadimos más headers si cabe, como Fastly-Debug-Path y Fastly-Debug-TTL.


Ningún navegador reconoce estos headers y su eliminación no afecta en absoluto al modo de presentación de tus páginas. Sin embargo, dado que estos headers probablemente te proporcionen como desarrollador información útil, quizás te interese conservar una forma de activarlos.


Confusión (Pragma)


Aunque nunca pensé que escribiría una entrada de blog sobre el header Pragma en el año 2018, este sigue ocupando el puesto 11.º en popularidad según nuestros datos de HTTP Archive. Pragma no solo fue censurado hace mucho en 1997, sino que en ningún caso pretendía ser un encabezado de respuesta: tal y como está especificado, únicamente adquiere significado como parte de una solicitud.


Pragma: no-cache

No obstante, su uso a modo de encabezado de respuesta está tan extendido que algunos navegadores también lo reconocen en este contexto. A día de hoy, las probabilidades de que tu respuesta transite por una caché que comprenda Pragma dentro del contexto de una respuesta y que no comprenda Cache-Control son cada vez más escasas. Si quieres asegurarte de que un contenido no se almacene en caché, lo único que necesitas es Cache-Control: no-store, private.


Ajeno a navegadores (X-Robots-Tag)


De entre nuestros principales 30 headers, solo uno es ajeno a los navegadores. X-Robots-Tag está diseñado para su consumo por parte de rastreadores como Google o de bots de Bing. Puesto que carece de significado para los navegadores, podrías optar por configurarlo únicamente cuando el agente de usuario solicitante sea un rastreador. Del mismo modo, podrías tomar la determinación de que este header dificulta la realización de pruebas o de que quizás infringe las condiciones de servicio del motor de búsquedas.


Errores


En último lugar, merece la pena concluir haciendo mención honorífica de los simples errores. El header Host tiene sentido en cualquier solicitud , pero su inclusión en una respuesta quizás nos esté indicando que tu servidor está mal configurado por algún motivo (me encantaría saber exactamente cuál). No obstante, 68 dominios de HTTP Archive devuelven en sus respuestas el encabezado Host.


Eliminación de headers en el borde


Por suerte, si tu sitio subyace a Fastly, la eliminación de headers es muy sencilla a través de VCL. Es lógico que quieras conservar los datos de depuración que sean verdaderamente útiles y ponerlos a disposición de tu equipo de desarrollo, pero ocultos a los usuarios públicos; esto se consigue fácilmente detectando una cookie o un HTTP header entrante:


En la siguiente entrada de blog de la serie, hablaré de las buenas prácticas respecto a los headers que deberías ir implantando y de qué modo activarlas en el borde.

Andrew Betts
Principal Developer Advocate
Fecha de publicación:

1 min de lectura

Comparte esta entrada
Andrew Betts
Principal Developer Advocate

Andrew Bett es Principal Developer Advocate en Fastly y colabora con desarrolladores de todo el mundo para contribuir a que la web sea más rápida, segura, fiable y manejable. Fundó una consultora web que acabó adquiriendo el Financial Times, dirigió un equipo que creó la pionera aplicación web HTML5 del FT y fundó la división Labs dentro de este rotativo. Además, es miembro electo del Technical Architecture Group del W3C, comité compuesto por nueve personas que proporcionan orientación sobre el desarrollo de internet.

¿List@ para empezar?

Ponte en contacto o crea una cuenta.