Los headers HTTP son como las etiquetas invisibles que viajan con cada petición y respuesta entre tu navegador y un servidor web. Aunque no los veas directamente en tu pantalla, allí se esconden datos valiosos: la versión del servidor, el tipo de contenido, políticas de seguridad, cookies y mucho más. Conocerlos es fundamental para cualquier profesional de TI, ya sea que estés depurando una aplicación, auditando la seguridad de un servidor o simplemente curiosando por el funcionamiento de la web.
En este artículo vamos a recorrer el camino completo: primero aprenderemos a obtener y leer headers usando herramientas populares como nmap y curl, y luego veremos cómo modificarlos desde el lado del servidor con Apache, Nginx y PHP. ¡Vamos a sacarle el jugo a estos_headers_!
1. Obteniendo Headers con nmap
Nmap es conocido como el rey del escaneo de puertos, pero también tiene superpoderes para inspeccionar servicios web gracias a sus scripts NSE (Nmap Scripting Engine). En particular, el script http-headers realiza una petición HEAD a la raíz de un servidor web y nos muestra todos los headers de respuesta. Es ideal para un primer reconocimiento rápido de un servidor.
Comando básico
nmap --script http-headers -p 80,443 ejemplo.com
Este comando escanea los puertos 80 y 443 del dominio indicado y ejecuta el script http-headers sobre los servicios que encuentre. El resultado incluirá una lista completa de los headers devueltos por el servidor, como Server, Content-Type, X-Frame-Options y muchos otros. Es una forma rápida y limpia de ver qué información está exponiendo un servidor sin interactuar directamente con un navegador.
Script de seguridad de headers
¡Pero espera, hay más! Nmap también incluye el script http-security-headers, que no solo lista los headers sino que evalúa si tu servidor tiene configurados los headers de seguridad recomendados, como HSTS (HTTP Strict Transport Security), X-Content-Type-Options, X-Frame-Options y Content-Security-Policy. Es una herramienta fantástica para auditar la seguridad de tus despliegues en minutos.
nmap --script http-security-headers -p 443 ejemplo.com
Si el resultado muestra que faltan headers críticos de seguridad, no te preocupes: más adelante en este artículo veremos exactamente cómo añadirlos en Apache, Nginx y PHP.
2. Obteniendo Headers con curl
Curl es la navaja suiza de las peticiones HTTP. Probablemente ya lo tengas instalado en tu sistema (y si no, ¡instálalo ya!). Es perfecto para inspeccionar headers porque es directo, rápido y está disponible prácticamente en cualquier plataforma. A diferencia de nmap, curl te da control total sobre la petición: puedes elegir el método HTTP, enviar headers personalizados y ver tanto los de petición como los de respuesta.
Ver solo los headers de respuesta (-I)
curl -I https://ejemplo.com
El flag -I realiza una petición HEAD y muestra únicamente los headers de respuesta. Es la forma más rápida de ver qué está respondiendo un servidor. Verás algo como HTTP/2 200 seguido de todos los headers con su respectivo valor.
Ver headers de petición y respuesta (-v)
curl -v https://ejemplo.com
El flag -v (verbose) es ideal cuando quieres ver toda la conversación. No solo muestra los headers de respuesta, sino también los headers de petición que curl envía al servidor, incluyendo el User-Agent, Accept, Host y otros. Además, verás información sobre la conexión SSL/TLS si usas HTTPS, lo cual es útil para depurar problemas de certificados.
Enviar un header personalizado (-H)
curl -I -H "X-Custom-Header: HolaMundo" https://ejemplo.com
Con el flag -H puedes enviar headers personalizados en tu petición. Esto es sumamente útil para probar cómo responde tu servidor a ciertos headers, simular peticiones desde clientes específicos, o verificar si tu aplicación respeta correctamente algún header de seguridad que hayas configurado.
3. Modificando Headers en Apache
Apache HTTP Server utiliza el módulo mod_headers para manipular headers HTTP tanto de petición como de respuesta. Este módulo te permite añadir, modificar, reemplazar y eliminar headers de forma granular, ya sea a nivel global del servidor, por VirtualHost o incluso en un archivo .htaccess. Es flexible, potente y probablemente ya esté cargado en tu instalación de Apache.
Activar mod_headers
sudo a2enmod headers
sudo systemctl restart apache2
En distribuciones basadas en Debian/Ubuntu, el comando a2enmod activa el módulo. Si usas CentOS/RHEL, asegúrate de que la línea LoadModule headers_module no esté comentada en tu archivo de configuración. Una vez activado, puedes empezar a jugar con las directivas Header y RequestHeader.
Añadir headers de respuesta
# Archivo: /etc/apache2/sites-available/mi-sitio.conf
<VirtualHost *:80>
ServerName ejemplo.com
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'"
# Ocultar la versión de Apache
ServerTokens Prod
ServerSignature Off
</VirtualHost>
Las directivas Header always set garantizan que los headers se apliquen a todas las respuestas, independientemente del código de estado HTTP. Esto es crucial para los headers de seguridad, que deben estar presentes incluso en respuestas de error como 404 o 500. También es buena práctica ocultar la versión del servidor con ServerTokens Prod, ya que revelar la versión exacta de Apache puede ayudar a un atacante a buscar vulnerabilidades conocidas.
Eliminar headers no deseados
Header always unset X-Powered-By
Header always unset Server
A veces es tan importante añadir headers como eliminar los que revelan información innecesaria. El header X-Powered-By, por ejemplo, suele indicar qué tecnología se usa en el backend (como PHP), información que un atacante podría aprovechar. Con Header always unset puedes deshacerte de ellos fácilmente.
4. Modificando Headers en Nginx
Nginx maneja los headers HTTP a través de su módulo ngx_http_headers_module, que viene habilitado por defecto en la mayoría de las instalaciones. La directiva principal es add_header, que te permite añadir headers de respuesta de forma sencilla y directa. Nginx también ofrece expires para controlar el cache y add_trailer para trailers HTTP, aunque add_header es la que usarás el 99% de las veces.
Añadir headers de seguridad
# Archivo: /etc/nginx/conf.d/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
El parámetro always es muy importante en Nginx: sin él, los headers solo se añadirán a respuestas con código 200, 201, 204, 206, 301, 302, 303, 304 o 307. Con always, se aplican a todas las respuestas, incluidas las páginas de error. Este archivo puede incluirse desde tu server block principal con la directiva include.
Headers en el server block
server {
listen 80;
server_name ejemplo.com;
include /etc/nginx/conf.d/security-headers.conf;
# Ocultar la versión de Nginx
server_tokens off;
location / {
proxy_pass http://backend;
}
}
La directiva server_tokens off oculta la versión de Nginx en el header Server. Es una medida básica de hardening que debería estar activa en cualquier servidor en producción. Recuerda que si tienes múltiples bloques location, los headers definidos en el nivel server se heredan a menos que un bloque location redefina la misma directiva, en cuyo caso se reemplazan completamente.
Un detalle importante sobre la herencia
En Nginx, si añades un add_header dentro de un bloque location, todos los add_header del nivel server se pierden para ese bloque. Es un comportamiento que suele pillar por sorpresa. La solución es usar el archivo de inclusión que mencionamos arriba, o repetir todos los headers necesarios en cada bloque location donde los necesites.
5. Modificando Headers con PHP
PHP ofrece la función header() para enviar headers HTTP personalizados directamente desde tu código. Es tremendamente útil cuando necesitas que la lógica de negocio determine qué headers enviar: por ejemplo, redirecciones dinámicas, tipos de contenido condicionales, headers de descarga de archivos o respuestas de API REST. La regla de oro es clara: header() debe llamarse antes de enviar cualquier salida al navegador. Si ya se ha enviado HTML, texto o incluso un espacio en blanco, PHP lanzará el temido error «Cannot modify header information – headers already sent».
Ejemplos prácticos
<?php
// Establecer el tipo de contenido
header('Content-Type: application/json; charset=utf-8');
// Redireccionar al usuario
header('Location: https://ejemplo.com/nueva-pagina');
exit;
// Forzar la descarga de un archivo
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="doc.pdf"');
readfile('/ruta/al/archivo.pdf');
// Header de seguridad desde PHP
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
Verificar si los headers ya fueron enviados
<?php
if (!headers_sent()) {
header("X-Custom: valor");
} else {
echo "Los headers ya fueron enviados :(";
}
La función headers_sent() te permite verificar de forma segura si ya se ha enviado algún contenido al navegador. Es una buena práctica usarla antes de intentar enviar headers, especialmente en aplicaciones complejas donde puede ser difícil rastrear exactamente dónde se produce la primera salida. También puedes usar los parámetros opcionales de headers_sent() para saber en qué archivo y línea se envió el primer output, lo cual es invaluable para depurar.
Un uso común en aplicaciones PHP modernas es enviar headers desde un middleware o controlador frontal, antes de que se renderice la vista. Frameworks como Laravel, Symfony y WordPress ya manejan esto internamente, pero entender cómo funciona header() a bajo nivel te dará mayor control sobre tus aplicaciones.
6. Headers de Seguridad: Los Imprescindibles
No estaría de más hacer un repaso rápido de los headers de seguridad que todo servidor web debería tener configurados. Estos headers no son un lujo, son una capa fundamental de defensa contra ataques comunes como XSS, clickjacking y MIME sniffing. Configurarlos correctamente puede marcar una diferencia enorme en la seguridad de tus aplicaciones.
| Header | Propósito | Valor recomendado |
| X-Frame-Options | Prevenir clickjacking | SAMEORIGIN o DENY |
| X-Content-Type-Options | Evitar MIME sniffing | nosniff |
| X-XSS-Protection | Filtro XSS del navegador | 1; mode=block |
| Strict-Transport-Security | Forzar HTTPS (HSTS) | max-age=31536000 |
| Content-Security-Policy | Controlar recursos cargados | default-src ‘self’ |
| Referrer-Policy | Controlar info del referer | strict-origin-when-cross-origin |
Después de configurar estos headers en tu servidor (ya sea Apache, Nginx o ambos), te recomiendo verificar su correcta aplicación con las herramientas que vimos al inicio: usa nmap con el script http-security-headers o curl con el flag -I para comprobar que cada header está presente y con el valor esperado.
Y con esto ya tienes todo lo necesario para inspeccionar y modificar headers HTTP como todo un profesional. Recuerda: conocer tus headers es conocer tu servidor. Ya sea que estés hardening un servidor de producción, depurando una API o simplemente aprendiendo cómo funciona la web por debajo, estas herramientas y técnicas te acompañarán toda tu carrera en TI. ¡Happy hacking!
Referencias
[1] Nmap NSE Script: http-headers — Documentación oficial de Nmap — https://nmap.org/nsedoc/scripts/http-headers.html
[2] Nmap NSE Script: http-security-headers — Documentación oficial de Nmap — https://nmap.org/nsedoc/scripts/http-security-headers.html
[3] How to Send HTTP Headers With cURL — Bright Data — https://brightdata.com/blog/how-tos/http-headers-with-curl
[4] How to view HTTP request headers in cURL — Simplified Guide — https://www.simplified.guide/curl/http-view-request-header
[5] mod_headers — Apache HTTP Server 2.4 Documentation — https://httpd.apache.org/docs/current/mod/mod_headers.html
[6] How to Configure Apache mod_headers for Security — OneUptime Blog — https://oneuptime.com/blog/post/2026-03-02-configure-apache-mod-headers-security-headers-ubuntu/view
[7] ngx_http_headers_module — Nginx Official Documentation — https://nginx.org/en/docs/http/ngx_http_headers_module.html
[8] Using the Nginx add_header Directive — KeyCDN Support — https://www.keycdn.com/support/nginx-add_header
[9] PHP: header() — Manual oficial de PHP — https://www.php.net/manual/en/function.header.php
[10] HTTP Headers Cheat Sheet — OWASP — https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html
[11] X-Frame-Options — MDN Web Docs — https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options
[12] Content Security Policy (CSP) — MDN Web Docs — https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP

Deja una respuesta