{"id":3901,"date":"2026-10-16T00:47:10","date_gmt":"2026-10-15T22:47:10","guid":{"rendered":"https:\/\/mantenimientoweb.pro\/blog\/que-encabezados-de-seguridad-http-security-headers-son-obligatorios-en-tu-servidor\/"},"modified":"2026-10-16T00:47:12","modified_gmt":"2026-10-15T22:47:12","slug":"que-encabezados-de-seguridad-http-security-headers-son-obligatorios-en-tu-servidor","status":"publish","type":"post","link":"https:\/\/mantenimientoweb.pro\/blog\/que-encabezados-de-seguridad-http-security-headers-son-obligatorios-en-tu-servidor\/","title":{"rendered":"\u00bfQu\u00e9 encabezados de seguridad HTTP (Security Headers) son obligatorios en tu servidor?"},"content":{"rendered":"<article>\n  \u00bfQu\u00e9 encabezados de seguridad HTTP son obligatorios en tu servidor? \ud83d\udee1\ufe0f<\/p>\n<p>Un sitio web sin encabezados de seguridad HTTP puede parecer impecable: dise\u00f1o limpio, formularios elegantes, velocidad aceptable, certificado SSL brillante como una medalla reci\u00e9n pulida. Pero debajo, en el di\u00e1logo silencioso entre navegador y servidor, quiz\u00e1 va desnudo por la plaza p\u00fablica. Y lo curioso \u2014la peque\u00f1a iron\u00eda t\u00e9cnica de nuestro tiempo\u2014 es que muchas de estas defensas se configuran con unas pocas l\u00edneas.<\/p>\n<p>Los <strong>encabezados de seguridad HTTP<\/strong>, tambi\u00e9n llamados <em>Security Headers<\/em>, son instrucciones que el servidor env\u00eda al navegador para decirle c\u00f3mo debe comportarse frente a ciertos riesgos: ataques XSS, clickjacking, filtraci\u00f3n de datos por referencias, abuso de APIs del navegador, carga de contenido inseguro, exposici\u00f3n de cookies, pol\u00edticas de aislamiento y otras criaturas discretas que rara vez salen en la portada, pero que trabajan en la sombra.<\/p>\n<p>\u00bfSon \u201cobligatorios\u201d? Depende de qu\u00e9 entendamos por obligatorio. No existe una \u00fanica ley universal que diga: \u201ctodo servidor deber\u00e1 llevar exactamente estos siete encabezados o ser\u00e1 arrojado a las tinieblas\u201d. Ser\u00eda c\u00f3modo, s\u00ed. Tambi\u00e9n ingenuo. En seguridad web, lo obligatorio se construye entre varios mundos: est\u00e1ndares t\u00e9cnicos, cumplimiento normativo, auditor\u00edas, requisitos de clientes, buenas pr\u00e1cticas de OWASP, recomendaciones de navegadores, pol\u00edticas internas y, por supuesto, el sentido com\u00fan, ese pariente pobre al que llamamos cuando el incidente ya est\u00e1 en producci\u00f3n.<\/p>\n<p>Lo que s\u00ed existe es un <strong>conjunto m\u00ednimo profesional<\/strong> que cualquier sitio serio deber\u00eda implementar. Un servidor moderno sin estos encabezados se parece a una casa con cerradura biom\u00e9trica en la puerta principal y ventanas abiertas en el s\u00f3tano. Muy tecnol\u00f3gico. Muy vulnerable.<\/p>\n<p>    <strong>En esta gu\u00eda veremos:<\/strong><\/p>\n<ul>\n<li>Qu\u00e9 encabezados de seguridad HTTP son imprescindibles en un servidor moderno.<\/li>\n<li>Cu\u00e1les son recomendables, cu\u00e1les dependen del caso y cu\u00e1les conviene evitar.<\/li>\n<li>C\u00f3mo configurarlos en Apache, Nginx, WordPress, Cloudflare y otros entornos.<\/li>\n<li>Errores frecuentes que rompen sitios o generan una falsa sensaci\u00f3n de protecci\u00f3n.<\/li>\n<li>Una lista pr\u00e1ctica de verificaci\u00f3n para producci\u00f3n. \u2705<\/li>\n<\/ul>\n<h2>Primero: qu\u00e9 son realmente los Security Headers<\/h2>\n<p>Cada vez que visitas una p\u00e1gina, tu navegador pide recursos al servidor: documentos HTML, hojas CSS, JavaScript, im\u00e1genes, fuentes, llamadas a APIs. La respuesta del servidor no trae solo contenido; trae tambi\u00e9n metadatos. Entre ellos est\u00e1n los encabezados HTTP.<\/p>\n<p>Algunos encabezados son funcionales, como <code>Content-Type<\/code> o <code>Cache-Control<\/code>. Otros son defensivos: restringen, advierten, a\u00edslan, limitan. Son como se\u00f1ales de tr\u00e1fico en una ciudad digital. No impiden que existan malos conductores, pero reducen el caos y hacen que ciertas maniobras sean directamente imposibles.<\/p>\n<p>Un ejemplo simple:<\/p>\n<pre><code>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\nX-Content-Type-Options: nosniff\nReferrer-Policy: strict-origin-when-cross-origin\nContent-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'\nPermissions-Policy: camera=(), microphone=(), geolocation=()<\/code><\/pre>\n<p>Estas l\u00edneas no decoran. Ordenan al navegador que use HTTPS, que no adivine tipos MIME, que limite la informaci\u00f3n enviada en el encabezado <code>Referer<\/code>, que solo cargue recursos desde or\u00edgenes permitidos y que bloquee funciones sensibles como c\u00e1mara, micr\u00f3fono o geolocalizaci\u00f3n salvo autorizaci\u00f3n expl\u00edcita.<\/p>\n<p>El contraste es casi literario: el servidor habla en frases breves; el navegador obedece con consecuencias enormes.<\/p>\n<h2>\u00bf\u201cObligatorios\u201d para qui\u00e9n? La respuesta honesta<\/h2>\n<p>La palabra obligatorio conviene tratarla con cuidado. En seguridad, exagerar es f\u00e1cil; precisar cuesta m\u00e1s.<\/p>\n<p>Un encabezado puede ser obligatorio por:<\/p>\n<ul>\n<li><strong>Requisitos de auditor\u00eda o compliance:<\/strong> PCI DSS, ISO 27001, SOC 2, ENS, pol\u00edticas corporativas o auditor\u00edas de seguridad pueden exigir ciertos controles.<\/li>\n<li><strong>Buenas pr\u00e1cticas reconocidas:<\/strong> OWASP Secure Headers Project, Mozilla Observatory, recomendaciones de Google y documentaci\u00f3n de navegadores modernos.<\/li>\n<li><strong>Necesidad t\u00e9cnica:<\/strong> si tu sitio usa cookies de sesi\u00f3n, HTTPS, iframes, APIs, pagos, paneles privados o datos personales, ciertos encabezados dejan de ser \u201copcionales simp\u00e1ticos\u201d.<\/li>\n<li><strong>Riesgo de negocio:<\/strong> no es lo mismo un blog personal que una tienda WooCommerce con datos de clientes, pagos, sesiones administrativas y p\u00edxeles de terceros haciendo su peque\u00f1o carnaval.<\/li>\n<\/ul>\n<p><strong>Idea clave:<\/strong> no todos los encabezados son obligatorios para todos los sitios, pero todo sitio profesional deber\u00eda tener una pol\u00edtica m\u00ednima de encabezados de seguridad. En 2026, no configurarlos ya no es descuido inocente; es negligencia con buena conexi\u00f3n a Internet.<\/p>\n<h2>La lista corta: encabezados imprescindibles en casi cualquier servidor \ud83d\udd10<\/h2>\n<p>Si necesitas una respuesta directa, aqu\u00ed est\u00e1 el n\u00facleo duro. Estos son los encabezados que, en la mayor\u00eda de sitios web modernos, deber\u00edan estar presentes o evaluados seriamente antes de publicar en producci\u00f3n.<\/p>\n<table>\n<thead>\n<tr>\n<th>Encabezado<\/th>\n<th>Prioridad<\/th>\n<th>Funci\u00f3n principal<\/th>\n<th>\u00bfCu\u00e1ndo usarlo?<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>Strict-Transport-Security<\/code><\/td>\n<td><strong>Muy alta<\/strong><\/td>\n<td>Fuerza el uso de HTTPS y reduce ataques de downgrade.<\/td>\n<td>Sitios con HTTPS estable en todo el dominio.<\/td>\n<\/tr>\n<tr>\n<td><code>Content-Security-Policy<\/code><\/td>\n<td><strong>Muy alta<\/strong><\/td>\n<td>Controla desde d\u00f3nde se cargan scripts, estilos, im\u00e1genes, frames y otros recursos.<\/td>\n<td>Casi todos los sitios; requiere pruebas cuidadosas.<\/td>\n<\/tr>\n<tr>\n<td><code>X-Content-Type-Options<\/code><\/td>\n<td><strong>Alta<\/strong><\/td>\n<td>Evita que el navegador \u201cadivine\u201d tipos de archivo.<\/td>\n<td>Todos los sitios.<\/td>\n<\/tr>\n<tr>\n<td><code>Referrer-Policy<\/code><\/td>\n<td><strong>Alta<\/strong><\/td>\n<td>Controla cu\u00e1nta informaci\u00f3n se env\u00eda en el encabezado Referer.<\/td>\n<td>Todos los sitios, especialmente con rutas sensibles.<\/td>\n<\/tr>\n<tr>\n<td><code>X-Frame-Options<\/code> o <code>frame-ancestors<\/code> en CSP<\/td>\n<td><strong>Alta<\/strong><\/td>\n<td>Previene clickjacking al limitar si tu sitio puede ser incrustado en iframes.<\/td>\n<td>Paneles, tiendas, login, formularios, \u00e1reas privadas.<\/td>\n<\/tr>\n<tr>\n<td><code>Permissions-Policy<\/code><\/td>\n<td><strong>Media-alta<\/strong><\/td>\n<td>Limita APIs del navegador como c\u00e1mara, micr\u00f3fono, geolocalizaci\u00f3n, sensores.<\/td>\n<td>Todos los sitios, con ajustes seg\u00fan funcionalidades.<\/td>\n<\/tr>\n<tr>\n<td><code>Set-Cookie<\/code> con <code>Secure<\/code>, <code>HttpOnly<\/code>, <code>SameSite<\/code><\/td>\n<td><strong>Cr\u00edtica<\/strong><\/td>\n<td>Protege cookies de sesi\u00f3n y reduce robo o abuso cross-site.<\/td>\n<td>Cualquier sitio con login, sesiones, carrito o panel.<\/td>\n<\/tr>\n<tr>\n<td><code>Cache-Control<\/code><\/td>\n<td><strong>Alta en \u00e1reas sensibles<\/strong><\/td>\n<td>Evita que datos privados queden almacenados en cach\u00e9s o navegadores compartidos.<\/td>\n<td>Login, checkout, paneles, cuentas de usuario, APIs privadas.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>1. Strict-Transport-Security: HTTPS sin marcha atr\u00e1s<\/h2>\n<p><code>Strict-Transport-Security<\/code>, conocido como <strong>HSTS<\/strong>, le dice al navegador: \u201cdurante este tiempo, visita este dominio solo por HTTPS\u201d. Es una barrera contra ataques de tipo <em>SSL stripping<\/em>, donde un atacante intenta degradar la conexi\u00f3n a HTTP para espiar o manipular tr\u00e1fico.<\/p>\n<p>Ejemplo recomendado para un sitio maduro:<\/p>\n<pre><code>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload<\/code><\/pre>\n<p>Significado:<\/p>\n<ul>\n<li><code>max-age=31536000<\/code>: el navegador recordar\u00e1 la pol\u00edtica durante un a\u00f1o.<\/li>\n<li><code>includeSubDomains<\/code>: aplica tambi\u00e9n a todos los subdominios.<\/li>\n<li><code>preload<\/code>: permite solicitar inclusi\u00f3n en la lista HSTS preload usada por navegadores principales.<\/li>\n<\/ul>\n<p><strong>Atenci\u00f3n:<\/strong> HSTS es poderoso, pero no perdona improvisaciones. Si activas <code>includeSubDomains<\/code> y tienes un subdominio antiguo sin HTTPS, lo romper\u00e1s. Y si entras en la lista preload, salir no es inmediato. Es como tatuar una instrucci\u00f3n en la memoria colectiva de los navegadores: conviene estar sobrio antes de hacerlo.<\/p>\n<p>Versi\u00f3n prudente para empezar:<\/p>\n<pre><code>Strict-Transport-Security: max-age=300<\/code><\/pre>\n<p>Despu\u00e9s de validar que todo funciona por HTTPS, se puede subir gradualmente a seis meses o un a\u00f1o:<\/p>\n<pre><code>Strict-Transport-Security: max-age=15552000; includeSubDomains<\/code><\/pre>\n<p>Y, solo si todo el ecosistema est\u00e1 preparado:<\/p>\n<pre><code>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload<\/code><\/pre>\n<h2>2. Content-Security-Policy: el muro inteligente contra XSS<\/h2>\n<p>Si HSTS es una orden firme, <code>Content-Security-Policy<\/code> \u2014CSP\u2014 es un tratado diplom\u00e1tico con aduanas, fronteras y permisos de importaci\u00f3n. Define qu\u00e9 recursos puede cargar una p\u00e1gina y desde d\u00f3nde: scripts, estilos, im\u00e1genes, fuentes, conexiones, iframes, objetos, formularios.<\/p>\n<p>Una CSP bien dise\u00f1ada puede reducir dr\u00e1sticamente el impacto de ataques <strong>Cross-Site Scripting<\/strong> \u2014XSS\u2014. No sustituye la validaci\u00f3n de entradas, el escape de salidas ni el desarrollo seguro. Quien crea eso probablemente tambi\u00e9n piensa que un paraguas detiene un hurac\u00e1n. Pero como capa defensiva, CSP es una de las m\u00e1s valiosas.<\/p>\n<p>Pol\u00edtica base razonable para empezar:<\/p>\n<pre><code>Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests<\/code><\/pre>\n<p>Directivas importantes:<\/p>\n<ul>\n<li><code>default-src<\/code>: valor por defecto para cargar recursos si no hay una directiva espec\u00edfica.<\/li>\n<li><code>script-src<\/code>: controla JavaScript. Es la parte m\u00e1s delicada.<\/li>\n<li><code>style-src<\/code>: controla CSS.<\/li>\n<li><code>img-src<\/code>: controla im\u00e1genes.<\/li>\n<li><code>font-src<\/code>: controla fuentes.<\/li>\n<li><code>connect-src<\/code>: controla conexiones AJAX, Fetch, WebSocket, APIs.<\/li>\n<li><code>frame-src<\/code>: define qu\u00e9 puede ser embebido dentro de tu sitio.<\/li>\n<li><code>frame-ancestors<\/code>: define qui\u00e9n puede embeber tu sitio.<\/li>\n<li><code>object-src<\/code>: bloquea plugins antiguos como Flash, Silverlight o Java applets. S\u00ed, hay fantasmas que tardan en irse.<\/li>\n<li><code>base-uri<\/code>: evita manipulaci\u00f3n de etiquetas <code>&lt;base&gt;<\/code>.<\/li>\n<li><code>form-action<\/code>: limita a d\u00f3nde pueden enviarse formularios.<\/li>\n<li><code>upgrade-insecure-requests<\/code>: intenta actualizar recursos HTTP a HTTPS.<\/li>\n<\/ul>\n<h3>CSP en modo informe antes de bloquear<\/h3>\n<p>Para evitar romper el sitio de golpe, puede usarse <code>Content-Security-Policy-Report-Only<\/code>. El navegador no bloquea, pero informa violaciones.<\/p>\n<pre><code>Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; object-src 'none'; report-uri https:\/\/tudominio.com\/csp-report<\/code><\/pre>\n<p>Es una etapa sensata para sitios complejos, especialmente WordPress con plugins de anal\u00edtica, p\u00edxeles publicitarios, chatbots, constructores visuales y otros invitados que entran al sal\u00f3n con barro en los zapatos.<\/p>\n<h3>El problema de <code>'unsafe-inline'<\/code><\/h3>\n<p>Muchas implementaciones de CSP acaban as\u00ed:<\/p>\n<pre><code>Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval' *<\/code><\/pre>\n<p>Eso no es una pol\u00edtica de seguridad; es una carta de amor al desorden. <code>'unsafe-inline'<\/code> permite scripts inline, uno de los vectores cl\u00e1sicos de XSS. <code>'unsafe-eval'<\/code> habilita evaluaci\u00f3n din\u00e1mica de c\u00f3digo. Y <code>*<\/code> abre demasiado la puerta.<\/p>\n<p>Lo ideal es usar <strong>nonces<\/strong> o <strong>hashes<\/strong> para permitir solo scripts autorizados:<\/p>\n<pre><code>Content-Security-Policy: script-src 'self' 'nonce-r4nd0mSeguro'; object-src 'none'; base-uri 'self'<\/code><\/pre>\n<p>En aplicaciones modernas, los nonces se generan por respuesta y se aplican a los scripts leg\u00edtimos. En WordPress puede ser m\u00e1s complicado, pero no imposible: algunos plugins de seguridad avanzados, configuraciones personalizadas o capas de proxy permiten aproximarse bastante.<\/p>\n<h2>3. X-Content-Type-Options: no dejes que el navegador improvise<\/h2>\n<p>El encabezado <code>X-Content-Type-Options<\/code> con valor <code>nosniff<\/code> impide que el navegador interprete archivos como un tipo distinto al declarado por el servidor.<\/p>\n<pre><code>X-Content-Type-Options: nosniff<\/code><\/pre>\n<p>\u00bfPor qu\u00e9 importa? Porque algunos navegadores hist\u00f3ricamente intentaban \u201cadivinar\u201d el contenido. Si un archivo subido por un usuario parec\u00eda JavaScript aunque el servidor lo sirviera como texto, pod\u00eda ejecutarse. Una maravillosa cortes\u00eda del navegador, como si un portero dejara pasar a cualquiera porque \u201cparec\u00eda vecino\u201d.<\/p>\n<p>Este encabezado es sencillo, ampliamente soportado y pr\u00e1cticamente obligatorio en cualquier configuraci\u00f3n seria.<\/p>\n<h2>4. X-Frame-Options y frame-ancestors: defensa contra clickjacking<\/h2>\n<p>El <strong>clickjacking<\/strong> consiste en incrustar tu sitio dentro de un iframe invisible o manipulado para enga\u00f1ar al usuario y hacerle clic donde no quer\u00eda. El usuario cree que pulsa un bot\u00f3n inocente; en realidad confirma una acci\u00f3n en otro sitio. La trampa es tan vieja como efectiva.<\/p>\n<p>Encabezado cl\u00e1sico:<\/p>\n<pre><code>X-Frame-Options: SAMEORIGIN<\/code><\/pre>\n<p>Valores comunes:<\/p>\n<ul>\n<li><code>DENY<\/code>: nadie puede incrustar la p\u00e1gina en un frame.<\/li>\n<li><code>SAMEORIGIN<\/code>: solo p\u00e1ginas del mismo origen pueden hacerlo.<\/li>\n<\/ul>\n<p>La alternativa moderna es usar <code>frame-ancestors<\/code> dentro de CSP:<\/p>\n<pre><code>Content-Security-Policy: frame-ancestors 'self' https:\/\/socio-autorizado.com<\/code><\/pre>\n<p><code>frame-ancestors<\/code> es m\u00e1s flexible y deber\u00eda preferirse en navegadores modernos. Aun as\u00ed, muchas configuraciones mantienen tambi\u00e9n <code>X-Frame-Options<\/code> por compatibilidad.<\/p>\n<p><strong>Recomendaci\u00f3n pr\u00e1ctica:<\/strong> si tu sitio no necesita ser embebido por terceros, usa <code>frame-ancestors 'self'<\/code> o <code>DENY<\/code>. Si trabajas con pasarelas, plataformas educativas, CRM o integraciones que usan iframes, documenta exactamente qu\u00e9 dominios est\u00e1n permitidos.<\/p>\n<h2>5. Referrer-Policy: discreci\u00f3n en tiempos de rastreo permanente<\/h2>\n<p>Cuando un usuario hace clic desde tu sitio hacia otro, el navegador puede enviar el encabezado <code>Referer<\/code> \u2014s\u00ed, mal escrito hist\u00f3ricamente; la web tambi\u00e9n tiene sus f\u00f3siles ortogr\u00e1ficos\u2014 indicando la URL de origen.<\/p>\n<p>Esto puede revelar informaci\u00f3n sensible: rutas internas, par\u00e1metros, tokens mal dise\u00f1ados, b\u00fasquedas, identificadores. La <code>Referrer-Policy<\/code> controla cu\u00e1nto se comparte.<\/p>\n<p>Valor recomendado para la mayor\u00eda de sitios:<\/p>\n<pre><code>Referrer-Policy: strict-origin-when-cross-origin<\/code><\/pre>\n<p>Este valor suele equilibrar privacidad y funcionalidad:<\/p>\n<ul>\n<li>Env\u00eda la URL completa al navegar dentro del mismo origen.<\/li>\n<li>Env\u00eda solo el origen \u2014por ejemplo, <code>https:\/\/ejemplo.com<\/code>\u2014 al ir a otro sitio HTTPS.<\/li>\n<li>No env\u00eda referrer desde HTTPS hacia HTTP.<\/li>\n<\/ul>\n<p>Opciones m\u00e1s restrictivas:<\/p>\n<pre><code>Referrer-Policy: no-referrer<\/code><\/pre>\n<p>O:<\/p>\n<pre><code>Referrer-Policy: same-origin<\/code><\/pre>\n<p>La elecci\u00f3n depende de anal\u00edtica, afiliaci\u00f3n, integraciones y privacidad. Para sitios con datos sensibles, <code>no-referrer<\/code> puede ser conveniente. Para sitios comerciales que necesitan atribuci\u00f3n b\u00e1sica sin exponer rutas completas, <code>strict-origin-when-cross-origin<\/code> suele ser una buena br\u00fajula.<\/p>\n<h2>6. Permissions-Policy: poner l\u00edmites a las capacidades del navegador \ud83c\udf9b\ufe0f<\/h2>\n<p>Antes conocida como <code>Feature-Policy<\/code>, <code>Permissions-Policy<\/code> permite controlar qu\u00e9 APIs del navegador pueden usarse: c\u00e1mara, micr\u00f3fono, geolocalizaci\u00f3n, aceler\u00f3metro, pantalla completa, pagos, USB, inter\u00e9s cohortado \u2014cuando exist\u00eda FLoC\u2014 y otras funciones.<\/p>\n<p>Ejemplo conservador:<\/p>\n<pre><code>Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), fullscreen=(self)<\/code><\/pre>\n<p>Esto indica:<\/p>\n<ul>\n<li>Nadie puede usar c\u00e1mara.<\/li>\n<li>Nadie puede usar micr\u00f3fono.<\/li>\n<li>Nadie puede solicitar geolocalizaci\u00f3n.<\/li>\n<li>Nadie puede usar pagos del navegador.<\/li>\n<li>Nadie puede usar USB.<\/li>\n<li>Solo el propio sitio puede usar pantalla completa.<\/li>\n<\/ul>\n<p>Si tu aplicaci\u00f3n necesita geolocalizaci\u00f3n, por ejemplo una tienda con buscador de sucursales, puedes permitirla en tu propio origen:<\/p>\n<pre><code>Permissions-Policy: geolocation=(self), camera=(), microphone=()<\/code><\/pre>\n<p>La belleza de este encabezado est\u00e1 en su sobriedad: desactiva lo que no necesitas. En seguridad, lo que no existe no se explota; lo que no se habilita no se abusa.<\/p>\n<h2>7. Cookies seguras: no basta con Set-Cookie<\/h2>\n<p>Aunque <code>Set-Cookie<\/code> no siempre aparece en las listas de \u201csecurity headers\u201d tradicionales, en la pr\u00e1ctica es uno de los puntos m\u00e1s cr\u00edticos. Las cookies sostienen sesiones, carritos, autenticaci\u00f3n, preferencias y tokens. Son peque\u00f1as, persistentes y peligrosamente confiadas si se configuran mal.<\/p>\n<p>Una cookie de sesi\u00f3n deber\u00eda incluir:<\/p>\n<pre><code>Set-Cookie: session_id=abc123; Secure; HttpOnly; SameSite=Lax; Path=\/<\/code><\/pre>\n<p>Atributos esenciales:<\/p>\n<ul>\n<li><code>Secure<\/code>: la cookie solo viaja por HTTPS.<\/li>\n<li><code>HttpOnly<\/code>: JavaScript no puede leerla mediante <code>document.cookie<\/code>, lo que reduce impacto de XSS.<\/li>\n<li><code>SameSite<\/code>: limita el env\u00edo de cookies en solicitudes cross-site y ayuda contra CSRF.<\/li>\n<li><code>Path<\/code> y <code>Domain<\/code>: delimitan alcance.<\/li>\n<li><code>Max-Age<\/code> o <code>Expires<\/code>: controlan duraci\u00f3n.<\/li>\n<\/ul>\n<h3>SameSite: Lax, Strict o None<\/h3>\n<table>\n<thead>\n<tr>\n<th>Valor<\/th>\n<th>Uso habitual<\/th>\n<th>Advertencia<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>SameSite=Strict<\/code><\/td>\n<td>M\u00e1xima protecci\u00f3n cross-site.<\/td>\n<td>Puede romper flujos leg\u00edtimos al venir desde enlaces externos, SSO o pagos.<\/td>\n<\/tr>\n<tr>\n<td><code>SameSite=Lax<\/code><\/td>\n<td>Buen equilibrio para sesiones comunes.<\/td>\n<td>No sustituye tokens CSRF en operaciones sensibles.<\/td>\n<\/tr>\n<tr>\n<td><code>SameSite=None; Secure<\/code><\/td>\n<td>Necesario para cookies de terceros o integraciones cross-site.<\/td>\n<td>Debe llevar <code>Secure<\/code>. \u00dasalo solo si realmente lo necesitas.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>En WordPress, las cookies de autenticaci\u00f3n suelen gestionarse internamente, pero el servidor, un plugin de seguridad o una capa de proxy pueden reforzar atributos en determinados escenarios. Cuidado con \u201carreglar\u201d cookies a ciegas: una tienda WooCommerce, un SSO o un sistema multisitio pueden comportarse como relojes suizos\u2026 hasta que alguien cambia un engranaje con un martillo.<\/p>\n<h2>8. Cache-Control: privacidad tambi\u00e9n es no guardar de m\u00e1s<\/h2>\n<p>El rendimiento web nos ha ense\u00f1ado a cachearlo todo: HTML, CSS, JS, im\u00e1genes, fuentes, respuestas de API. Y est\u00e1 bien. Pero cachear contenido privado en el lugar incorrecto es como dejar expedientes m\u00e9dicos en una cafeter\u00eda porque \u201cas\u00ed se consultan m\u00e1s r\u00e1pido\u201d.<\/p>\n<p>Para p\u00e1ginas p\u00fablicas est\u00e1ticas, puedes usar cach\u00e9 agresiva con versionado:<\/p>\n<pre><code>Cache-Control: public, max-age=31536000, immutable<\/code><\/pre>\n<p>Para \u00e1reas privadas, login, checkout, cuenta de usuario o datos personales:<\/p>\n<pre><code>Cache-Control: no-store, no-cache, must-revalidate, private\nPragma: no-cache\nExpires: 0<\/code><\/pre>\n<p><code>no-store<\/code> indica que la respuesta no debe almacenarse. <code>private<\/code> limita el almacenamiento a cach\u00e9s privadas, aunque para contenido muy sensible conviene ser m\u00e1s restrictivo.<\/p>\n<p>En WordPress y WooCommerce, revisa especialmente:<\/p>\n<ul>\n<li><code>\/wp-admin\/<\/code><\/li>\n<li><code>\/wp-login.php<\/code><\/li>\n<li>P\u00e1ginas de carrito y checkout.<\/li>\n<li>\u00c1rea \u201cMi cuenta\u201d.<\/li>\n<li>Endpoints REST con datos privados.<\/li>\n<li>Paneles de membres\u00eda o LMS.<\/li>\n<\/ul>\n<h2>Encabezados recomendables seg\u00fan el tipo de proyecto<\/h2>\n<p>M\u00e1s all\u00e1 del m\u00ednimo, hay encabezados que pueden ser importantes en arquitecturas modernas, aplicaciones de alto riesgo o proyectos con integraciones complejas. Aqu\u00ed el mapa se vuelve m\u00e1s interesante.<\/p>\n<h3>Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy y Cross-Origin-Resource-Policy<\/h3>\n<p>Estos encabezados ayudan a aislar contextos de navegaci\u00f3n y recursos entre or\u00edgenes. Son especialmente relevantes si necesitas <strong>cross-origin isolation<\/strong>, por ejemplo para usar ciertas APIs como <code>SharedArrayBuffer<\/code> de forma segura.<\/p>\n<pre><code>Cross-Origin-Opener-Policy: same-origin\nCross-Origin-Embedder-Policy: require-corp\nCross-Origin-Resource-Policy: same-origin<\/code><\/pre>\n<p>Pero cuidado: pueden romper recursos embebidos de terceros si no est\u00e1n preparados. Aqu\u00ed la seguridad y la compatibilidad se miran como dos duelistas al amanecer. Antes de aplicarlos globalmente, prueba en staging.<\/p>\n<ul>\n<li><code>COOP<\/code> ayuda a separar tu ventana de otras ventanas cross-origin.<\/li>\n<li><code>COEP<\/code> exige que los recursos embebidos permitan expl\u00edcitamente ser cargados.<\/li>\n<li><code>CORP<\/code> indica qui\u00e9n puede cargar tus recursos.<\/li>\n<\/ul>\n<h3>Access-Control-Allow-Origin: CORS no es un escudo m\u00e1gico<\/h3>\n<p>CORS merece una menci\u00f3n especial porque suele confundirse con seguridad del servidor. <code>Access-Control-Allow-Origin<\/code> no protege tus datos por s\u00ed mismo; regula qu\u00e9 or\u00edgenes pueden leer respuestas desde navegadores. Un atacante puede seguir haciendo solicitudes desde herramientas fuera del navegador si no hay autenticaci\u00f3n adecuada.<\/p>\n<p>Configuraci\u00f3n peligrosa si se combina con credenciales:<\/p>\n<pre><code>Access-Control-Allow-Origin: *\nAccess-Control-Allow-Credentials: true<\/code><\/pre>\n<p>De hecho, los navegadores no permiten esa combinaci\u00f3n exacta con credenciales, pero muchas configuraciones din\u00e1micas reflejan cualquier origen y a\u00f1aden credenciales. Resultado: una puerta giratoria con alfombra roja.<\/p>\n<p>Mejor:<\/p>\n<pre><code>Access-Control-Allow-Origin: https:\/\/app.tudominio.com\nAccess-Control-Allow-Credentials: true\nVary: Origin<\/code><\/pre>\n<p>Usa listas blancas expl\u00edcitas, valida el encabezado <code>Origin<\/code> y a\u00f1ade <code>Vary: Origin<\/code> cuando la respuesta cambie seg\u00fan el origen.<\/p>\n<h3>Vary: Origin<\/h3>\n<p><code>Vary<\/code> no es un encabezado de seguridad en sentido estricto, pero en CORS ayuda a evitar que una cach\u00e9 sirva a un origen una respuesta generada para otro. En entornos con CDN, proxies y APIs, puede marcar la diferencia entre una configuraci\u00f3n limpia y una fuga sutil.<\/p>\n<pre><code>Vary: Origin<\/code><\/pre>\n<h2>Encabezados obsoletos o que conviene evitar<\/h2>\n<p>No todo lo que suena a seguridad sigue siendo recomendable. La web envejece r\u00e1pido; algunos encabezados que antes eran h\u00e9roes hoy son estatuas con palomas encima.<\/p>\n<table>\n<thead>\n<tr>\n<th>Encabezado<\/th>\n<th>Estado actual<\/th>\n<th>Recomendaci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>X-XSS-Protection<\/code><\/td>\n<td>Obsoleto en navegadores modernos.<\/td>\n<td>Preferible desactivarlo con <code>0<\/code> o no depender de \u00e9l. Usa CSP.<\/td>\n<\/tr>\n<tr>\n<td><code>Public-Key-Pins<\/code> \/ HPKP<\/td>\n<td>Obsoleto y peligroso.<\/td>\n<td>No usar. Pod\u00eda dejar dominios inaccesibles por errores de pinning.<\/td>\n<\/tr>\n<tr>\n<td><code>Expect-CT<\/code><\/td>\n<td>Obsoleto en la pr\u00e1ctica tras la obligatoriedad de Certificate Transparency en Chrome.<\/td>\n<td>No es necesario para la mayor\u00eda de sitios.<\/td>\n<\/tr>\n<tr>\n<td><code>X-Powered-By<\/code><\/td>\n<td>Expone tecnolog\u00eda, no aporta seguridad.<\/td>\n<td>Eliminar o minimizar informaci\u00f3n.<\/td>\n<\/tr>\n<tr>\n<td><code>Server<\/code><\/td>\n<td>Puede revelar versi\u00f3n del servidor.<\/td>\n<td>Reducir detalle si es posible, aunque no sustituye parcheo.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Sobre <code>X-XSS-Protection<\/code>, algunos equipos a\u00fan lo a\u00f1aden por costumbre:<\/p>\n<pre><code>X-XSS-Protection: 1; mode=block<\/code><\/pre>\n<p>Sin embargo, los filtros XSS integrados en navegadores han sido retirados o deshabilitados en muchos casos porque pod\u00edan generar comportamientos inseguros. Si necesitas poner algo por compatibilidad, muchos especialistas prefieren:<\/p>\n<pre><code>X-XSS-Protection: 0<\/code><\/pre>\n<p>Lo importante: no lo cuentes como defensa principal.<\/p>\n<h2>Configuraci\u00f3n recomendada de base para un sitio est\u00e1ndar<\/h2>\n<p>Para un sitio corporativo, blog profesional, WordPress b\u00e1sico o web de servicios sin funcionalidades extra\u00f1as, una base inicial podr\u00eda ser:<\/p>\n<pre><code>Strict-Transport-Security: max-age=31536000; includeSubDomains\nX-Content-Type-Options: nosniff\nReferrer-Policy: strict-origin-when-cross-origin\nX-Frame-Options: SAMEORIGIN\nPermissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()\nContent-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests<\/code><\/pre>\n<p>Pero no copies y pegues sin pensar. Una CSP demasiado estricta puede bloquear fuentes de Google, scripts de anal\u00edtica, p\u00edxeles publicitarios, mapas, reCAPTCHA, v\u00eddeos incrustados, chats y pasarelas de pago. Una pol\u00edtica demasiado laxa, en cambio, se convierte en un adorno: elegante, in\u00fatil, perfectamente auditable por alguien que no mira de cerca.<\/p>\n<h2>Ejemplos para Apache<\/h2>\n<p>En Apache, normalmente se usa el m\u00f3dulo <code>mod_headers<\/code>. Aseg\u00farate de que est\u00e9 habilitado.<\/p>\n<pre><code>&lt;IfModule mod_headers.c&gt;\n  Header always set Strict-Transport-Security \"max-age=31536000; includeSubDomains\"\n  Header always set X-Content-Type-Options \"nosniff\"\n  Header always set Referrer-Policy \"strict-origin-when-cross-origin\"\n  Header always set X-Frame-Options \"SAMEORIGIN\"\n  Header always set Permissions-Policy \"camera=(), microphone=(), geolocation=(), payment=(), usb=()\"\n  Header always set Content-Security-Policy \"default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests\"\n&lt;\/IfModule&gt;<\/code><\/pre>\n<p>Para ocultar <code>X-Powered-By<\/code> en PHP:<\/p>\n<pre><code>expose_php = Off<\/code><\/pre>\n<p>Y en Apache, reducir firma del servidor:<\/p>\n<pre><code>ServerTokens Prod\nServerSignature Off<\/code><\/pre>\n<h2>Ejemplos para Nginx<\/h2>\n<p>En Nginx, se usa <code>add_header<\/code>. Conviene a\u00f1adir <code>always<\/code> para que los encabezados tambi\u00e9n aparezcan en respuestas de error.<\/p>\n<pre><code>add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\" always;\nadd_header X-Content-Type-Options \"nosniff\" always;\nadd_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\nadd_header X-Frame-Options \"SAMEORIGIN\" always;\nadd_header Permissions-Policy \"camera=(), microphone=(), geolocation=(), payment=(), usb=()\" always;\nadd_header Content-Security-Policy \"default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests\" always;<\/code><\/pre>\n<p>Para \u00e1reas privadas:<\/p>\n<pre><code>location ~* ^\/(wp-admin|wp-login\\.php|mi-cuenta|checkout|carrito) {\n  add_header Cache-Control \"no-store, no-cache, must-revalidate, private\" always;\n  add_header Pragma \"no-cache\" always;\n  add_header Expires \"0\" always;\n}<\/code><\/pre>\n<p>Nota: en Nginx, <code>add_header<\/code> tiene reglas de herencia que pueden sorprender. Si defines encabezados dentro de un bloque <code>location<\/code>, podr\u00edas sobrescribir los heredados. Es uno de esos detalles que parecen menores hasta que una auditor\u00eda te muestra que tus headers desaparecen justo en la p\u00e1gina de login. Peque\u00f1as tragedias de configuraci\u00f3n.<\/p>\n<h2>WordPress: seguridad realista en un ecosistema lleno de plugins \ud83e\udde9<\/h2>\n<p>WordPress no es inseguro por naturaleza, pero es extensible hasta el v\u00e9rtigo. Temas, constructores, plugins, shortcodes, scripts externos, AJAX, REST API, WooCommerce, formularios, p\u00edxeles, fuentes, CDN. Es una ciudad con muchos barrios y demasiadas llaves.<\/p>\n<p>Para WordPress, los encabezados de seguridad pueden configurarse en:<\/p>\n<ul>\n<li>El servidor web: Apache, Nginx, LiteSpeed.<\/li>\n<li>El panel del hosting.<\/li>\n<li>Cloudflare u otro CDN\/WAF.<\/li>\n<li>Plugins de seguridad.<\/li>\n<li>C\u00f3digo personalizado en el tema o un plugin propio.<\/li>\n<\/ul>\n<h3>\u00bfD\u00f3nde conviene configurarlos?<\/h3>\n<p>Preferiblemente en el <strong>servidor o CDN<\/strong>. As\u00ed se aplican antes de que WordPress procese la solicitud y tambi\u00e9n pueden cubrir archivos est\u00e1ticos, redirecciones y respuestas de error. Configurarlos mediante PHP puede funcionar para HTML, pero no siempre para im\u00e1genes, CSS, JS o errores generados por el servidor.<\/p>\n<h3>CSP en WordPress: paciencia, bistur\u00ed y registros<\/h3>\n<p>Una CSP estricta en WordPress puede ser dif\u00edcil porque muchos plugins insertan scripts inline. Lo sensato:<\/p>\n<ol>\n<li>Auditar scripts externos actuales.<\/li>\n<li>Activar CSP en modo <code>Report-Only<\/code>.<\/li>\n<li>Recolectar violaciones durante varios d\u00edas.<\/li>\n<li>Ajustar dominios permitidos.<\/li>\n<li>Eliminar plugins innecesarios o demasiado invasivos.<\/li>\n<li>Pasar a modo bloqueo gradualmente.<\/li>\n<\/ol>\n<p>Una CSP m\u00e1s realista para un WordPress con recursos externos podr\u00eda parecerse a esto \u2014debes adaptarla\u2014:<\/p>\n<pre><code>Content-Security-Policy: default-src 'self'; script-src 'self' https:\/\/www.googletagmanager.com https:\/\/www.google-analytics.com; style-src 'self' 'unsafe-inline' https:\/\/fonts.googleapis.com; font-src 'self' https:\/\/fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https:\/\/www.google-analytics.com; frame-src https:\/\/www.youtube.com; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests<\/code><\/pre>\n<p>No es perfecta porque permite <code>'unsafe-inline'<\/code> en estilos, algo frecuente por compatibilidad. El objetivo es mejorar progresivamente. La seguridad web rara vez se parece a encender una luz; se parece m\u00e1s a limpiar una casa vieja: levantas una alfombra y aparece otra historia.<\/p>\n<h2>Cloudflare y CDN: \u00fatiles, pero no m\u00e1gicos \u2601\ufe0f<\/h2>\n<p>CDN y proxies como Cloudflare, Fastly, Akamai o BunnyCDN pueden a\u00f1adir encabezados en el borde. Esto es \u00fatil porque centraliza pol\u00edticas y evita tocar m\u00faltiples servidores. En Cloudflare, por ejemplo, puedes usar <strong>Rules<\/strong>, <strong>Transform Rules<\/strong> o configuraciones espec\u00edficas de seguridad seg\u00fan el plan.<\/p>\n<p>Ventajas:<\/p>\n<ul>\n<li>Aplicaci\u00f3n r\u00e1pida sin modificar c\u00f3digo.<\/li>\n<li>Pol\u00edticas consistentes para m\u00faltiples or\u00edgenes.<\/li>\n<li>Posibilidad de ajustar por ruta.<\/li>\n<li>Integraci\u00f3n con WAF y cach\u00e9.<\/li>\n<\/ul>\n<p>Riesgos:<\/p>\n<ul>\n<li>Duplicar encabezados con valores contradictorios.<\/li>\n<li>Aplicar CSP global que rompe p\u00e1ginas espec\u00edficas.<\/li>\n<li>Creer que el CDN protege tambi\u00e9n accesos directos al servidor de origen si este queda expuesto.<\/li>\n<li>Olvidar entornos staging, subdominios o APIs.<\/li>\n<\/ul>\n<p>La regla de oro: define qui\u00e9n manda. Si el servidor y el CDN configuran los mismos encabezados, documenta la jerarqu\u00eda. La seguridad sin documentaci\u00f3n se convierte en arqueolog\u00eda para el pr\u00f3ximo desarrollador.<\/p>\n<h2>Qu\u00e9 encabezados revisar en APIs<\/h2>\n<p>Las APIs no cargan p\u00e1ginas HTML, pero tambi\u00e9n necesitan atenci\u00f3n. Para APIs JSON, algunos encabezados son especialmente relevantes:<\/p>\n<ul>\n<li><code>Content-Type: application\/json; charset=utf-8<\/code><\/li>\n<li><code>X-Content-Type-Options: nosniff<\/code><\/li>\n<li><code>Cache-Control: no-store<\/code> en respuestas sensibles.<\/li>\n<li>CORS estricto si la API se consume desde navegadores.<\/li>\n<li><code>Vary: Origin<\/code> si el CORS var\u00eda por origen.<\/li>\n<li>Cookies con <code>Secure<\/code>, <code>HttpOnly<\/code> y <code>SameSite<\/code> si se usa autenticaci\u00f3n basada en cookies.<\/li>\n<\/ul>\n<p>Para APIs p\u00fablicas con tokens Bearer, no conf\u00edes en CORS como control de acceso. Autenticaci\u00f3n, autorizaci\u00f3n, rate limiting, validaci\u00f3n y registros siguen siendo imprescindibles. CORS decide qui\u00e9n puede leer desde el navegador; no decide qui\u00e9n tiene derecho a los datos.<\/p>\n<h2>Herramientas para comprobar tus encabezados<\/h2>\n<p>No hace falta adivinar. Puedes comprobar los Security Headers con herramientas p\u00fablicas y comandos locales.<\/p>\n<h3>Herramientas online<\/h3>\n<ul>\n<li><strong>Mozilla Observatory:<\/strong> eval\u00faa encabezados, TLS, cookies y buenas pr\u00e1cticas.<\/li>\n<li><strong>SecurityHeaders.com:<\/strong> ofrece una calificaci\u00f3n r\u00e1pida y clara.<\/li>\n<li><strong>SSL Labs:<\/strong> excelente para revisar TLS\/SSL, certificados y protocolos.<\/li>\n<li><strong>Google Lighthouse:<\/strong> incluye auditor\u00edas \u00fatiles, aunque no sustituye una revisi\u00f3n de seguridad.<\/li>\n<\/ul>\n<h3>Con cURL<\/h3>\n<pre><code>curl -I https:\/\/tudominio.com<\/code><\/pre>\n<p>Para seguir redirecciones:<\/p>\n<pre><code>curl -I -L https:\/\/tudominio.com<\/code><\/pre>\n<p>Para revisar una ruta concreta:<\/p>\n<pre><code>curl -I https:\/\/tudominio.com\/wp-login.php<\/code><\/pre>\n<p>La revisi\u00f3n debe hacerse en varias rutas: home, login, panel, checkout, API, errores 404, archivos est\u00e1ticos y subdominios. M\u00e1s de una vez he visto sitios con una calificaci\u00f3n perfecta en la portada y un agujero discreto en <code>\/admin<\/code>. Como esas fachadas impecables de algunos pueblos donde la parte trasera da a un patio lleno de trastos.<\/p>\n<h2>Errores frecuentes al implementar Security Headers<\/h2>\n<h3>1. Copiar pol\u00edticas de otro sitio<\/h3>\n<p>La CSP de una aplicaci\u00f3n bancaria no sirve necesariamente para una revista digital con publicidad program\u00e1tica. La configuraci\u00f3n de un SaaS con React no encaja sin m\u00e1s en WordPress. Copiar encabezados sin entenderlos es como tomar medicaci\u00f3n ajena porque ambos tienen fiebre.<\/p>\n<h3>2. Activar HSTS preload demasiado pronto<\/h3>\n<p>Antes de usar <code>preload<\/code>, verifica:<\/p>\n<ul>\n<li>HTTPS v\u00e1lido en dominio ra\u00edz.<\/li>\n<li>HTTPS v\u00e1lido en todos los subdominios.<\/li>\n<li>Redirecci\u00f3n HTTP a HTTPS correcta.<\/li>\n<li><code>max-age<\/code> m\u00ednimo de 31536000.<\/li>\n<li><code>includeSubDomains<\/code> activo.<\/li>\n<li>Capacidad operativa para mantener HTTPS siempre.<\/li>\n<\/ul>\n<h3>3. Usar CSP con comodines excesivos<\/h3>\n<p><code>script-src *<\/code> o <code>default-src *<\/code> reducen much\u00edsimo la utilidad de CSP. A veces son necesarios temporalmente durante una migraci\u00f3n, pero deben tener fecha de caducidad. La excepci\u00f3n permanente es la forma administrativa del abandono.<\/p>\n<h3>4. Olvidar p\u00e1ginas de error<\/h3>\n<p>Los encabezados deber\u00edan aplicarse tambi\u00e9n en 404, 500, redirecciones y respuestas generadas por el servidor. Por eso en Nginx y Apache es importante usar directivas que apliquen \u201calways\u201d cuando corresponda.<\/p>\n<h3>5. Duplicar encabezados contradictorios<\/h3>\n<p>Si Cloudflare env\u00eda una CSP y tu servidor env\u00eda otra, el navegador puede aplicar ambas o comportarse de forma inesperada seg\u00fan el encabezado. Lo mismo ocurre con <code>X-Frame-Options<\/code>, CORS o <code>Cache-Control<\/code>.<\/p>\n<h3>6. Ignorar terceros<\/h3>\n<p>Google Analytics, Tag Manager, Meta Pixel, YouTube, Stripe, PayPal, reCAPTCHA, mapas, chatbots, fuentes externas, CDN de librer\u00edas. Cada tercero ampl\u00eda la superficie de ataque y complica CSP. No se trata de vivir en una cueva, pero s\u00ed de saber qui\u00e9n entra a casa.<\/p>\n<h2>Pol\u00edtica m\u00ednima recomendada por tipo de sitio<\/h2>\n<table>\n<thead>\n<tr>\n<th>Tipo de sitio<\/th>\n<th>Encabezados m\u00ednimos recomendados<\/th>\n<th>Notas<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Blog o web corporativa simple<\/td>\n<td>HSTS, CSP b\u00e1sica, X-Content-Type-Options, Referrer-Policy, X-Frame-Options\/frame-ancestors, Permissions-Policy<\/td>\n<td>Revisar scripts de anal\u00edtica, fuentes y formularios.<\/td>\n<\/tr>\n<tr>\n<td>WordPress con plugins<\/td>\n<td>Los anteriores + cookies seguras + CSP gradual en Report-Only<\/td>\n<td>Especial cuidado con constructores visuales, formularios y plugins de marketing.<\/td>\n<\/tr>\n<tr>\n<td>WooCommerce o e-commerce<\/td>\n<td>Todos los m\u00ednimos + Cache-Control privado en checkout\/cuenta + cookies robustas<\/td>\n<td>Validar pasarelas de pago, iframes y redirecciones externas.<\/td>\n<\/tr>\n<tr>\n<td>SaaS o aplicaci\u00f3n con login<\/td>\n<td>Todos + CSP con nonces\/hashes + COOP\/COEP\/CORP si aplica + CORS estricto<\/td>\n<td>Integrar headers en pipeline CI\/CD y pruebas automatizadas.<\/td>\n<\/tr>\n<tr>\n<td>API privada<\/td>\n<td>X-Content-Type-Options, Cache-Control, CORS estricto, Vary: Origin, cookies seguras si aplica<\/td>\n<td>No confiar en CORS como autenticaci\u00f3n.<\/td>\n<\/tr>\n<tr>\n<td>Administraci\u00f3n p\u00fablica o sector regulado<\/td>\n<td>Pol\u00edtica completa documentada, auditor\u00eda peri\u00f3dica, HSTS fuerte, CSP rigurosa, registros<\/td>\n<td>Alinear con ENS, ISO 27001, OWASP ASVS o requisitos internos.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>\u00bfC\u00f3mo priorizar si partes de cero?<\/h2>\n<p>Si tu sitio no tiene ning\u00fan encabezado de seguridad, no intentes resolverlo todo en una tarde heroica. La heroicidad en producci\u00f3n suele dejar tickets al d\u00eda siguiente.<\/p>\n<ol>\n<li><strong>Confirma HTTPS completo:<\/strong> certificado v\u00e1lido, redirecciones limpias, sin contenido mixto.<\/li>\n<li><strong>A\u00f1ade <code>X-Content-Type-Options<\/code>:<\/strong> bajo riesgo, alto beneficio.<\/li>\n<li><strong>A\u00f1ade <code>Referrer-Policy<\/code>:<\/strong> normalmente no rompe nada.<\/li>\n<li><strong>A\u00f1ade protecci\u00f3n contra iframes:<\/strong> <code>X-Frame-Options<\/code> o <code>frame-ancestors<\/code>.<\/li>\n<li><strong>Configura HSTS progresivamente:<\/strong> empieza con <code>max-age<\/code> bajo, luego aumenta.<\/li>\n<li><strong>Implementa <code>Permissions-Policy<\/code>:<\/strong> bloquea APIs que no usas.<\/li>\n<li><strong>Dise\u00f1a CSP en modo Report-Only:<\/strong> observa, ajusta y luego bloquea.<\/li>\n<li><strong>Revisa cookies y cach\u00e9:<\/strong> especialmente si hay login, pagos o datos personales.<\/li>\n<li><strong>Automatiza pruebas:<\/strong> para que los encabezados no desaparezcan en el pr\u00f3ximo despliegue.<\/li>\n<\/ol>\n<p><strong>Checklist r\u00e1pida para producci\u00f3n \u2705<\/strong><\/p>\n<ul>\n<li>HTTPS activo en todo el sitio.<\/li>\n<li>Redirecci\u00f3n HTTP \u2192 HTTPS sin cadenas innecesarias.<\/li>\n<li><code>Strict-Transport-Security<\/code> configurado con cuidado.<\/li>\n<li><code>X-Content-Type-Options: nosniff<\/code>.<\/li>\n<li><code>Referrer-Policy<\/code> definida.<\/li>\n<li>Protecci\u00f3n anti-clickjacking con <code>frame-ancestors<\/code> o <code>X-Frame-Options<\/code>.<\/li>\n<li><code>Permissions-Policy<\/code> restrictiva.<\/li>\n<li>CSP probada, preferiblemente sin comodines peligrosos.<\/li>\n<li>Cookies con <code>Secure<\/code>, <code>HttpOnly<\/code> y <code>SameSite<\/code>.<\/li>\n<li><code>Cache-Control<\/code> adecuado para contenido privado.<\/li>\n<li>Sin encabezados obsoletos usados como defensa principal.<\/li>\n<li>Headers presentes tambi\u00e9n en errores, redirecciones y rutas sensibles.<\/li>\n<\/ul>\n<h2>Security Headers y rendimiento: \u00bfafectan la velocidad?<\/h2>\n<p>En t\u00e9rminos generales, los encabezados de seguridad tienen un impacto m\u00ednimo en rendimiento. Son texto. Apenas pesan. Lo que s\u00ed puede afectar indirectamente es una pol\u00edtica CSP mal planteada que bloquee recursos, genere errores o impida optimizaciones.<\/p>\n<p>HSTS incluso puede mejorar la experiencia al evitar intentos iniciales por HTTP despu\u00e9s de quedar registrado en el navegador. <code>upgrade-insecure-requests<\/code> ayuda durante migraciones a HTTPS, aunque no debe usarse como sustituto de corregir URLs internas.<\/p>\n<p>La verdadera relaci\u00f3n entre seguridad y rendimiento aparece en otro plano: menos scripts de terceros, menor superficie de ataque, menos dependencias, menos llamadas externas. Un sitio sobrio suele ser m\u00e1s r\u00e1pido y m\u00e1s seguro. Ant\u00edtesis feliz: cuanto menos ruido, m\u00e1s defensa.<\/p>\n<h2>Security Headers no sustituyen otras medidas<\/h2>\n<p>Ser\u00eda c\u00f3modo pensar que unos encabezados bien puestos bastan. No basta. Ayudan mucho, pero no reemplazan:<\/p>\n<ul>\n<li>Actualizaciones de CMS, temas, plugins y dependencias.<\/li>\n<li>Validaci\u00f3n y sanitizaci\u00f3n de entradas.<\/li>\n<li>Escape correcto de salidas.<\/li>\n<li>Autenticaci\u00f3n multifactor.<\/li>\n<li>Principio de m\u00ednimo privilegio.<\/li>\n<li>Copias de seguridad verificadas.<\/li>\n<li>WAF bien configurado.<\/li>\n<li>Monitorizaci\u00f3n de logs.<\/li>\n<li>Protecci\u00f3n contra fuerza bruta.<\/li>\n<li>Revisi\u00f3n de permisos de archivos.<\/li>\n<li>Gesti\u00f3n segura de secretos y claves API.<\/li>\n<\/ul>\n<p>Los encabezados son una muralla, no el reino completo. Y una muralla con puertas mal vigiladas solo sirve para dar sombra.<\/p>\n<h2>Una configuraci\u00f3n m\u00e1s avanzada como punto de partida<\/h2>\n<p>Para una aplicaci\u00f3n web moderna con control sobre el frontend y backend, podr\u00edas aspirar a algo m\u00e1s estricto:<\/p>\n<pre><code>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\nX-Content-Type-Options: nosniff\nReferrer-Policy: strict-origin-when-cross-origin\nPermissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()\nCross-Origin-Opener-Policy: same-origin\nCross-Origin-Resource-Policy: same-origin\nContent-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{RANDOM}'; style-src 'self' 'nonce-{RANDOM}'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https:\/\/api.tudominio.com; frame-ancestors 'none'; object-src 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests<\/code><\/pre>\n<p>Si necesitas aislamiento completo:<\/p>\n<pre><code>Cross-Origin-Embedder-Policy: require-corp<\/code><\/pre>\n<p>Pero solo tras verificar que tus recursos externos env\u00edan permisos adecuados. De lo contrario, ver\u00e1s c\u00f3mo partes del sitio desaparecen con la elegancia cruel de una marea que se lleva castillos de arena.<\/p>\n<h2>Preguntas frecuentes<\/h2>\n<h3>\u00bfNecesito todos los encabezados si mi sitio solo es informativo?<\/h3>\n<p>No todos, pero s\u00ed una base. Incluso un sitio informativo puede sufrir XSS por plugins, formularios, scripts de terceros o malas configuraciones. Como m\u00ednimo: HSTS si usas HTTPS correctamente, <code>X-Content-Type-Options<\/code>, <code>Referrer-Policy<\/code>, protecci\u00f3n contra iframes, <code>Permissions-Policy<\/code> y una CSP b\u00e1sica.<\/p>\n<h3>\u00bfPuedo configurar Security Headers desde un plugin de WordPress?<\/h3>\n<p>S\u00ed, pero no siempre es lo ideal. Un plugin puede funcionar para respuestas generadas por WordPress, aunque tal vez no cubra archivos est\u00e1ticos, errores del servidor o determinadas redirecciones. Si puedes, configura en servidor o CDN. Si no, un buen plugin es mejor que nada, siempre que se pruebe bien.<\/p>\n<h3>\u00bfUna buena puntuaci\u00f3n en SecurityHeaders.com significa que estoy seguro?<\/h3>\n<p>No necesariamente. Significa que ciertos encabezados est\u00e1n presentes y tienen una forma aceptable. Es \u00fatil, pero no mide toda la seguridad: l\u00f3gica de negocio, vulnerabilidades en plugins, contrase\u00f1as d\u00e9biles, permisos mal configurados, inyecciones SQL, exposici\u00f3n de backups o APIs sin control.<\/p>\n<h3>\u00bfCSP puede romper mi sitio?<\/h3>\n<p>S\u00ed. Por eso conviene usar <code>Content-Security-Policy-Report-Only<\/code> antes de bloquear. CSP es potente precisamente porque restringe. Y todo lo que restringe puede cortar algo que alguien daba por sentado.<\/p>\n<h3>\u00bfDebo eliminar el encabezado Server?<\/h3>\n<p>Reducir informaci\u00f3n expuesta es buena pr\u00e1ctica, pero no es una defensa fuerte. Ocultar que usas Nginx o Apache no protege un servidor sin parches. La discreci\u00f3n ayuda; el mantenimiento salva.<\/p>\n<h3>\u00bfQu\u00e9 hago con sitios que necesitan ser embebidos en iframes?<\/h3>\n<p>Usa <code>frame-ancestors<\/code> en CSP y permite solo dominios espec\u00edficos. Evita permitir <code>*<\/code>. Documenta qui\u00e9n puede embeber tu sitio y por qu\u00e9.<\/p>\n<h2>La parte humana: seguridad como h\u00e1bito, no como ceremonia<\/h2>\n<p>Hace a\u00f1os, en una migraci\u00f3n peque\u00f1a \u2014de esas que en teor\u00eda se resuelven antes del caf\u00e9\u2014 encontr\u00e9 un panel administrativo servido por HTTPS, protegido con contrase\u00f1a fuerte y, sin embargo, embebible desde cualquier dominio. Nadie lo hab\u00eda notado. No hab\u00eda drama visible. No sonaban alarmas. La vulnerabilidad estaba all\u00ed, quieta, como una gotera detr\u00e1s de una pared reci\u00e9n pintada.<\/p>\n<p>Eso tienen los encabezados HTTP: pertenecen al reino de lo invisible. No cambian el hero banner, no mejoran el logo, no hacen que el cliente diga \u201cqu\u00e9 bonito qued\u00f3 el sitio\u201d. Pero cuando faltan, el navegador pierde instrucciones esenciales. Y cuando est\u00e1n bien puestos, muchas amenazas encuentran la puerta cerrada antes incluso de empezar la conversaci\u00f3n.<\/p>\n<p>La seguridad web madura no consiste en llenar el servidor de amuletos t\u00e9cnicos. Consiste en entender el riesgo, aplicar controles adecuados, medir, ajustar y volver a revisar. Es menos \u00e9pica que una pel\u00edcula de hackers; m\u00e1s parecida a revisar cerraduras antes de dormir. Aburrida, tal vez. Eficaz, sin duda.<\/p>\n<h2>Resumen pr\u00e1ctico: qu\u00e9 encabezados deber\u00edas tener<\/h2>\n<p>Si administras un servidor, una web en WordPress, una tienda online o una aplicaci\u00f3n profesional, estos son los encabezados que deber\u00edas considerar como base m\u00ednima:<\/p>\n<ul>\n<li><span>Imprescindible<\/span><code>Strict-Transport-Security<\/code>, si todo funciona correctamente con HTTPS.<\/li>\n<li><span>Imprescindible<\/span><code>Content-Security-Policy<\/code>, al menos en una versi\u00f3n b\u00e1sica y preferiblemente evolucionada.<\/li>\n<li><span>Imprescindible<\/span><code>X-Content-Type-Options: nosniff<\/code>.<\/li>\n<li><span>Imprescindible<\/span><code>Referrer-Policy: strict-origin-when-cross-origin<\/code> o una opci\u00f3n m\u00e1s restrictiva.<\/li>\n<li><span>Imprescindible<\/span><code>X-Frame-Options<\/code> o, mejor, <code>frame-ancestors<\/code> en CSP.<\/li>\n<li><span>Muy recomendable<\/span><code>Permissions-Policy<\/code> para limitar APIs del navegador.<\/li>\n<li><span>Cr\u00edtico con sesiones<\/span>Cookies con <code>Secure<\/code>, <code>HttpOnly<\/code> y <code>SameSite<\/code>.<\/li>\n<li><span>Cr\u00edtico en datos privados<\/span><code>Cache-Control<\/code> adecuado para evitar almacenamiento indebido.<\/li>\n<li><span>Seg\u00fan arquitectura<\/span><code>COOP<\/code>, <code>COEP<\/code> y <code>CORP<\/code> para aislamiento avanzado.<\/li>\n<li><span>Con cuidado<\/span>CORS estricto y bien documentado en APIs.<\/li>\n<\/ul>\n<p>El servidor perfecto no existe. El sitio invulnerable tampoco. Pero entre la perfecci\u00f3n imposible y el abandono c\u00f3modo hay un territorio profesional donde se configuran encabezados, se prueban rutas, se reducen permisos y se documentan decisiones. Ah\u00ed vive la seguridad real: no en el gesto grandilocuente, sino en la suma de peque\u00f1as \u00f3rdenes bien dadas.<\/p>\n<p>Y el navegador, que no tiene intuici\u00f3n ni memoria moral, agradece esas \u00f3rdenes. Obedece. Bloquea. Restringe. Protege. A veces, unas l\u00edneas en una respuesta HTTP son la diferencia entre una p\u00e1gina que simplemente carga y una p\u00e1gina que sabe defenderse. \ud83d\ude80<\/p>\n<\/article>\n","protected":false},"excerpt":{"rendered":"<p>\u00bfQu\u00e9 encabezados de seguridad HTTP son obligatorios en tu servidor? \ud83d\udee1\ufe0f Un sitio web sin<\/p>\n","protected":false},"author":1,"featured_media":3900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[],"_seopress_pro_schemas_manual":[],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-3901","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mantenimiento"],"_links":{"self":[{"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/posts\/3901","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/comments?post=3901"}],"version-history":[{"count":1,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/posts\/3901\/revisions"}],"predecessor-version":[{"id":3902,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/posts\/3901\/revisions\/3902"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/media\/3900"}],"wp:attachment":[{"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/media?parent=3901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/categories?post=3901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mantenimientoweb.pro\/blog\/wp-json\/wp\/v2\/tags?post=3901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}