<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">

<channel>
	<title>Ayuda WordPress</title>
	<atom:link href="https://ayudawp.com/feed/" rel="self" type="application/rss+xml"/>
	<link>https://ayudawp.com</link>
	<description>Recursos, temas, plugins, tutoriales en español</description>
	<lastBuildDate>Mon, 13 Jul 2026 09:07:22 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://ayudawp.com/wp-content/uploads/2026/05/cropped-ayuda-wordpress-32x32.png</url>
	<title>Ayuda WordPress</title>
	<link>https://ayudawp.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<xhtml:meta content="noindex" name="robots" xmlns:xhtml="http://www.w3.org/1999/xhtml"/><item>
		<title>¿Debo bloquear a los bots de IA que rastrean WordPress? Cómo se hace y qué afecta al SEO, AEO y a la visibilidad en IAs</title>
		<link>https://ayudawp.com/bloquear-bots-ia/</link>
					<comments>https://ayudawp.com/bloquear-bots-ia/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 16 Jul 2026 06:28:07 +0000</pubDate>
				<category><![CDATA[IA + WordPress]]></category>
		<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[VigIA]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159840</guid>

					<description><![CDATA[La pregunta que más me hacéis los que tenéis VigIA instalado no es «¿cómo bloqueo a las IA?», es la de fondo: «¿me conviene bloquearlas o no?»]]></description>
										<content:encoded><![CDATA[<p>La pregunta que más me hacéis los que tenéis <a href="https://es.wordpress.org/plugins/vigia/">VigIA</a> instalado no es «<strong>¿cómo bloqueo a las IA?</strong>», es la de fondo: <strong>«¿me conviene bloquearlas o no?»</strong>.</p>
<p>O sea, que <strong>si le cierro el paso a los rastreadores de inteligencia artificial</strong> que me entran en la web,<strong> ¿me estoy protegiendo o  pegando un tiro en el pie con el SEO y con mi visibilidad en las propias IA?</strong></p>
<p>Es una pregunta de las buenas, y casi todo el mundo la responde mal por dos motivos.</p>
<p>El primero es porque <strong>confunde declarar con bloquear</strong>, que no es lo mismo, una cosa es pedirle al bot que no lo haga y otra impedírselo de verdad, y luego está el hecho de que se decide a la brava, sin pararse a pensar qué le cuesta eso al posicionamiento.</p>
<p>Vamos a ponerlo en orden, con datos, y en mi opinión (y experiencia) son cuatro pasos:</p>
<ol>
<li><strong>Analizar</strong> qué puedes hacer y cómo se aplica cada cosa</li>
<li><strong>Saber</strong> (realmente) a qué hacen caso las IA y a qué no.</li>
<li>Lo más importante, <strong>razonar</strong> si a ti te conviene para el SEO y en qué casos.</li>
<li>Y al final, con toda la información en la mano, <strong>decidir</strong> qué haces con tu web.</li>
</ol>
<p>Vamos a verlo con calma.</p>
<h2>Ah ¿pero se puede bloquear a las IAs?</h2>
<p>Antes de decidir conviene saber qué tienes disponible, porque es más de lo que crees y no todo hace lo mismo. Y hay una línea que lo separa todo, porque <strong>unas acciones declaran tu voluntad (solo surten efecto si el bot decide respetarlas) y otras bloquean de verdad (impiden el acceso, lo respete o no)</strong>.</p>
<p>Con esa idea clara esto es lo que hay.</p>
<h3>Señales declarativas (piden, no obligan)</h3>
<p>¿En serio hace falta que recuerde esto? Ah ¿que sí?, pues nada, uy perdón …</p>
<ul>
<li><strong>El <code>Disallow</code> del <code>robots.txt</code>:</strong> Le dices a un bot, por su nombre, que no rastree tu web o ciertas partes. Aquí dentro entra también el <code>Google-Extended</code>, que no es más que un <code>Disallow</code> para el token con el que Google controla el entrenamiento de Gemini.</li>
<li><strong>El <code>noai</code> y el <code>noimageai</code>:</strong> Dos etiquetas en la cabecera de tu web que declaran «no me uses para entrenar, ni el texto ni las imágenes».</li>
<li><strong>Las Content Signals:</strong> Una técnica distinta y más fina, que va en el <code>robots.txt</code> y que en vez de bloquear a un bot separa <em>para qué</em> autorizas tu contenido y para qué no, y que además puede llevar respaldo legal. La vemos aparte, que tiene lo suyo.</li>
</ul>
<h3>Bloqueo real y efectivo (impide de verdad)</h3>
<p>Aquí quería llegar yo…</p>
<ul>
<li><strong>El 403.</strong> Le devuelves al bot un «prohibido» desde PHP, desde el <code>.htaccess</code> o desde un firewall, y no ve absolutamente nada. Esto no pide, esto impide.</li>
</ul>
<h3>Espera que hay más</h3>
<p>Y dos caminos más que no son ni bloquear ni dejar pasar, y que mucha gente ni se plantea:</p>
<ul>
<li><strong>Cobrar por el acceso</strong>, con la cabecera <code>402</code> y el protocolo <code>x402</code>.</li>
<li><strong>Adelantarte</strong>, asegurándote de que, cuando te compartan con una IA, tu web vaya siempre como fuente.</li>
</ul>
<p>¿Le damos ya?, que esto era solo la lista, la chicha de cada cosa la explico ahora.</p>
<h2>Cómo se bloquea a las IAs</h2>
<p>A las manos en la masa. El «cómo» de cada cosa, con código si te va lo artesano y con plugin si prefieres no tocar nada. Y sí, varios plugins son míos, porque los hice justo para esto, así que perdona el autobombo, pero es que vienen al pelo.</p>
<h3>El <code>Disallow</code> en el <code>robots.txt</code> (con el <code>Google-Extended</code> dentro)</h3>
<p>A mano, en tu <code>robots.txt</code>:</p>
<pre>User-agent: GPTBot
Disallow: /

User-agent: CCBot
Disallow: /

User-agent: Google-Extended
Disallow: /</pre>
<p>Fíjate en que el <code>Google-Extended</code> es un <code>Disallow</code> más, solo que especial, porque <strong>bloquearlo evita que Google te use para entrenar Gemini sin sacarte de las búsquedas</strong>, sigues apareciendo igual.</p>
<p>Lo anterior, por supuesto, es solo un ejemplo, <a href="https://ayudawp.com/bloquear-bots-inteligencia-artificial/" target="_blank" rel="noopener">aquí tienes una lista bastante más completa de bots de IA a los que hacer <code>Disallow</code></a> (o no)</p>
<p>Si no te quieres pelear con el fichero, tanto mi plugin <a href="https://es.wordpress.org/plugins/native-aeo-pack/">Visibility</a> como <a href="https://es.wordpress.org/plugins/vigia/">VigIA</a> te añaden el <code>Disallow</code> a los principales bots de IA <strong>con un par de clics</strong>.</p>
<h3>Las metas <code>noai</code> y el <code>noimageai</code></h3>
<p>En la cabecera de tu web, así:</p>
<pre>&lt;meta name="robots" content="noai, noimageai"&gt;</pre>
<p><strong>Es una declaración de intenciones contra el entrenamiento de las IAs</strong>, nacida en DeviantArt en 2022, que no es un estándar oficial de nada, así que <strong>vale para el bot que quiera respetarla y para nada frente al que no</strong>.</p>
<p>El plugin <a href="https://es.wordpress.org/plugins/ai-content-signals/">AI Content Signals</a> las añade (si quieres) sin tocar código ni complicarte.</p>
<h3>Las Content Signals (y su respaldo legal)</h3>
<p>Las <code>Content Signals</code> también van en el <code>robots.txt</code>, pero en vez de decirle a un bot que no entre, declaran <strong>para qué usos autorizas tu contenido y para cuáles no</strong>, separando tres cosas distintas:</p>
<ul>
<li><code>search</code>: construir un índice de búsqueda y mostrar resultados (enlaces y extractos cortos), sin incluir los resúmenes generados por IA.</li>
<li><code>ai-input</code>: meter tu contenido en modelos de IA en tiempo real, lo que se llama RAG o <em>grounding</em>, las respuestas de búsqueda con IA.</li>
<li><code>ai-train</code>: entrenar o afinar los modelos.</li>
</ul>
<p>Un ejemplo de «buscar sí, entrenar no» quedaría así:</p>
<pre>User-agent: *
Content-Signal: search=yes, ai-train=no</pre>
<p>¿Y dónde está la gracia de verdad? Pues en que <strong>esto no es solo una petición, es una reserva expresa de derechos con base legal</strong>.</p>
<p>El plugin <a href="https://es.wordpress.org/plugins/ai-content-signals/">AI Content Signals</a> que te comenté en el apartado anterior añade además al <code>robots.txt</code> una declaración que ampara esas señales en el artículo 4 de la Directiva europea 2019/790 de derechos de autor, la que <strong>permite a los autores reservarse su contenido frente a la minería de textos y datos</strong>, que es, ni más ni menos, lo que hace el entrenamiento de las IA.</p>
<p>O sea, que ya <strong>no solo le pides al bot que se porte, le recuerdas que hay una ley europea detrás que protege tu contenido</strong>. Te lo conté a fondo en mi artículo sobre las <a href="https://ayudawp.com/content-signals/">Content Signals</a>, por si quieres seguir informándote de esto.</p>
<h3>El bloqueo con 403 por <code>.htaccess</code> o por PHP</h3>
<p>Cuando la declaración no basta toca el <strong>bloqueo de verdad</strong>, cortando por <code>User-agent</code> desde <code>.htaccess</code>:</p>
<pre>RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (Bytespider|PerplexityBot|CCBot) [NC]
RewriteRule .* - [F,L]</pre>
<p>O desde PHP, en tu propio plugin o como suelas añadir códigos a tu web:</p>
<pre>function ayudawp_bloquear_bots_ia() {
    $ua = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
    if ( $ua &amp;&amp; preg_match( '#Bytespider|PerplexityBot|CCBot#i', $ua ) ) {
        status_header( 403 );
        exit;
    }
}
add_action( 'init', 'ayudawp_bloquear_bots_ia' );</pre>
<p>Y aquí, de nuevo, <strong>VigIA te lo da hecho</strong>, porque <strong>bloquea de verdad por PHP a los bots que tú elijas, por IP o por <code>User-agent</code></strong>.</p>
<p>Lo mejor de todo es que te da todas las capas, así que puedes probar con el <code>Disallow</code>, y <strong>cuando compruebes que no le hacen ni caso, además de aprender en carne propia, con un clic puedes bloquearlos</strong>, y también ahí comprobar que eso sí funciona (garantizado).</p>
<p>Para lo más bruto y lejos de tu web de todo, un cortafuegos (un WAF, como el de Cloudflare), que es el único que frena hasta a los que maquillan el <code>User-agent</code> o cambian dinámicamente de IP.</p>
<h2>Y en vez de bloquear a las IA ¿puedo cobrarles o alguna otra cosa?</h2>
<p>Pues sí ,es posible, y quizás son las que más interesante de cara al futuro.</p>
<h3>Cobrar por el acceso: 402 y x402</h3>
<p>Existe una cabecera HTTP, la <code>402 Payment Required</code>, que llevaba décadas casi de adorno y que ahora empieza a cobrar sentido, pues en vez de decirle a la IA que no, le dices «<strong>sírvete, pero pagando</strong>».</p>
<p>Sobre esa idea se está montando el protocolo <code>x402</code>, para <strong>que los bots paguen por rastrearte de forma automática</strong>, y Cloudflare ya está levantando su mercado de pago por rastreo.</p>
<p>No es ciencia ficción, te lo he contado en detalle en mis artículos sobre la <a href="https://ayudawp.com/402-payment-required/">cabecera 402</a> y sobre <a href="https://ayudawp.com/x402/">x402</a>, porque es, hoy o mañana, otra opción real para el dueño de <strong>una web que no quiere ni regalar su contenido ni renunciar del todo a las IA</strong>.</p>
<h3>Adelantarte a veces es inevitable, ya puestos que te lleven siempre de fuente</h3>
<p>Esta sería la forma más proactiva de todas, porque en vez de solo defenderte juegas al ataque. La gente va a compartir tu contenido con las IA quieras o no, así que <strong>al menos que lo haga citando tu web como fuente</strong>.</p>
<p>Eso es justo lo que hace el plugin <a href="https://es.wordpress.org/plugins/ai-share-summarize/">AI Share &amp; Summarize</a>, que añade <strong>botones para resumir y compartir tu contenido en ChatGPT, Claude, Perplexity y demás IAs</strong>, y cada vez que un lector los usa, el mensaje que se manda a <strong>la IA lleva tu URL como origen</strong>.</p>
<p>También va un paso más allá y te permite <strong>usar la IA para que los usuarios no abandonen tu web para usar la IA ¿flipas verdad? </strong></p>
<p>Básicamente <a href="https://ayudawp.com/resumenes-ia-integrados/" target="_blank" rel="noopener">puedes ofrecer resúmenes de tu contenido</a> para, a modo de extracto, generado con tu IA favorita, así <strong>les animas a seguir leyendo, sin que dejen de sentir ese calorcito especial que da la IA</strong>.</p>
<p>De paso te da <a href="https://ayudawp.com/ai-share-summarize-analitica-clics/">analítica de esos clics</a>, que no viene nada mal, lo tienes explicado en mi artículo sobre los <a href="https://ayudawp.com/resumenes-ia-integrados/">resúmenes con IA integrados</a>.</p>
<h2>¿A qué hacen caso las IA y a qué no?</h2>
<p>Por resumir, recuerda que <strong>las señales (el <code>Disallow</code>, el <code>noai</code>, las Content Signals) declaran, y solo surten efecto si el bot decide respetarlas, el 403 bloquea de verdad, lo respete o no</strong>.</p>
<p>Los hay que hacen caso, que conste. Sin ir más lejos, esta semana le pedí a mi IA de cabecera (sí, <a href="https://claude.ai/referral/Y0TXzOGBpQ" target="_blank" rel="nofollow noopener">es Claude Code</a>) que me leyera un artículo de <em>ZDNet</em> para recopilar documentarme para los vídeos que hago en YouTube y <strong>me dijo que no podía, que ese dominio estaba vetado en su herramienta ¿mande? </strong></p>
<p>Pues resulta que quien opera estas herramientas mantiene una <strong>lista de webs que no rastrea, casi siempre por motivos legales</strong>, para respetar a editores que han restringido el acceso de las IA o que están directamente en pleitos con ellas.</p>
<p>Y casualmente ZDNet es de Ziff Davis, que <a href="https://www.eweek.com/news/ziff-davis-sues-openai/" target="_blank" rel="nofollow noopener">demandó a OpenAI en abril de 2025</a> justo por usar su contenido para entrenar y para alimentar respuestas, así que encaja como un guante.</p>
<p>No tengo acceso a la lista ni al motivo exacto de cada web, pero la idea es esa, y conviene saberla, que <strong>a veces la IA no te lee porque legalmente no puede</strong>.</p>
<p>El bot más activo de ChatGPT (<code>ChatGPT-User</code>) también se porta razonablemente bien, lee tu <code>robots.txt</code> y para si le dices que no.</p>
<p>El problema son todos los demás.</p>
<p>En agosto de 2025 <a href="https://blog.cloudflare.com/perplexity-is-using-stealth-undeclared-crawlers-to-evade-website-no-crawl-directives/">Cloudflare pilló a Perplexity</a> saltándose las señales a base de cambiar de identidad, rotar direcciones IP y disfrazarse de un navegador normal para colarse en webs que le habían dicho que no. Y yo que tenía en un altar a Perplexity, ¡qué decepción!</p>
<p>Y el <code>Bytespider</code> de ByteDance ignora el <code>robots.txt</code> cuando le da la gana, vamos, siempre. Resumiendo, que <strong>fiarte solo de las señales es fiarte de la buena voluntad de cada bot, uno por uno</strong>, y ya ves que no todos la tienen.</p>
<p>¿Y cómo sabes tú en cuál de los dos grupos está cada bicho que te visita? Aquí es donde VigIA tiene algo que decir, porque trae una herramienta hecha justo para esto: <strong>comprueba si los bots respetan de verdad el <code>Disallow</code> que les has puesto</strong>.</p>
<p>Si pillas a una IA pasando de ti, con el mismo VigIA le aplicas el bloqueo por PHP. Declarar, comprobar y, solo si hace falta, bloquear, todo en el mismo sitio y sin adivinar, con datos reales, que de esto falta mucho <strong>en todo este tema de las IAs, hay mucho iluminado pero los negocios viven/vivimos de realidades</strong> ¿o no?.</p>
<h2>¿Y a ti te conviene bloquear? el SEO y AEO</h2>
<p>Vale, ya sabes qué puedes hacer y a qué hacen caso. Ahora lo que de verdad nos quita el sueño, que es de donde viene la duda de si <strong>conviene bloquear a las IA para el SEO, o nos estamos cerrando una puerta que no deberíamos cerrar.</strong></p>
<p>La pregunta buena no es ¿bloqueo las IA, sí o no?, es más fina, sería algo más como <strong>¿quieres seguir saliendo en los buscadores y en las respuestas de las IA, pero a la vez impedir que usen tu contenido para entrenar sus modelos?</strong></p>
<p>Parece rebuscado, algunos pensarán que imposible, pero no, porque eso, hoy, se puede separar, y ahí está casi toda la chicha, donde podemos poner un poco de orden y control en todo este mejunje.</p>
<p>La clave para entenderlo es que <strong>el AEO y el GEO, eso de posicionarte en las respuestas de la IA, siguen siendo SEO</strong>. No lo digo yo, lo dice <a href="https://developers.google.com/search/docs/fundamentals/ai-optimization-guide">la propia guía de optimización para IA de Google</a>, pues las AI Overviews y el AI Mode se apoyan en su mismo sistema de posicionamiento y calidad de siempre.</p>
<p>O sea, que <strong>las mismas señales que te hacen posicionar son las que hacen que te citen en las respuestas con IA</strong>. Y ahora ata cabos, que si le impides el paso a los bots que recuperan tu contenido para buscar y citar, <strong>dejas de salir en esas respuestas, y el hueco lo ocupa tu competencia</strong>.</p>
<p>Y esto no es una teoría mía, ya hay datos. Alrededor del 80 % de los grandes medios de noticias ya bloquean al menos un bot de entrenamiento, y un 70 % bloquea también los bots que recuperan contenido para citar en las IA.</p>
<p>¿El resultado? Pues varios estudios apuntan a que esos mismos medios <strong>se están quedando fuera de las respuestas de la IA y perdiendo visibilidad</strong> justo por bloquear a la brava. Se protegen de una cosa y se disparan en el pie con la otra, así que <strong>la cosa está en saber qué y cuándo bloquear</strong>.</p>
<h3>Cuándo bloquear SÍ tiene sentido</h3>
<p>Que quede claro que no todo es dejar pasar. Bloquear compensa, y mucho, cuando <strong>proteger tu contenido pesa más que la visibilidad</strong>. Ejemplos de esto:</p>
<ul>
<li><strong>Contenido propietario o sensible</strong>, eso que te diferencia de verdad de la competencia.</li>
<li><strong>Contenido de pago</strong>, para miembros, cursos o zonas privadas.</li>
<li><strong>Datos únicos que son tu negocio</strong>, como los precios o las fichas de una tienda que no quieres que acaben en el buscador de otro.</li>
<li><strong>Sitios con obligaciones de cumplimiento</strong> estrictas.</li>
<li>Y el caso de los <strong>editores que, sencillamente, no quieren regalar su trabajo para entrenar modelos</strong> y prefieren pelear por que les paguen, ahí es donde entra lo del 402 y el x402 de antes.</li>
</ul>
<h3>Cuándo bloquear sería un grave error</h3>
<p>Y al revés, si <strong>tu web vive de que te encuentren y te citen</strong>, impedir el paso a los bots de búsqueda de IA es de las peores ideas que puedes tener.</p>
<p>Hablo de <strong>blogs, webs de empresa, guías, contenido informativo, marca personal</strong>, todo eso que se alimenta de visibilidad y autoridad.</p>
<p>Ahí <strong>cada cita en una IA es un ladrillo más de tu reputación</strong>, y cerrarles el paso es quedarte fuera del escaparate donde ahora busca la gente. Y para que te citen bien, <strong>el contenido tiene que merecer la cita, que es el <a href="https://ayudawp.com/eeat-wordpress/">E-E-A-T</a> de toda la vida</strong>.</p>
<p>Hay un motivo aparte, eso sí, que vale para cualquiera, y me refiero al <strong>coste de rastreo</strong>.</p>
<p>Estos bots rastrean a lo bestia, y según datos de <a href="https://www.cloudflare.com/learning/ai/how-to-block-ai-crawlers/">Cloudflare</a> hay rastreadores de IA que piden decenas de miles de páginas de tu web por cada mísera visita que te devuelven.</p>
<p>Eso es factura de servidor, así que si uno te está reventando el hosting tienes todo el derecho a pararlo aunque el SEO te diga otra cosa.</p>
<p>¿Y surte efecto bloquear? Pues depende de a quién.</p>
<p>Los bots decentes que respetan las señales pararán en cuanto se lo pidas, los que ignoran el <code>robots.txt</code> necesitan el 403. Y a los que se disfrazan, como vimos con Perplexity, ni el bloqueo por <em>user-agent</em> los para del todo, ahí solo un firewall en condiciones les corta el acceso de verdad.</p>
<p><strong>El método tiene que estar adaptado al bot</strong>, no hay una bala de plata.</p>
<h2>La decisión, con todo en la mano</h2>
<p>Con todo esto ya puedes decidir sin agobios, y el orden sensato es este, justo al revés de lo que hace casi todo el mundo:</p>
<ol>
<li><strong>Primero mide:</strong> Con VigIA (o con los <em>logs</em> de tu servidor), mira quién te rastrea, si respeta tus señales y cuánto te cuesta. Sin este paso vas a ciegas.</li>
<li><strong>Clasifica según el bot y según tu contenido:</strong> A los de búsqueda y cita, déjalos pasar si vives de la visibilidad. A los de entrenamiento, ponles la señal. A los que te sangran el servidor o pasan de ti, bloqueo.</li>
<li><strong>Aplica el nivel justo:</strong> Declaración para el que la respeta, bloqueo para el que no. Y valora si, en vez de bloquear, te compensa cobrar o adelantarte con la atribución.</li>
<li><strong>Revisa tu estrategia a menudo:</strong> Que esto cambia a toda velocidad, y el bot que hoy no te aporta nada, mañana puede ser tu principal fuente de visitas.</li>
</ol>
<h2>«Bueno, vale, ¿pero qué hago?»</h2>
<p>Te veo venir, porque es justo donde te quedas después de tragarte todo esto: «vale, Fernando, ya sé cómo decirle a la IA que no me lea, de varias maneras, y sé qué funciona y qué no, pero yo, con mi web, ¿qué hago?».</p>
<p>Pues para ayudarte a poner orden en la decisión, te lo dejo en una tabla, y luego mi consejo.</p>
<table>
<thead>
<tr>
<th>Qué puedes hacer</th>
<th>En qué afecta</th>
<th>Recomendación</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Disallow</code> a bots de <code>training</code> (Visibility, VigIA)</td>
<td>Declarativo. Los que lo respetan dejan de entrenarte, no toca tu SEO</td>
<td>Recomendado. Cuesta cero y no pierdes nada</td>
</tr>
<tr>
<td><code>Disallow</code> a bots de <code>search</code> o de <code>assistant</code> de IA (VigIA, Visibility)</td>
<td>Declarativo. Dejas de salir citado en las respuestas de las IA</td>
<td>Solo si de verdad no quieres visibilidad en IA. En general no deberías bloquearlos</td>
</tr>
<tr>
<td><code>noai</code> y <code>noimageai</code> (AI Content Signals)</td>
<td>Declarativo. Pides no ser usado para entrenar; voluntario</td>
<td>Recomendado para dejar tu postura clara, sin código</td>
</tr>
<tr>
<td>Content Signals + reserva legal UE (AI Content Signals)</td>
<td>Declarativo con base jurídica (Directiva UE 2019/790). Separa <code>search</code>, <code>ai-input</code> y <code>ai-train</code></td>
<td>Recomendado, es la señal más completa y la única con respaldo legal</td>
</tr>
<tr>
<td>Monitorizar y comprobar cumplimiento (VigIA)</td>
<td>Ni declara ni bloquea: te dice quién entra y quién respeta tus señales</td>
<td>Imprescindible. Es lo que te deja decidir con datos y no a ciegas</td>
</tr>
<tr>
<td>Bloqueo con <code>403</code> por <code>.htaccess</code> o PHP (VigIA)</td>
<td>Bloqueo efectivo. Impide el acceso a los bots declarados que ignoran las señales</td>
<td>Para los que te sangran el servidor o pasan de ti. No frena a los que se disfrazan</td>
</tr>
<tr>
<td>Firewall (WAF, Cloudflare, Vigilante)</td>
<td>Bloqueo efectivo, hasta a los que se disfrazan</td>
<td>Lo más robusto. Ojo, bloquear el <code>training</code> puede impedir también a <code>Googlebot</code></td>
</tr>
<tr>
<td>Cobrar por el acceso (<code>402</code> / <code>x402</code>)</td>
<td>Ni bloqueas ni regalas, pones precio al rastreo de la IA</td>
<td>A tener en el radar, es la vía de futuro para monetizar el acceso</td>
</tr>
<tr>
<td>Adelantarte con la atribución (AI Share &amp; Summarize)</td>
<td>No bloquea, cuando te comparten con una IA, eres de fuente y puedes medir</td>
<td>Recomendado. Juegas a favor en vez de solo defenderte</td>
</tr>
</tbody>
</table>
<p>Si miras la tabla entera, la lógica salta sola, pues casi todo lo que de verdad quieres (que no te entrenen) lo consigues con señales que no tocan tu SEO, y el bloqueo efectivo lo guardas para los que ignoran tus normas o solo consumen recursos del servidor.</p>
<p>Lo único que te cuesta visibilidad de verdad es impedir el paso a los bots de búsqueda, así que ese error no lo cometas sin querer.</p>
<h3>Mi consejo, por si te sirve</h3>
<p>Para la web típica, la de contenido, servicios o marca, mi posición es deja pasar a los bots de búsqueda (<code>search</code>) y de cita (<code>assistant</code>), que te interesa muchísimo que las IA te lean y te nombren.</p>
<p>Además, declarar con las Content Signals y el <code>noai</code> que no te entrenen, medir con VigIA quién te respeta, y bloquear de verdad solo a los que ignoran tus normas o te ponen a prueba el hosting.</p>
<p>Además, estoy muy a favor de limitarte solo en defenderte, a ir a por la atribución, que las IA te van a leer igual y más vale que te lleven de fuente.</p>
<p>Si en cambio tu negocio es contenido propietario, de pago o datos únicos, ahí sí, bloquea lo que haga falta y con menos remordimientos, o plantéate cobrar por el acceso.</p>
<p>Porque al final esto va de lo de siempre, de que <strong>hemos pasado de ser dueños de nuestro contenido a andar negociando quién lo lee, para qué y a cambio de qué</strong>.</p>
<p>Tu web es tuya y la decisión también, faltaría más, pero tómala con los datos delante y sabiendo qué es una declaración y qué es un bloqueo efectivo, que es justo lo que casi nadie te cuenta.</p>
<p>Si quieres seguir tirando del hilo, tengo más escrito sobre <a href="https://ayudawp.com/visibilidad-ia/">visibilidad en las IA</a>, sobre el <a href="https://ayudawp.com/llms-txt-llms-full-txt/">llms.txt</a> y sobre <a href="https://ayudawp.com/ai-overviews-google/">cómo posicionar en las AI Overviews de Google</a>, donde seguro que atas algún cabo más.</p>
<p>Y si lo ves de otra manera, o me quieres contar cómo lo llevas en tu web, me tienes ahí abajo, en la sección de comentarios, que para eso están.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/bloquear-bots-ia/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Trucazo rápido para saber dónde y por qué va lento WordPress</title>
		<link>https://ayudawp.com/diagnostico-rapido-pagina-lenta/</link>
					<comments>https://ayudawp.com/diagnostico-rapido-pagina-lenta/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 15 Jul 2026 06:28:14 +0000</pubDate>
				<category><![CDATA[Programación + WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[WPO - Optimizar WordPress]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[mu-plugins]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Query Monitor]]></category>
		<category><![CDATA[wp-config.php]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159885</guid>

					<description><![CDATA[Si quieres diagnosticar en qué se te van los tiempos de carga de cualquier página aquí tienes un modo rápido, limpio y privado de verlo fase a fase.]]></description>
										<content:encoded><![CDATA[<p>Tu WordPress va lento, abres Query Monitor a ver qué pasa, miras las consultas y… están bien, hay pocas, son rápidas, nada raro, y sin embargo la página tarda un mundo en pintarse.</p>
<p>Pues bien, resulta que ahí tienes el problema delante y no lo estás viendo, porque <strong>el tiempo no siempre se va en la base de datos</strong>.</p>
<p>Que conste, la mayoría de las veces que algo va lento la culpable sí es la base de datos, en eso llevas razón y por eso conviene empezar por ahí con la <a href="https://ayudawp.com/optimizar-consultas-sql/" target="_blank" rel="ugc noopener">guía para optimizar las consultas SQL</a>.</p>
<p>Pero cuando las consultas están limpias y la cosa se sigue arrastrando el tiempo de carga se te está yendo en otro sitio, en PHP puro, en un plugin que hace un bucle a lo bestia, en una llamada a una API externa metida dentro de un hook, en un render que se atasca.</p>
<p>Y no, eso en las consultas no sale.</p>
<p>Para medirlo con detalle existe el comando <code>wp profile</code>, que reparte el tiempo de carga por fases, pero necesita SSH y línea de comandos, y en un alojamiento compartido normal ni lo tienes ni te dejan tocarlo.</p>
<p>Así que aquí va la versión casera, <strong>un mu-plugin que te dice, al final de cada página, cuánto tiempo se ha ido en cada tramo de la carga</strong>. Sin consola, y solo lo ves solo tú.</p>
<h2>Midiendo los tiempos de carga de una página web por fases</h2>
<p>La carga de WordPress no es un bloque, son fases encadenadas, primero se cargan los plugins, luego arranca el tema, después se dispara <code>init</code>, viene la consulta principal y al final el render de la página.</p>
<p>La idea es poner un cronómetro en cada uno de esos pasos para ver en cuál se atasca la cosa.</p>
<p>Crea un archivo, por ejemplo <code>ayudawp-phase-timer.php</code>, y súbelo a la carpeta <code>/wp-content/mu-plugins/</code> (si no existe la creas tú, es una carpeta normal y corriente).</p>
<p><a href="https://ayudawp.com/que-son-los-mu-plugins-de-wordpress/" target="_blank" rel="noopener">Los mu-plugins ya sabrás se ejecutan solos y antes que todo lo demás</a>, que es justo lo que necesitamos para cronometrar desde el arranque.</p>
<p>En fin, que este es el nene:</p>
<pre>&lt;?php
/**
* Plugin Name: Load Phase Timer
* Plugin URI: https://ayudawp.com/
* Description: Solo para admins: muestra los momentos en los que el tiempo real se solapa con el ciclo de carga de WordPress. Herramienta de diagnóstico, eliminar tras su uso.
* Version: 1.0.0
* Author: Fernando Tellado
* Author URI: https://tellado.es
 */

// Evitar el acceso directo
defined( 'ABSPATH' ) || exit;

// Solo se ejecuta cuando se activa explícitamente, para evitar una sobrecarga en el uso habitual
// Activar definiendo AYUDAWP_PHASE_TIMER como true in wp-config.php
if ( ! defined( 'AYUDAWP_PHASE_TIMER' ) || ! AYUDAWP_PHASE_TIMER ) {
	return;
}

// Una marca temporal por cada paso del ciclo
$GLOBALS['ayudawp_phase_marks'] = array();

// Ancla al inicio de la solicitud real, definida por PHP incluso antes de que se cargue WordPress
$GLOBALS['ayudawp_phase_marks']['request_start'] = isset( $_SERVER['REQUEST_TIME_FLOAT'] )
	? (float) $_SERVER['REQUEST_TIME_FLOAT']
	: microtime( true );

// Momento en que este mu-plugin empieza a ejecutarse
$GLOBALS['ayudawp_phase_marks']['muplugins_start'] = microtime( true );

/**
 * Registra el tiempo real de cada paso
 */
function ayudawp_mark_phase( $name ) {
	$GLOBALS['ayudawp_phase_marks'][ $name ] = microtime( true );
}

// Marca temporal de cada paso del ciclo de carga, en orden
add_action( 'muplugins_loaded',  function () { ayudawp_mark_phase( 'muplugins_loaded' ); },  0 );
add_action( 'plugins_loaded',    function () { ayudawp_mark_phase( 'plugins_loaded' ); },    0 );
add_action( 'after_setup_theme', function () { ayudawp_mark_phase( 'after_setup_theme' ); }, 0 );
add_action( 'init',              function () { ayudawp_mark_phase( 'init' ); },              0 );
add_action( 'wp_loaded',         function () { ayudawp_mark_phase( 'wp_loaded' ); },         0 );
add_action( 'template_redirect', function () { ayudawp_mark_phase( 'template_redirect' ); }, 0 );

// Al final de la solicitud muestra el informe (solo admins)
add_action( 'shutdown', 'ayudawp_print_phase_report', PHP_INT_MAX );

/**
 * Genera y muestra el desglose por fases como comentario HTML, solo para admins
 */
function ayudawp_print_phase_report() {

	// Nunca expone tiempos internos a visitantes
	if ( ! function_exists( 'current_user_can' ) || ! current_user_can( 'manage_options' ) ) {
		return;
	}

	ayudawp_mark_phase( 'shutdown' );
	$marks = $GLOBALS['ayudawp_phase_marks'];

	// Etiqueta para humanos =&gt; [ from milestone, to milestone ]. Cadena contigua
	$phases = array(
		'Antes de WordPress (arranque PHP)' =&gt; array( 'request_start', 'muplugins_start' ),
		'Carga de mu-plugins'               =&gt; array( 'muplugins_start', 'muplugins_loaded' ),
		'Carga de plugins'                  =&gt; array( 'muplugins_loaded', 'plugins_loaded' ),
		'Arranque del tema'                 =&gt; array( 'plugins_loaded', 'after_setup_theme' ),
		'Hasta init'                        =&gt; array( 'after_setup_theme', 'init' ),
		'De init a wp_loaded'               =&gt; array( 'init', 'wp_loaded' ),
		'Consulta principal'                =&gt; array( 'wp_loaded', 'template_redirect' ),
		'Render y salida'                   =&gt; array( 'template_redirect', 'shutdown' ),
	);

	$total = ( $marks['shutdown'] - $marks['request_start'] ) * 1000;

	$lines   = array();
	$lines[] = 'AyudaWP Load Phase Timer';
	$lines[] = 'URL: ' . ( isset( $_SERVER['REQUEST_URI'] ) ? esc_html( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : 'n/a' );
	$lines[] = str_repeat( '-', 52 );

	foreach ( $phases as $label =&gt; $pair ) {
		list( $from, $to ) = $pair;

		// Omite fases cuyos pasos no se hayan activado (p.ej. template_redirect en wp-admin)
		if ( ! isset( $marks[ $from ], $marks[ $to ] ) ) {
			continue;
		}

		$ms  = ( $marks[ $to ] - $marks[ $from ] ) * 1000;
		$pct = $total &gt; 0 ? ( $ms / $total ) * 100 : 0;
		$lines[] = sprintf( '%-38s %8.1f ms  %5.1f%%', $label, $ms, $pct );
	}

	$lines[] = str_repeat( '-', 52 );
	$lines[] = sprintf( '%-38s %8.1f ms', 'TOTAL', $total );

	$output = implode( "\n", $lines );

	// Red de seguridad: no dejar que el contenido salga del comentario HTML
	$output = str_replace( '--&gt;', '--&amp;gt;', $output );

	echo "\n&lt;!--\n" . $output . "\n--&gt;\n"; // phpcs:ignore WordPress.Security.EscapeOutput
}
</pre>
<p>Para que no te consuma nada en el día a día, <strong>el cronómetro solo se enciende cuando tú quieres</strong>. Añade esta línea a tu <code>wp-config.php</code> mientras diagnosticas y la quitas al terminar:</p>
<pre>// Activa el temporizador de fase de AyudaWP para medir el tiempo de carga de las páginas
define( 'AYUDAWP_PHASE_TIMER', true );</pre>
<h2>Interpretar el reparto de tiempos</h2>
<p>Abre como administrador la página que va lenta, mira el código fuente (botón derecho, <code>Ver código fuente de la página</code>) y busca al final del todo <strong>un comentario de código con el reparto de tiempos</strong>, verás algo así:</p>
<pre>&lt;!--
AyudaWP Load Phase Timer
URL: /mi-pagina-lentorra/
----------------------------------------------------
Antes de WordPress (arranque PHP) 37.8 ms 23.9%
Carga de mu-plugins 0.1 ms 0.1%
Carga de plugins 17.9 ms 11.3%
Arranque del tema 8.4 ms 5.3%
Hasta init 3.9 ms 2.5%
De init a wp_loaded 18.0 ms 11.4%
Consulta principal 8.1 ms 5.1%
Render y salida 63.8 ms 40.4%
----------------------------------------------------
TOTAL 158.1 ms
--&gt;</pre>
<p><strong>La fase con más milisegundos es donde se te está yendo el tiempo.</strong> A partir de ahí:</p>
<ul>
<li>Si se concentra en <strong>Carga de plugins</strong> o en <strong>Hasta init</strong>, tienes demasiados plugins o alguno hace trabajo pesado al arrancar, así que toca revisar cuáles son y desactivar los que no aporten.</li>
<li>Si el tiempo está en <strong>Consulta principal</strong> y las consultas estaban limpias, mira el bucle principal, las <code>WP_Query</code> mal montadas o los relacionados, y vuelve a esa guía de consultas SQL.</li>
<li>Si el grueso está en <strong>Render y salida</strong>, el problema es de la plantilla, de shortcodes pesados o de scripts, no de la base de datos.</li>
</ul>
<p>Ojo, esto es para direcciones de la parte visible de la web, en el escritorio (<code>wp-admin</code>) algunas fases no aparecen porque no llegan a dispararse, y es lo normal.</p>
<p>Y que quede claro, esto es un primer vistazo y no sustituye a nada. Cuando ya sepas donde se atasca la cosa y quieras al culpable concreto <a href="https://ayudawp.com/query-monitor/" target="_blank" rel="ugc noopener">Query Monitor</a> te atribuye cada consulta, cada llamada HTTP y cada hook al plugin que lo provoca. Y si tienes SSH, <code>wp profile</code> te da todo esto y bastante más.</p>
<p>Una última cosa, que luego todo son sustos, <strong>esto es una herramienta de diagnóstico y no se queda puesta. </strong>Cuando termines quita la línea del <code>wp-config.php</code> o borra directamente el archivo, que un cronómetro corriendo en cada carga, por ligero que sea, no pinta nada en producción.</p>
<p>¿Te ha salido disparada una fase que no te esperabas? Cuéntamelo aquí abajo en los comentarios, que seguro que no eres el único al que le pasa.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/diagnostico-rapido-pagina-lenta/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Todo lo que deberías revisar si vas a auditar un web WordPress, o al menos lo que yo hago</title>
		<link>https://ayudawp.com/auditar-web-wordpress/</link>
					<comments>https://ayudawp.com/auditar-web-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 14 Jul 2026 06:28:44 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[AI Share & Summarize]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Content Signals]]></category>
		<category><![CDATA[DietPress]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[Omnibus]]></category>
		<category><![CDATA[OPcache]]></category>
		<category><![CDATA[RGPD]]></category>
		<category><![CDATA[VigIA]]></category>
		<category><![CDATA[Visibility]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159848</guid>

					<description><![CDATA[Te llega una web WordPress que no has hecho tú, de la que nadie sabe darte detalles, y tienes que decidir si aceptas mantenerla, cuánto cobras por arreglarla o qué contarle al cliente en la consultoría. ]]></description>
										<content:encoded><![CDATA[<p>Te llega una web WordPress que no has hecho tú, de la que nadie sabe darte detalles, y tienes que decidir si aceptas mantenerla, cuánto cobras por arreglarla o qué contarle al cliente en la consultoría. Para eso sirve una auditoría técnica: <strong>una revisión sistemática, área por área, que termina en un informe con prioridades claras</strong> y no en una lista infinita de cosas que «habría que mirar».</p>
<p>Las áreas habituales no son pocas, rondan la decena: entorno y servidor, núcleo de WordPress, tema, plugins, seguridad, rendimiento, SEO técnico, visibilidad IA y RGPD, más tienda online y multisitio si los hay.</p>
<p>Pues bien, hoy quiero compartir contigo cómo lo hacemos en mi servicio de mantenimiento de webs WordPress, y espero que te sea útil, no solo si también ofreces ese tipo de servicio, sino en otras posibles situaciones:</p>
<ol>
<li><strong>Asumes el mantenimiento de una web que no conoces</strong> y quieres saber dónde te metes antes de firmar, porque lo que no detectes hoy será tu problema mañana.</li>
<li><strong>Te contratan una consultoría</strong> y necesitas diagnosticar el estado real de la web antes de recomendar nada.</li>
<li><strong>Te encargan mejorar o rediseñar una web existente</strong>, o valorar una que tu cliente quiere comprar, y toca saber sobre qué base estás pisando.</li>
<li><strong>Quieres analizar tu propia web</strong> para saber qué está bien, qué no, y cómo mejorarla de manera generalizada.</li>
</ol>
<p>Igual que en la guía de <a href="https://ayudawp.com/analizar-codigo-tema-wordpress/" target="_blank" rel="ugc noopener">auditoría de temas WordPress a medida</a>, el artículo va en dos velocidades. Si prefieres no usar código cada bloque te dice qué puedes comprobar con herramientas visuales y qué pedirle a una IA, y si eres el técnico del proyecto tienes los comandos y el detalle que completan el trabajo.</p>
<p>Y aunque no tengas acceso por SSH ni por FTP, tranquilo, que en cada bloque te doy la manera de comprobar lo mismo desde el escritorio de WordPress, el panel del hosting o una herramienta, para que la falta de un acceso no te deje ningún bloque sin revisar.</p>
<p>Cada bloque de esta propuesta de estructura de auditoría <strong>clasifica los hallazgos en tres niveles</strong>, los mismos que luego usarás <strong>para priorizar el trabajo</strong>:</p>
<ul>
<li><strong>Crítico</strong> (se corrige antes de cualquier otra cosa)</li>
<li><strong>Importante</strong> (se planifica en la próxima actuación)</li>
<li><strong>Menor</strong> (se documenta y se resuelve cuando toque pasar por ahí).</li>
</ul>
<p>Vamos a verlo con calma.</p>
<h2>Antes de tocar nada: accesos, contexto y red de seguridad</h2>
<p>Una auditoría sin accesos completos es una auditoría a medias, así que lo primero es pedirle al cliente todo esto, y pedirlo por escrito, que luego las cosas se olvidan:</p>
<ul>
<li><strong>Administrador de WordPress</strong>: un usuario propio para ti, nuevo, no el que se comparte media empresa por WhatsApp.</li>
<li><strong>Panel del hosting</strong>: sin él no puedes configurar versiones de PHP, base de datos, copias de seguridad con garantías ni logs del servidor.</li>
<li><strong>FTP/SFTP, WP-CLI o SSH</strong>: imprescindible para la velocidad técnica, y tu salvavidas si algo se rompe durante la revisión.</li>
<li><strong>Gestión del dominio y DNS</strong>: a veces está en un registrador distinto del hosting y nadie recuerda la contraseña, mejor descubrirlo ahora que durante una migración.</li>
<li><strong>Licencias de plugins y temas de pago</strong>: cuáles hay, quién las paga y desde qué cuenta se renuevan.</li>
<li><strong>Google Search Console, Bing Webmasters y Analytics</strong>: si existen, pide acceso; si no existen, ya tienes el primer hallazgo del informe.</li>
</ul>
<p>Pide también contexto, que no todo son contraseñas: quién hizo la web, quién la ha tocado desde entonces, qué problemas recuerdan y si hay algo «<strong>que no se puede tocar porque se rompe</strong>». Esa última frase, cuando aparece, <strong>señala exactamente el sitio donde más falta hace la auditoría</strong>.</p>
<p>Y antes de nada, la red de seguridad: <strong>copia de seguridad completa, verificada y descargada fuera del servidor</strong>. La auditoría en sí no debería romper nada porque es observación, pero posiblemente vayas a activar plugins de diagnóstico y a hurgar en ajustes, y si algo falla quieres poder volver atrás sin depender de la copia (quizás inexistente, ya lo verás en el bloque de seguridad) del hosting.</p>
<p>Todo lo que sea intervención de verdad, en staging (una copia de pruebas de la web), nunca en producción.</p>
<h3>Herramientas básicas</h3>
<p>Para la velocidad sin código usa el <a href="https://ayudawp.com/que-es-wp_debug-y-como-usarlo/" target="_blank" rel="ugc noopener">modo depuración de WordPress</a> con registro en archivo, el plugin oficial <a href="https://es.wordpress.org/plugins/health-check/" target="_blank" rel="nofollow noopener">Health Check &amp; Troubleshooting</a> y la pantalla <a href="https://ayudawp.com/salud-del-sitio-wordpress/" target="_blank" rel="ugc noopener">salud del sitio</a>, que ya viene de serie en la pantalla de herramientas, y es el mejor <strong>punto de partida que regala WordPress</strong>. Con eso y tu IA de confianza cubres la mayor parte del recorrido.</p>
<p>Para todo lo que normalmente pedirías por FTP, el <strong>gestor de archivos del hosting</strong> (cPanel, Plesk, las Site Tools de SiteGround o prácticamente cualquier panel) te deja ver y editar ficheros y revisar permisos sin instalar nada ni abrir una consola, que es tu puente para casi todo lo que aquí resuelvo por línea de comandos.</p>
<p>Para la parte más técnica te recomiendo tener <a href="https://wordpress.org/plugins/query-monitor/" target="_blank" rel="nofollow noopener">Query Monitor</a> instalado durante la auditoría (y desinstalado después), <a href="https://wp-cli.org/" target="_blank" rel="nofollow noopener">WP-CLI</a> por SSH para los comandos que irán apareciendo, y una <strong>hoja de cálculo o herramienta donde ir anotando hallazgos</strong> con su gravedad, porque <strong>una auditoría que no se documenta sobre la marcha es una auditoría que toca repetir</strong>.</p>
<p>Y <strong>si la caché no te deja ver el estado real de la web</strong> mientras investigas, el plugin <a href="https://es.wordpress.org/plugins/anticache/" target="_blank" rel="nofollow noopener">Anti-Cache Kit</a> vacía y desactiva de golpe los plugins de caché, activa el modo depuración y lo revierte todo al desactivarlo, con la misma regla que Query Monitor de <strong>activo mientras dura la auditoría, fuera al terminar</strong>.</p>
<h2>Qué puedes auditar sin tener acceso ni una triste contraseña de nada</h2>
<p>Mientras esperas los accesos (en la vida real tardan días, ya lo verás) puedes ir adelantando trabajo, porque <strong>una parte sorprendentemente amplia de la auditoría se puede hacer desde fuera</strong>, con la web pública y cuatro herramientas gratuitas.</p>
<p>La forma rápida de barrer casi todo este bloque es el <a href="https://herramientas.ayudawp.com/security-check/" target="_blank" rel="ugc noopener">análisis de seguridad WordPress</a> de las herramientas gratuitas, que hace <strong>más de 30 comprobaciones externas de seguridad</strong> de una tacada, entre las que están algunas tan importantes como las cabeceras HTTP, certificado SSL, exposición de archivos, listas negras y bastantes más.</p>
<p>Lo anterior lo complementas con <a href="https://pagespeed.web.dev/" target="_blank" rel="nofollow noopener">PageSpeed Insights</a> para las <strong>métricas de experiencia real de usuarios</strong>, <a href="https://www.ssllabs.com/ssltest/" target="_blank" rel="nofollow noopener">SSL Labs</a> para el certificado a fondo y <a href="https://mxtoolbox.com/" target="_blank" rel="nofollow noopener">MXToolbox</a> para DNS, listas negras y la salud del correo del dominio.</p>
<p>Lo del correo casi nadie lo mete en una auditoría web y luego pasa lo que pasa, y hay cosas que revisar, como los registros <strong>SPF, DKIM y DMARC</strong> (las firmas DNS que autorizan quién puede enviar correo en nombre del dominio), que determinan <strong>si los emails de la web (pedidos, formularios, recuperación de contraseña) llegan a la bandeja de entrada o mueren en spam</strong>.</p>
<p>De todo esto ya nos saldrá información que podemos empezar a clasificar.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Certificado SSL caducado, mal instalado o con la cadena incompleta</strong>: además del susto del navegador, invalida de facto todo lo demás.</li>
<li><strong>Dominio o IP en listas negras de spam o malware</strong>: hay que averiguar el porqué antes de seguir, puede ser herencia de una infección pasada o señal de una activa.</li>
<li><strong>Contenido mixto</strong> (recursos HTTP dentro de páginas HTTPS): candado roto, avisos al visitante y datos viajando sin cifrar.</li>
<li><strong>Sin SPF ni DMARC en un dominio que envía correo transaccional</strong>: entregabilidad a la ruleta y suplantación del dominio servida en bandeja.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Cabeceras de seguridad ausentes</strong> (HSTS, X-Content-Type-Options o Referrer-Policy, entre otras): se resuelven en el bloque de seguridad, aquí solo se anotan.</li>
<li><strong>Métricas Web Principales no superadas en datos de campo</strong>: LCP por encima de 2,5 segundos o INP por encima de 200 ms en móvil apuntan maneras para el bloque de rendimiento.</li>
<li><strong>Versión de WordPress visible</strong> en el meta generator y archivos como <code>readme.html</code> accesibles: información regalada a cualquier escáner automático.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Sin archivo <code>security.txt</code> (el estándar para que investigadores de seguridad sepan a quién avisar si encuentran algo).</li>
<li>TTFB (el tiempo que tarda el servidor en empezar a responder) por encima de 800 ms desde ubicaciones cercanas al público del sitio: no es sentencia, pero es la primera pista de un hosting justito.</li>
</ul>
<h2>Entorno y servidor</h2>
<p>Con los accesos ya en la mano, lo primero es analizar los cimientos de la web, porque <strong>ninguna optimización posterior compensa un servidor por debajo de mínimos</strong>. La pantalla de información de la salud del sitio te da casi todo el inventario sin salir de WordPress, y el panel del hosting completa el resto.</p>
<p>Para el técnico, <code>wp cli info</code>, <code>wp core check-update</code> y un vistazo a <code>phpinfo()</code> temporal (que borrarás al terminar, no como los que verás en el bloque de seguridad) cierran la foto.</p>
<p>Lo que hay que inventariar es el hosting y tipo de servidor (Apache, Nginx, LiteSpeed), versión de PHP y sus límites de memoria y ejecución, versión de MySQL o MariaDB, protocolo HTTP, compresión activa, sistema de copias del hosting, CDN si la hay y cómo está gestionado el cron.</p>
<p>Las referencias contra las que comparar las tienes siempre al día en la <a href="https://wordpress.org/about/requirements/" target="_blank" rel="nofollow noopener">página oficial de requisitos de WordPress</a>, que son versiones de PHP y base de datos mínimos y recomendados del momento. La regla que nunca caduca es que <strong>una versión de PHP sin soporte de seguridad es siempre un mal comienzo</strong>, aunque WordPress todavía la acepte, así que un servidor anclado en versiones viejas acumula papeletas más deprisa de lo que su dueño se imagina.</p>
<p>El cron merece párrafo propio, pues WordPress tiene su propio planificador de tareas (<a href="https://ayudawp.com/wp-cron/" target="_blank" rel="ugc noopener"><code>wp-cron</code></a>) que se ejecuta cuando alguien visita la web, lo que significa que <strong>en webs con poco tráfico las tareas programadas se retrasan y en webs con mucho tráfico se dispara más de la cuenta</strong>.</p>
<p>La configuración sana en producción es desactivarlo con <code>define( 'DISABLE_WP_CRON', true );</code> y sustituirlo por un cron real del servidor cada pocos minutos. Si encuentras publicaciones programadas que no se publicaron ya sabes por dónde empezar.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Versión de PHP sin soporte de seguridad</strong> (que el hosting te la ofrezca no la convierte en segura): sin parches ante vulnerabilidades nuevas, es la primera actualización a planificar, en staging y con calma.</li>
<li><strong>Sin copias de seguridad del hosting</strong>, o existentes pero jamás restauradas: <strong>una copia que nunca se ha probado a restaurar es una esperanza, no una copia</strong>.</li>
<li><strong>Correo transaccional saliente sin authentication por PHP</strong> con la función <code>mail()</code> en un dominio con SPF estricto: los correos de la web no llegan, y nadie se ha dado cuenta porque nadie los echa de menos hasta que hacen falta.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Límite de memoria PHP por debajo de 256 MB</strong> en webs con WooCommerce o page builders: errores intermitentes difíciles de reproducir que desaparecen «solos».</li>
<li><strong>Función <code>wp-cron</code> sin sustituir por cron de sistema</strong> en webs de tráfico alto o muy bajo.</li>
<li><strong>Servidor sin HTTP/2</strong> (ya ni hablamos de HTTP/3) o sin compresión Brotli/GZIP activa: rendimiento regalado que no cuesta dinero activar.</li>
<li><strong>Base de datos en MySQL 5.7 o MariaDB antiguas</strong>: funcionan, pero sin soporte y perdiendo mejoras de rendimiento considerables.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Sin CDN en webs con público geográficamente disperso: mejora disponible, no urgencia.</li>
<li>Espacio en disco o <a href="https://ayudawp.com/inodos/" target="_blank" rel="noopener">inodos</a> cerca del límite del plan: hoy anécdota, el día que la web no pueda escribir ni una imagen, drama.</li>
<li>Logs de error del servidor inaccesibles o desactivados: sin ellos, el próximo diagnóstico será a ciegas.</li>
</ul>
<h2>El núcleo de WordPress y ajustes que nadie revisa</h2>
<p>Aquí se audita el WordPress en sí, o sea, la <strong>versión, integridad del sistema, configuración y usuarios</strong>. Es el bloque más rápido de revisar y donde aparecen algunos de los hallazgos más incómodos de explicar al cliente, porque <strong>casi todos se arreglaban con un clic que nadie hizo en su momento</strong>.</p>
<p>Sin necesidad de código, la herramienta de salud del sitio te dice versión, actualizaciones pendientes y problemas de configuración, y en los ajustes de lectura está la casilla más peligrosa de WordPress, la de disuadir a los motores de búsqueda, que en más de una web estrenada lleva años marcada <strong>sin que nadie sepa por qué el SEO <em>no despega</em></strong>.</p>
<p>Repasa también los usuarios para saber cuántos administradores hay, si siguen en la empresa y si alguno se llama <code>admin</code>, que a estas alturas ya es casi una declaración de intenciones.</p>
<p>Con código, la comprobación estrella es la integridad del núcleo:</p>
<pre>wp core verify-checksums
wp plugin verify-checksums --all</pre>
<p>El primer comando compara cada archivo del núcleo con el original de WordPress.org y <strong>delata cualquier archivo modificado o añadido</strong>, que es una de las formas más rápidas de detectar una infección. El segundo hace lo mismo con los plugins del repositorio oficial.</p>
<p>Para realizar este tipo de comprobación si no tienes acceso a la interfaz de comandos puedes usar el <strong>scanner de integridad de archivos y la auditoría de seguridad del <a href="https://vigilante.works" target="_blank" rel="nofollow noopener">plugin de seguridad Vigilante</a></strong>.</p>
<p>En <code>wp-config.php</code> revisa que las claves y salts de seguridad existan y no sean las de ejemplo, que <code>WP_DEBUG</code> no esté activo en producción y si hay constantes útiles como <code>DISALLOW_FILE_EDIT</code> (desactiva el editor de código del admin, un clásico de la post-explotación).</p>
<h3>Crítico</h3>
<ul>
<li><strong>Núcleo de WordPress varias versiones mayores por detrás</strong>: no es solo funcionalidad, cada versión sin aplicar es una lista pública de vulnerabilidades corregidas que la web sigue teniendo.</li>
<li>Detectar con <code>verify-checksums</code> con <strong>archivos modificados o desconocidos en el núcleo</strong>: tratar como incidente de seguridad hasta demostrar lo contrario.</li>
<li><strong>Administradores que ya no trabajan en el proyecto</strong> con la cuenta activa, o cuentas compartidas entre varias personas: cada admin de más es una puerta de entrada más.</li>
<li><strong>Constantes</strong> <code>WP_DEBUG</code> con <code>WP_DEBUG_DISPLAY</code> activo en producción: rutas, consultas y errores del servidor impresos en pantalla para quien pase por allí.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Actualizaciones automáticas del núcleo desactivadas del todo, sin proceso alternativo que las cubra</strong>: las menores de seguridad deberían estar siempre activas.</li>
<li><strong>Salts de seguridad</strong> de <code>wp-config.php</code> <a href="https://ayudawp.com/seguridad-cookies-sesion/" target="_blank" rel="noopener">sin regenerar</a> desde el año de la instalación, o iguales entre el sitio de producción y copias de staging que andan por ahí.</li>
<li><strong>Prefijo de tablas</strong> <code>wp_</code> con usuarios y contraseñas heredados de instaladores automáticos antiguos: el prefijo en sí no es la muralla que algunos venden, pero el combo delata una instalación nunca revisada.</li>
<li><strong>Zona horaria, idioma o ajustes de comentarios</strong> sin configurar (bien): spam entrando a manta por comentarios abiertos sin moderación en entradas de hace cinco años, pingbacks y trackbacks activos, emails innecesarios.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Etiqueta <code>meta generator</code> con la versión de WordPress en el HTML: información innecesaria de cara al exterior.</li>
<li>Página «Hola mundo», página de ejemplo y temas de prueba aún publicados: cosmética, pero cosmética que retrata el nivel de mantenimiento que ha tenido la web.</li>
</ul>
<h2>El tema WordPress y sus personalizaciones</h2>
<p>Al tema le dediqué una guía completa de <a href="https://ayudawp.com/analizar-codigo-tema-wordpress/" target="_blank" rel="ugc noopener">auditoría de temas a medida</a>, con análisis de código, seguridad, rendimiento y SEO bloque a bloque, así que no voy a repetirla aquí. Lo que sí forma parte de esta auditoría general es lo que el tema cuenta de sí mismo a nivel de instalación, sin abrir un solo archivo.</p>
<p>En <code>Apariencia → Temas</code> lo razonable a revisar es <strong>el tema activo, su tema padre si es un tema hijo, y un tema de respaldo reciente de los de WordPress</strong> (el Twenty Twenty-algo de turno) para pruebas y emergencias.</p>
<p>Todo lo demás sobra, y no por manía, pues cada tema instalado es código presente en el servidor que hay que mantener actualizado aunque esté inactivo, porque <strong>un tema desactivado también es explotable si tiene una vulnerabilidad</strong>.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Tema activo sin actualizaciones disponibles</strong> porque el desarrollador desapareció o la licencia caducó: la web funciona sobre código congelado y sin parches, decisión estratégica a poner sobre la mesa del cliente cuanto antes.</li>
<li><strong>Tema padre modificado directamente</strong>, sin tema hijo: la próxima actualización del padre borra los cambios sin avisar.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Licencia del tema de pago sin saber quién la paga</strong> ni desde qué cuenta: mientras nadie lo aclare, las actualizaciones dependen de una renovación que quizás ya no existe.</li>
<li><strong>Media docena de temas instalados</strong> <em>por si acaso</em>: superficie de ataque y peso de mantenimiento sin beneficio alguno.</li>
<li><strong>Tema hijo con cambios sustanciales sin documentar</strong>: funciona, pero nadie sabe qué se tocó ni por qué, y eso en la práctica es deuda técnica heredada.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Tema hijo con cabecera incompleta o <code>style.css</code> vacío: señal de creación con prisas, revisar que al menos esté bien construido.</li>
</ul>
<p>Si el tema es a medida o hay mucho que revisar, ahí sí, guía completa de auditoría de temas que te comenté antes, y la herramienta gratuita de <a href="https://herramientas.ayudawp.com/theme-audit/" target="_blank" rel="ugc noopener">auditoría de temas WordPress</a> para documentar los hallazgos y generar el informe.</p>
<h2>Los plugins</h2>
<p>Este es el bloque estrella de la auditoría, y no lo digo por decir, pues <strong>la inmensa mayoría de las vulnerabilidades que se descubren en el ecosistema WordPress están en los plugins, casi todo el resto en los temas y un puñado testimonial en el núcleo</strong>, año tras año en cada informe del sector.</p>
<p>La seguridad, el rendimiento y buena parte de los problemas raros de una web WordPress viven en su lista de plugins, así que aquí conviene ir despacio.</p>
<p>Lo primero es el inventario. Sin necesidad de código puedes revisar la pantalla de plugins con sus contadores, con código esta línea te da la foto completa lista para pegar en el informe:</p>
<pre>wp plugin list --fields=name,status,version,update,auto_update</pre>
<p>Y ahora, las preguntas que hay que hacerle a esa lista, una por una:</p>
<ul>
<li><strong>¿Cuántos hay y cuántos están activos?:</strong> Los inactivos son código explotable en el servidor. Se verifica que no hagan falta, se borran (no solo desactivar) y listo.</li>
<li><strong>¿Cuáles están abandonados?:</strong> En la ficha de WordPress.org hay que mirar última actualización hace más de dos años, sin probar en las últimas tres versiones mayores o con el aviso naranja del repositorio. Un plugin abandonado no avisa, simplemente un día deja de funcionar o se convierte en el agujero por el que entran. Si tienes un plugin como Worfence o Vigilante te avisan en su scanner de plugins cerrados y abandonados.</li>
<li><strong>¿Hay duplicidades funcionales?:</strong> Dos plugins de caché, dos de SEO, tres de seguridad pisándose las reglas entre sí. Pasa muchísimo más de lo que parece, y el resultado nunca es <em>doble protección</em>, es doble carga y conflictos.</li>
<li><strong>¿Hay plugins de pago sin licencia?:</strong> Versiones pro que no se actualizan desde tiempos inmemoriales, o instaladas desde «clubs GPL» de dudosa procedencia. Además del riesgo legal que el cliente debe conocer, <strong>un plugin de pago sin licencia es un plugin sin actualizaciones, y sin actualizaciones no hay parches de seguridad</strong>.</li>
<li><strong>¿Tiene alguno vulnerabilidades conocidas?:</strong> Se busca cada plugin con su versión exacta en <a href="https://patchstack.com/database" target="_blank" rel="nofollow noopener">Patchstack</a> o <a href="https://wpscan.com/" target="_blank" rel="nofollow noopener">WPScan</a>. Si aparece con vulnerabilidad sin parchear, al primer puesto de la lista de acciones.</li>
<li><strong>¿Cuánto cuesta cada uno en rendimiento?:</strong> Con Query Monitor ves qué plugin mete más consultas y más tiempo en cada carga. No se trata del número de plugins, que ese debate está más que visto y <strong>el problema nunca es la cantidad de plugis, es sobrecargar la web con código que no necesita</strong>. Cinco plugins bien programados y realmente necesarios pesan menos que un todo-en-uno hinchado.</li>
<li><strong>¿Qué hay en mu-plugins y en los drop-ins?:</strong> La carpeta <code>mu-plugins</code> (plugins de activación obligatoria que no aparecen en la lista normal) y los drop-ins como <code>object-cache.php</code> o <code>advanced-cache.php</code> son los rincones que nadie mira, donde lo mismo vive una integración legítima del hosting que un regalo de un atacante con acceso pasado. En <code>Plugins → Imprescindibles</code> se listan los mu-plugins y, si hay plugins dependientes (<code>drop-ins</code>), aparece también su pestaña, y por consola los sacan <code>wp plugin list --status=must-use</code> y <code>wp plugin list --status=dropin</code>. Para asomarte a lo que hay dentro de esos archivos sin SSH, tira del gestor de archivos del hosting, que es justo el sitio donde un atacante esconde lo que no quiere que veas.</li>
<li><strong>¿Qué dejaron los plugins desinstalados?:</strong> Tablas huérfanas en la base de datos, opciones con autoload y tareas cron que siguen ejecutándose contra nada. Lo retomamos en el bloque de rendimiento, pero se detecta aquí, comparando la lista de plugins con lo que hay en la base de datos.</li>
</ul>
<p>Para algo rápido sin código hay truco, y es pegar la lista completa de plugins (nombre y versión) en tu IA de confianza con este prompt:</p>
<pre>Esta es la lista de plugins de una instalación WordPress con sus versiones. Dime: 1) cuáles parecen abandonados o con mala reputación de mantenimiento; 2) qué duplicidades funcionales detectas; 3) cuáles tienen vulnerabilidades conocidas en esas versiones; 4) qué preguntas debería hacerle al propietario sobre licencias. Preséntalo como tabla con nivel de prioridad.</pre>
<p>La respuesta no sustituye la comprobación en Patchstack o WPScan (la IA puede no conocer lo de esta semana), pero como primer barrido y detector de duplicidades funciona de maravilla.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Plugins con vulnerabilidades conocidas sin parchear en la versión instalada</strong>: actualización o retirada inmediata, antes de terminar la auditoría siquiera.</li>
<li><strong>Plugins <a href="https://ayudawp.com/plugins-temas-nulled-gpl/" target="_blank" rel="noopener">nulled</a> o de procedencia <em>desconocida</em></strong>: retirada y sustitución, sin matices. Nunca sabes qué llevan dentro, y lo que llevan dentro a veces se llama puerta trasera.</li>
<li><strong>Plugins abandonados ocupando funciones primordial de la web</strong> (formularios, tienda, membresías): planificar sustitución ya, no cuando falle.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Plugins inactivos acumulados</strong> sin verificar ni borrar.</li>
<li><strong>Duplicidades funcionales activas</strong> (especialmente caché y SEO): elegir uno, configurar bien y retirar el resto.</li>
<li><strong>Licencias de pago sin titular claro</strong>: documentar quién paga qué, cuánto y hasta cuándo, en el informe.</li>
<li><strong>Actualizaciones automáticas sin criterio</strong>: ni todo activado a lo loco en una web crítica sin staging, ni todo desactivado y sin nadie que actualice a mano. Lo importante es que haya una decisión consciente, no una casilla olvidada.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Plugins de un solo uso puntual (un import de hace años, un generador de algo) que siguen instalados: fuera con ellos.</li>
<li>Restos menores de plugins desinstalados en base de datos: se limpian en la fase de optimización, con copia previa.</li>
</ul>
<h2>La SEGURIDAD</h2>
<p>Instalar un plugin de seguridad y darse por protegido es como comprar un extintor para tu casa y dejarlo en el maletero del coche, porque de algo servirá, pero no es un plan. Lo que se audita aquí es <strong>cuántas capas reales de protección tiene la web y cuántas cree tener</strong>, que suelen ser números distintos.</p>
<p>Sin tener que tirar de código, el barrido externo ya lo hiciste con el análisis de seguridad del bloque sin accesos, y <strong>ahora toca la parte interna</strong>, que es probar a mano si responden URLs que jamás deberían responder, como <code>/debug.log</code>, <code>/.env</code>, <code>/phpinfo.php</code>, el listado de directorios en <code>/wp-content/uploads/</code> o copias de seguridad sueltas tipo <code>backup.zip</code> en la raíz.</p>
<p><strong>Cada una de esas URLs respondiendo contenido es un hallazgo directo al informe</strong>, y más habitual de lo que te gustaría creer.</p>
<p>Pero hay un hallazgo que no está en ninguna URL suelta pero aparece más de lo que parece, como una copia de staging, de pre-producción o un clon viejo del sitio accesible al público, que Google indexa y un atacante estudia a placer para colarse por la de verdad.</p>
<p>Si das con una, hasta que decidas si la migras o la borras, lo suyo es <strong>cerrarla con acceso obligatorio</strong>, y para eso te vale un plugin como <a href="https://es.wordpress.org/plugins/gozer/" target="_blank" rel="nofollow noopener">Gozer</a>, que deja la web entera detrás del acceso con un clic.</p>
<p>Con código, además de los checksums que ya pasaste en el bloque del núcleo, toca comprobar <a href="https://ayudawp.com/permisos-de-carpetas-y-archivos-en-wordpress/" target="_blank" rel="noopener">permisos de archivos</a> (directorios en <code>755</code>, archivos en <code>644</code> y <code>wp-config.php</code> más restrictivo), probar <code>xmlrpc.php</code> (si responde y nadie lo usa para nada, se cierra), consultar <code>/wp-json/wp/v2/users</code> a ver si la web muestra la lista de usuarios a cualquiera (enumeración vía REST API), y revisar a fondo las cabeceras de seguridad que anotaste en el barrido externo.</p>
<p>Si no tienes consola no te preocupes que este bloque de auditoría no se te queda a medias, la propia comprobación de seguridad que trae el plugin <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a> corre <strong>más de 40 chequeos desde dentro de WordPress</strong>, incluidos decenas que no se pueden hacer desde fuera, como los permisos de los archivos, los salts por defecto, el prefijo <code>wp_</code>, si hay algún administrador sin 2FA o si tu versión de PHP ya está fuera de soporte.</p>
<p>Así que buena parte de lo que sacarías por SSH lo tienes en una sola pantalla. Los permisos concretos también los ves y los cambias desde el gestor de archivos del hosting, y las URLs que no deberían responder las pruebas tú mismo en el navegador, que <strong>para eso no hace falta ni herramienta</strong>.</p>
<p>El modelo mental para el informe son <strong>3 niveles de cortafuegos</strong>:</p>
<ul>
<li><strong>CDN/perímetro</strong> (Cloudflare o similar por delante del servidor).</li>
<li><strong>Servidor</strong> (lo que ponga el hosting)</li>
<li><strong>Aplicación</strong> (plugin de seguridad bien configurado)</li>
</ul>
<p>No son obligatorios los tres en toda web, pero hay que saber cuáles hay, y <strong>si la respuesta es «ninguno», eso es un problema</strong>, no una opinión.</p>
<p>Y la joya de la corona, las copias de seguridad, donde la regla razonable es la <code>3-2-1</code> (tres copias, en dos soportes, una fuera del servidor). La copia de seguridad del hosting cuenta como una, no como el plan entero, porque si el servidor arde o la cuenta se suspende, se llevan la web y la copia en el mismo incendio.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Malware o código inyectado detectado</strong>: se acabó la auditoría normal, toca protocolo de limpieza, y si el sitio es un tema a medida revisa la guía de <a href="https://ayudawp.com/temas-wordpress-codigo-malicioso/" target="_blank" rel="ugc noopener">detección de código malicioso</a> antes de tocar nada.</li>
<li><strong>Archivos <code>debug.log</code>, <code>.env</code> o <code>phpinfo.php</code> accesibles públicamente</strong>: exposición directa de rutas, errores, credenciales o configuración del servidor.</li>
<li><strong>Sin identificación en dos pasos (2FA) en cuentas de administrador</strong>, combinado con login sin límite de intentos: la puerta principal abierta a fuerza bruta con toda la paciencia del mundo.</li>
<li><strong>Copias de seguridad inexistentes</strong>, solo en el propio servidor o nunca restauradas de prueba.</li>
<li><strong><a href="https://ayudawp.com/enumeracion-usuarios/" target="_blank" rel="noopener">Enumeración de usuarios</a> abierta</strong> vía REST API o archivos de autor, con nombres de usuario que coinciden con los del login, con lo que la mitad del trabajo del atacante ya se la das hecha.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Cabeceras de seguridad ausentes o incompletas</strong> (<code>HSTS</code>, <code>CSP</code> aunque sea básica, <code>X-Frame-Options</code>, <code>Referrer-Policy</code>).</li>
<li><code>xmlrpc.php</code> activo sin uso que lo justifique.</li>
<li><strong>Sin cortafuegos</strong> de aplicación ni plugin de seguridad configurado, o instalado con los ajustes de fábrica sin adaptar.</li>
<li><strong>Listado de directorios activo</strong> en <code>uploads</code> o directorios sensibles.</li>
<li><strong>Sin monitorización de cambios en archivos</strong>: para esto <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a> es fundamental, es un plugin gratuito, escanea los archivos y te avisa si alguien modifica algo sin que lo sepas, que es exactamente lo que hace un atacante cuando planta una puerta trasera en un archivo que ya existía. La auditoría te dice cómo está la web hoy, Vigilante te avisa si deja de estarlo mañana.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>URL de acceso sin enmascarar: medida cosmética que reduce ruido de bots, no sustituye a nada de lo anterior, pero como higiene vale.</li>
<li>Meta generator, <code>readme.html</code> y versiones visibles: ya anotado en el barrido externo, se resuelve junto al resto.</li>
<li>Endpoint de Application Passwords activo sin uso conocido: revisar y cerrar si nadie lo necesita.</li>
</ul>
<h2>Rendimiento y velocidad de carga</h2>
<p>Antes de tocar nada conviene separar dos mundos que se confunden constantemente. Me refiero a <strong>los datos de campo</strong> (lo que experimentan los usuarios reales, que es lo que Google usa para valorar la web) y, por otro lado, a <strong>los datos de laboratorio</strong> (la simulación que hace la herramienta de turno para diagnosticar).</p>
<p>El informe se abre con los de campo, que salen en PageSpeed Insights si la web tiene tráfico suficiente, y las referencias son las métricas web principales: <strong>LCP hasta 2,5 segundos, INP hasta 200 ms y CLS hasta 0,1</strong>. El laboratorio viene después, para averiguar el porqué de cada suspenso.</p>
<p>La revisión interna va por <a href="https://ayudawp.com/caches-wordpress/" target="_blank" rel="noopener"><strong>capas de caché</strong></a>, que en una web sana son varias y coordinadas:</p>
<ul>
<li><strong>Caché de página</strong> (el plugin de turno o la del hosting, uno solo y bien configurado)</li>
<li><strong>Caché de objetos</strong> (Redis o Memcached si el hosting la ofrece, imprescindible para tiendas y membresías),</li>
<li><strong>OPcache de PHP y caché de navegador</strong> con sus caducidades.</li>
</ul>
<p>Como auditor tu misión no es saber si hay un plugin de caché, la cuestión adecuada es más bien <strong>cuántas capas hay, si se solapan y con qué criterio se han configurado</strong>.</p>
<p>Después, la base de datos, esa gran olvidada. Con código, esta línea te dice cuántos KB de <a href="https://ayudawp.com/optimizar-autoload-opciones-base-datos/" target="_blank" rel="noopener">opciones se cargan en memoria en cada petición</a> (<code>autoload</code>):</p>
<pre>wp option list --autoload=on --format=total_bytes</pre>
<p>Por debajo de 1 MB vas bien, y a partir de ahí cada MB extra es lastre que se carga en todas y cada una de las visitas. El <strong>desglose de culpables</strong> te lo da <a href="https://wordpress.org/plugins/aaa-option-optimizer/" target="_blank" rel="nofollow noopener">AAA Option Optimizer</a>, que además identifica opciones huérfanas de plugins ya desinstalados.</p>
<p>Completa el repaso con <strong>revisiones acumuladas por miles, transients caducados y tablas huérfanas</strong>, todo ello con copia de seguridad previa antes de limpiar nada.</p>
<p>Quedan <strong>los sospechosos habituales</strong>, que son las imágenes sin optimizar (formatos modernos WebP o AVIF, tamaños acordes a lo que se muestra, carga diferida nativa).</p>
<p>También cuentan las <strong>fuentes cargadas desde Google en vez de alojadas en local</strong> (doble motivo para cambiarlo, el segundo te espera en el bloque RGPD), el Heartbeat de WordPress a su ritmo por defecto en el admin, y JavaScript y CSS sin minimizar ni combinar con criterio.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Métricas web principales suspensas en campo en móvil</strong>: afectan hoy mismo a usuarios y posicionamiento.</li>
<li><strong>Sin ninguna caché de página activa</strong> en una web con tráfico: cada visita cocina la página desde cero, con el servidor pagando la fiesta.</li>
<li><strong>Autoload de opciones desbocado</strong> (varios MB): impuesto invisible en cada petición, incluidas las del admin.</li>
<li><strong>Dos o más plugins de caché u optimización activos a la vez</strong>: no suman, se pisan, y los efectos son de los que vuelven loco a cualquiera («a veces va lento, a veces no»).</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Sin caché de objetos</strong> disponible o disponible pero sin activar en webs con WooCommerce o membresías.</li>
<li><strong>Imágenes a pelo</strong>: sin formatos modernos, sin dimensionar y sin comprimir. Suele ser la mejora más visible por esfuerzo invertido.</li>
<li><strong>Fuentes externas de Google sin alojar</strong> en local.</li>
<li><strong>Base de datos sin mantenimiento</strong>: revisiones infinitas, transients caducados, restos de plugins.</li>
<li><strong>Heartbeat sin controlar</strong> en webs con muchos usuarios simultáneos en el admin.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Minimizado de JS/CSS sin aplicar: mejora real pero modesta, y siempre después de tener el resto en orden.</li>
<li>Recursos (<code>assets</code>) que cargan en páginas donde no se usan: afinado fino, planificable.</li>
</ul>
<h2>SEO / AEO técnico</h2>
<p>Aquí no se audita el contenido ni las palabras clave, se audita la fontanería, las tripas, <strong>que lo que debe indexarse se pueda indexar, que lo que no deba no se indexe, y que ninguna configuración esté saboteando el trabajo de nadie</strong>. Es un bloque donde los hallazgos críticos suelen ser pocos pero de los que hacen polvo el negocio del cliente.</p>
<p>Empieza por lo que ya viste en el núcleo (la casilla de visibilidad) y sigue con el plugin SEO, y no es complicado, básicamente que haya uno, que sea uno solo y que esté bien configurado, adaptado al sitio, no instalado y ya.</p>
<p>Aquí cada maestrillo tiene su librillo, y yo en mis webs uso <a href="https://visibility.quest/" target="_blank" rel="nofollow noopener">Visibility</a>, plugin de <strong>SEO nativo y ligero</strong> pensado justo para sustituir suites hinchadas, pero lo que se audita no es la marca del plugin sino <strong>que la herramienta esté bien elegida y mejor configurada</strong>.</p>
<p>Después el <code>robots.txt</code> (que no bloquee CSS ni JavaScript y que no arrastre un <code>Disallow: /</code> heredado de staging), el mapa del sitio (accesible, declarado en <code>robots.txt</code>, enviado a Search Console y Bing, y sin URLs que no deberían estar).</p>
<p>Las redirecciones (una sola cadena de www/no-www y HTTP a HTTPS, sin saltos encadenados) y el estado de indexación real en Search Console Bing Webmasters, que para eso pediste el acceso al principio.</p>
<p>Del lado del código fuente toca ver <strong>si el canonical es correcto</strong>, que haya un solo H1 por página y <strong>jerarquía de encabezados</strong> sin saltos (el detalle fino lo tienes en la guía de auditoría de temas), schema sin duplicar entre tema y plugin SEO, y <code>hreflang</code> si hay idiomas.</p>
<p>Para saber en qué se está gastando Google el rastreo de la web, mi <a href="https://herramientas.ayudawp.com/crawl-limit/" target="_blank" rel="ugc noopener">analizador de límites de rastreo</a> te da la foto del <code>crawl budget</code> (el presupuesto de rastreo que Google dedica al sitio) sin instalar nada.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Casilla de disuadir buscadores activa</strong>, meta robots <code>noindex</code> global o <code>Disallow: /</code> en <code>robots.txt</code> en una web en producción: la web está pidiendo por escrito que no la encuentren.</li>
<li><strong>Dos plugins SEO</strong> activos o <strong>schema y metas duplicados entre tema y plugin</strong>: dos fuentes contándole a Google cosas distintas sobre la misma página.</li>
<li><strong>Acciones manuales o problemas de seguridad notificados en Search Console</strong> que nadie ha leído: pasa, y más de lo que parece, porque nadie mira el buzón.</li>
<li><strong>Redirecciones en cadena o bucles</strong> entre versiones www/no-www y HTTP/HTTPS.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Mapa del sitio con URLs <code>noindex</code>, archivos adjuntos o taxonomías vacías</strong>, que son ruido que gasta rastreo.</li>
<li><strong>Errores 404</strong> en enlaces internos y sin sistema de redirecciones para URLs que cambiaron.</li>
<li><strong>Enlaces externos <code>dofollow</code> donde deberían ser <code>nofollow</code></strong> (patrocinados, afiliados sin marcar, iconos sociales, páginas legales).</li>
<li><strong>Imágenes sin texto alternativo de forma sistemática</strong>, lo que supone accesibilidad y SEO de imágenes a la vez.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Relación texto/código muy baja en páginas clave es señal de plantillas sobrecargadas, se anota para la fase de mejoras.</li>
<li>Migas de pan ausentes o sin schema correspondiente.</li>
</ul>
<h2>Visibilidad IA</h2>
<p>Cada vez más gente pregunta directamente a ChatGPT, Claude, Perplexity y compañía, y <a href="https://ayudawp.com/ai-overviews-google/" target="_blank" rel="ugc noopener">Google responde con IA</a> antes de mostrar el primer resultado clásico.</p>
<p>Eso convierte en revisión de auditoría algo que hace tres años no existía, <strong>saber si pueden las IAs descubrir, entender y citar el contenido de esta web</strong> Y otra duda igual de legítima, <strong>si quiere el propietario que puedan</strong>.</p>
<p>Porque este bloque tiene una particularidad que no tiene ningún otro, que <strong>el resultado correcto depende de una decisión de negocio del cliente</strong>.</p>
<p>Hay quien quiere aparecer en cada respuesta de IA y hay quien no quiere ceder ni una coma para entrenamiento. <strong>Decidirlo no te toca a ti, tu trabajo es documentar el estado actual y sus consecuencias</strong>, que casi siempre son involuntarias, pues la mayoría de las webs ni bloquean ni facilitan, simplemente nadie ha mirado.</p>
<p><strong>Hay mucho que revisar</strong>, como las directivas para bots de IA en <code>robots.txt</code>, con el matiz de que el <code>robots.txt</code> es orientativo, quien de verdad quiera bloquear necesita hacerlo por PHP con respuesta 403), <a href="https://ayudawp.com/llms-txt/" target="_blank" rel="ugc noopener">archivos <strong>llms.txt y llms-full.txt</strong></a>, <strong>Content Signals</strong> en <code>robots.txt</code> (definido por Cloudflare para declarar qué usos permites de búsqueda, asistentes y entrenamiento de IA), datos estructurados <a href="https://ayudawp.com/tag/json-ld/" target="_blank" rel="noopener"><strong>JSON-LD</strong></a> de identidad, etiquetas <strong>Open Graph y Twitter Cards</strong>, HTML5 semántico, feed RSS accesible, contenido legible sin ejecutar JavaScript y, en el extremo más avanzado, contenido en <strong>Markdown para agentes de IA</strong>.</p>
<p>Mucho que revisar ¿verdad? No te preocupes, hay ayudas para todo.</p>
<p><strong>Para el diagnóstico externo</strong> tienes el <a href="https://herramientas.ayudawp.com/ai-visibility/" target="_blank" rel="ugc noopener">analizador de visibilidad IA</a> puntúa la web sobre 100 en cinco categorías y te dice exactamente qué falta. Sencillo, completo y gratis.</p>
<p>Y <strong>para implantar y vigilar desde dentro usa <a href="https://es.wordpress.org/plugins/vigia/" target="_blank" rel="nofollow noopener">VigIA</a></strong>, esa joya de plugin, también gratuito, que monitoriza más de 55 rastreadores de IA con analítica de cuáles pasan y qué leen, genera los <code>llms.txt</code>, sirve el contenido como Markdown para agentes, añade el JSON-LD de identidad y bloquea por PHP a los bots que decidas, todo en uno y de paso <strong>midiendo qué rastreadores ignoran tu <code>robots.txt</code></strong>.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Contenido invisible sin JavaScript</strong> en una web que vive de ser encontrada: si el HTML llega vacío, para buena parte de los rastreadores de IA la web no existe.</li>
<li><strong>Bloqueos involuntarios heredados</strong> (reglas anti-bots del hosting o CDN que nadie configuró a propósito) en una web cuyo negocio es la visibilidad.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Sin decisión documentada sobre bots de IA</strong>: ni directivas, ni señales, ni criterio. El hallazgo que apuntas al informe ahí se llama «nadie ha decidido nada».</li>
<li><strong>Sin datos estructurados de identidad</strong> (WebSite/Organization) ni Open Graph: las IAs pueden leer la web pero no saben de quién es ni cómo citarla.</li>
<li><strong>Feed RSS desactivado o roto</strong>: sigue siendo una de las vías favoritas de descubrimiento de contenido, también para las IAs.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Sin <code>llms.txt</code> ni Markdown para agentes en una web que sí quiere visibilidad IA: mejora incremental, fácil de añadir con VigIA.</li>
<li>Sin Content Signals en <code>robots.txt</code>: el estándar es joven, pero declarar intenciones cuesta un minuto.</li>
</ul>
<h2>Legalidad técnica y funcional</h2>
<p>Aviso antes de empezar, para que quede claro, no soy abogado y esto no es asesoramiento jurídico. Lo que sí puedo contarte es <strong>qué comprueba un técnico en una auditoría para saber si la web tiene los deberes hechos o está coleccionando papeletas para una sanción</strong>, y con eso tu cliente ya puede ir a su asesor con datos en vez de con vaguedades.</p>
<p>La comprobación principal se hace con las <strong>DevTools del navegador</strong> en una ventana de incógnito. Para ello abre la pestaña de red y la de cookies <strong>antes de aceptar nada en el banner</strong> y mira qué se carga. Si ya hay cookies de analítica o marketing, o peticiones saliendo hacia Google, Meta y compañía antes del consentimiento, el banner es decorativo, y <strong>un banner decorativo es peor que no tenerlo</strong>, porque documenta que sabías que tenías que pedir permiso.</p>
<p>El criterio vigente de la AEPD añade otra comprobación de primero de RGPD: <strong>rechazar tiene que ser tan fácil como aceptar</strong>, mismo nivel, mismo número de clics.</p>
<p>Las <strong>fuentes de Google cargadas en remoto</strong> son el segundo clásico. Un tribunal alemán ya sentenció que enviar la IP del visitante a Google sin consentimiento por cargar una fuente es sancionable, y de aquella sentencia llovieron reclamaciones por media Europa. Se detectan en la pestaña de red (peticiones a <code>fonts.googleapis.com</code> o <code>fonts.gstatic.com</code>).</p>
<p>El mismo repaso vale para <strong>vídeos de YouTube incrustados sin modo de privacidad mejorada</strong>, mapas y cualquier recurso de terceros que se cargue antes de consentir.</p>
<p>Completa el bloque lo de siempre que casi nunca está, como <strong>formularios y su primera capa informativa y casilla de aceptación sin activar</strong> por defecto, textos legales que describan lo que la web hace de verdad (no la plantilla de otra web con el buscar-y-reemplazar a medias, que hay por ahí cada política de privacidad con el nombre de otra empresa dentro que asusta), y si hay productos de Google en juego, <a href="https://ayudawp.com/tcfv2/" target="_blank" rel="noopener">Consent Mode v2</a> funcionando, obligatorio para audiencias del Espacio Económico Europeo.</p>
<p>Hasta aquí las cookies, pero hay <strong>otro consentimiento que casi nadie audita</strong> y que no tiene nada que ver con el banner. Una cosa es <strong>ePrivacy</strong>, lo del banner de cookies, y otra el consentimiento al que se refiere el artículo 7.1 del RGPD, <strong>el de aceptar tus condiciones o tu privacidad en un formulario, en el registro o en el pago</strong>.</p>
<p><strong>La mayoría de webs tienen la casilla marcada pero no guardan ninguna prueba de que se marcó</strong>, y el 7.1 no pide la casilla, pide <strong>que puedas demostrar el consentimiento</strong>: cuándo se dio, desde qué IP, y qué texto y qué versión se aceptaron. Sin ese registro una casilla marcada no vale de nada el día que alguien reclama.</p>
<p>Hay plugins de cookies que incluyen algún registro suelto, pero <strong>para dejar esa prueba sellada y a prueba de manipulación</strong> tienes <a href="https://es.wordpress.org/plugins/terms-conditions-consent-log/" target="_blank" rel="nofollow noopener">Terms &amp; Conditions Consent Log</a>, que guarda <strong>fecha, IP, agente de usuario, versión y el texto exacto con un hash SHA-256</strong>, y funciona con WooCommerce, Contact Form 7, WPForms, Gravity Forms, Fluent Forms y hasta los comentarios y el registro de WordPress.</p>
<p>Y si la web es una tienda (o sitio corporativo de una física), apunta otra obligación que no estaba hace nada, y que desde el 19 de junio de 2026 está en vigor en toda la UE el <strong>desistimiento digital</strong>, la Directiva 2023/2673, que exige <strong>que el cliente pueda desistir de su compra tan fácil como la hizo, con un botón o formulario claro</strong>, respetando los 14 días y con las exclusiones del artículo 16 bien marcadas, que es lo que por ley no admite devolución.</p>
<p><strong>Comprobar que ese mecanismo existe y que funciona es tan parte de la auditoría legal como el banner de cookies</strong>, y lo verás de verdad al hacer el pedido de prueba del bloque de tienda. Te lo cuento a fondo en la guía del <a href="https://ayudawp.com/desistimiento-ue-woocommerce/" target="_blank" rel="ugc noopener">derecho de desistimiento en WooCommerce</a>.</p>
<p>Para cumplirlo ya hay varios plugins de botón de desistimiento en el repositorio, pero ninguna cumplía del todo así que preparé uno que sí, gratis como siempre, <strong><a href="https://es.wordpress.org/plugins/eu-withdrawal-compliance/" target="_blank" rel="nofollow noopener">EU Withdrawal Compliance</a></strong>, que añade la función de desistimiento, guarda un recibo con hash SHA-256, incluye el formulario modelo del anexo I.B y te deja marcar las exclusiones del artículo 16 por producto y por categoría, <strong>con o sin WooCommerce</strong>.</p>
<p>La accesibilidad tampoco es ya cosa de buenos samaritanos, la <strong>Ley Europea de Accesibilidad</strong> está en vigor desde junio de 2025 y obliga a la mayoría de webs comerciales, así que en una auditoría de 2026 hay que mirarla, aunque sea por encima.</p>
<p>No toca hacer aquí una auditoría WCAG completa, pero sí un primer barrido de <strong>lo fundamental</strong>, o sea contraste suficiente, textos alternativos en las imágenes, que se pueda navegar con el teclado, formularios con sus etiquetas y que no haya barreras evidentes.</p>
<p>Para ese primer barrido tienes el <a href="https://herramientas.ayudawp.com/accesibilidad/" target="_blank" rel="ugc noopener">analizador de accesibilidad web</a> de mis herramientas, que revisa la web según las pautas WCAG y te dice qué falla.</p>
<p><strong>Eso sí, ninguna herramienta automática detecta más que una parte de los problemas de accesibilidad</strong>, así que lo que salga limpio ahí todavía necesita una revisión a mano, igual que pasa con cualquier análisis automático frente a una auditoría manual.</p>
<p>Y una última de tienda, fundamental si ofreces rebajas, descuentos, ofertas o como lo llames. Me refiero a la <strong>directiva Omnibus</strong>, que <strong>obliga a mostrar el precio más bajo de los últimos 30 días junto al precio rebajado</strong>. El clásico «antes 50 €, ahora 30 €» sin ese dato incumple, y es sancionable.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Cookies y rastreadores cargando antes del consentimiento</strong>: el hallazgo RGPD más frecuente y el más fácil de demostrar por cualquiera que reclame.</li>
<li><strong>Sin textos legales</strong>, o textos de otra web con nombres de empresa ajenos aún dentro.</li>
<li><strong>Formularios</strong> que recogen datos personales sin información ni aceptación alguna.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Banner sin opción de rechazo</strong> al mismo nivel que la aceptación.</li>
<li><strong>Fuentes de Google y recursos de terceros</strong> cargando en remoto sin consentimiento.</li>
<li><strong>Consent Mode v2 ausente</strong> usando Google Analytics o Ads con público europeo.</li>
<li><strong>Nadie sabe qué encargados del tratamiento hay</strong> (hosting, CDN, email marketing) ni dónde se firmaron los contratos de encargo.</li>
<li><strong>Formularios, registro o pago sin prueba del consentimiento</strong>: la casilla marcada, pero sin el registro con fecha, IP, texto y versión que exige el artículo 7.1 para poder demostrarlo.</li>
<li><strong>Tienda sin mecanismo de desistimiento</strong> accesible, o sin las exclusiones del artículo 16 marcadas, con la obligación de la Directiva 2023/2673 ya en vigor.</li>
<li><strong>Barreras de accesibilidad</strong> que incumplen la Ley Europea de Accesibilidad: contraste insuficiente, imágenes sin texto alternativo, navegación imposible con teclado o formularios sin etiquetas.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Política de cookies desactualizada respecto a las cookies que la web pone en realidad: toca inventario y puesta al día.</li>
<li>Solicitudes de permisos del navegador (geolocalización, notificaciones) disparadas nada más cargar la página: además de molestas, difíciles de justificar.</li>
<li>Rebajas sin mostrar el precio más bajo de los últimos 30 días que exige la directiva Omnibus.</li>
</ul>
<h2>Tienda online</h2>
<p>Si no hay tienda salta este bloque, y si la hay redobla la atención, porque <strong>aquí ya no auditas una web, auditas una caja registradora, y cada fallo tiene un coste que se mide en pedidos perdidos</strong>, no en puntuaciones de herramienta.</p>
<p>La primera revisión es el estado de WooCommerce Estado (<code>WooCommerce → Estado</code>), que por sí solo te dice la <strong>versión y base de datos de WooCommerce, plantillas sobreescritas obsoletas</strong> (lo vimos a fondo en la guía de temas) y el <strong>estado de HPOS, el almacenamiento de pedidos en tablas propias</strong> que ya es el modo por defecto en instalaciones nuevas.</p>
<p>Si la tienda sigue en modo antiguo, o peor, en modo compatibilidad con sincronización eterna, hay que averiguar qué plugin lo está impidiendo y <strong>valorar la migración con calma</strong> y en staging.</p>
<p>La segunda <strong>revisión obligatoria es hacer una compra, de verdad</strong>, del principio al final, probando el modo sandbox de la pasarela o producto de prueba de un céntimo, pero completa.</p>
<p>Esta es la única forma de saber si el checkout funciona, si hay errores de JavaScript en consola a mitad de proceso, si los impuestos cuadran y, atención a esta, <strong>si los correos del pedido llegan al cliente y a la tienda</strong>, que enlaza con el SPF y el SMTP que auditaste en el bloque de servidor.</p>
<p>Y ya que estás dentro del proceso, <strong>comprueba también si hay mecanismo de desistimiento</strong> como vimos antes en el bloque de legalidad, porque es aquí, con la compra hecha, donde se ve de verdad si el cliente puede ejercer su derecho con la misma facilidad con la que ha pagado.</p>
<p>Aprovecha para revisar las pasarelas de pago, con las claves de producción donde haga falta y que no haya ningún modo de pruebas olvidado desde el lanzamiento, que haberlos haylos.</p>
<p>Y la tercera es el <strong>programador de acciones</strong> (la cola de tareas internas de WooCommerce), que se revisa en <code>WooCommerce → Estado → Acciones programadas</code>. Te puedes encontrar con <strong>decenas de miles de acciones fallidas o pendientes acumuladas</strong>, que pueden ser síntoma de algo roto por debajo, pero siempre son <strong>lastre para la base de datos</strong>. Si se desmadra (que lo hará) ten siempre a mano <a href="https://es.wordpress.org/plugins/easy-actions-scheduler-cleaner-ayudawp/" target="_blank" rel="nofollow noopener">el plugin para limpiar las acciones programadas innecesarias</a>.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Pasarela en modo de pruebas en producción</strong>, o claves de test y producción mezcladas: pedidos que parecen cobrados y no lo están.</li>
<li><strong>Correos transaccionales que no llegan</strong>: pedidos a ciegas para el cliente y para la tienda.</li>
<li><strong>Pago con errores de JavaScript o pasos rotos en móvil</strong>: dinero saliéndose por el desagüe cada día que pasa.</li>
<li><strong>Plugins clave de la tienda incompatibles con HPOS</strong> consultando pedidos a la antigua: roturas silenciosas ya o en la próxima actualización.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Plantillas de WooCommerce sobreescritas</strong> varias versiones por detrás.</li>
<li><strong>Programador de acciones</strong> con miles de tareas fallidas o pendientes sin explicación.</li>
<li><strong>Impuestos mal configurados o precios sin coherencia</strong> entre ficha, carrito y checkout.</li>
<li><strong>Webhooks de integraciones</strong> (ERP, email marketing, envíos) fallando en silencio.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Checkout con campos innecesarios y distracciones: mejora de conversión a proponer, no urgencia técnica.</li>
<li>Pedidos de prueba y datos de desarrollo aún en la base de datos de producción.</li>
</ul>
<p>Para terminar, repasa la sección anterior sobre legalidad, porque en tiendas la cosa está cargadita, y las sanciones son tremendas.</p>
<h2>Multisitio: auditar una red no es auditar una web</h2>
<p>Si el sitio es una instalación normal sáltate este bloque. Y si es una red multisitio, prepárate, porque <strong>una red no es un área más que auditar, es un modo que cambia cómo auditas todo lo anterior</strong>.</p>
<p>Aquí <strong>varios sitios comparten una sola instalación de WordPress, la misma base de datos, los mismos archivos de plugins y temas y, muchas veces los mismos usuarios</strong>, así que un fallo en un rincón puede llevarse la red entera por delante.</p>
<p>Lo primero es tener claro qué está compartido, porque ahí viven casi todos los riesgos.</p>
<p><strong>El código es común</strong>, o sea que una vulnerabilidad en un plugin o un tema no afecta a un sitio, afecta a todos a la vez. <strong>Los usuarios también son comunes</strong>, porque la tabla <code>wp_users</code> es única para toda la red, y <strong>una inyección SQL</strong> en el sitio más tonto puede exponer los usuarios y las contraseñas de todos, superadministradores incluidos.</p>
<p>Las subidas van a una carpeta compartida, <code>/wp-content/uploads/sites/ID/</code>, donde un archivo malicioso colado en un sitio vive pared con pared con el resto. El caso de manual que se repite es justo ese, un PHP colado en uploads, la tabla de usuarios volcada, una contraseña débil de superadmin reventada y puerta trasera en toda la red en una tarde.</p>
<p>Por encima de todo está el superadministrador, que en una red es el modo dios, pues crea y borra sitios, instala plugins y temas para todos y gestiona a cualquier usuario.</p>
<p>Así que la primera pregunta de la auditoría es <strong>cuántos superadmins hay</strong> (lo razonable son tres o menos), si alguno es en realidad un cliente que no debería serlo, si todos tienen 2FA y si sigue en el proyecto la gente que aparece en esa lista.</p>
<p>Sin tocar código, casi todo esto lo tienes en el escritorio de red, en <code>Mis sitios → Administrar red</code>. Ahí está la lista de sitios con su estado, los usuarios de toda la red, los plugins y temas disponibles y la pantalla de actualizaciones.</p>
<p>Con eso auditas la red sin abrir una consola. Con WP-CLI, <code>wp site list</code> te saca todos los sitios con su ID y su URL, <code>wp user list --network</code> los usuarios, y para actuar sobre un sitio concreto le añades <code>--url=</code> a cualquier comando. Tras actualizar el núcleo, no olvides <code>wp core update-db --network</code>, que pone al día la base de datos de todos los sitios de golpe.</p>
<p>Dos cosas más que la red cambia respecto a un sitio suelto. Una es que <strong>una actualización toca todos los sitios a la vez</strong>, así que el staging deja de ser recomendable y pasa a ser obligatorio, porque una incompatibilidad no rompe un sitio, rompe la red.</p>
<p>La otra es que los recursos del servidor son compartidos, de modo que un pico de tráfico o un plugin desbocado en un solo sitio degrada a todos los demás, que es justo lo del bloque de picos de tráfico pero multiplicado.</p>
<p>En lo relativo a la seguridad en redes multisitio la regla de oro es activar en red solo lo imprescindible, porque <strong>cada plugin activado en red se ejecuta en todos los sitios en cada carga</strong>, y lo demás actívalo sitio a sitio.</p>
<p>Lo que pongas de seguridad, o sea cortafuegos, bloqueo de ejecución de PHP en uploads, escaneo de integridad y registro de actividad, compruébalo antes en un plugin que sea compatible con multisitio, que muchos no lo son.</p>
<p>Vigilante, por ejemplo, funciona en red, aunque con ajustes independientes por sitio y sin un panel único que lo gobierne todo de golpe, así que aseguras cada sitio pero lo configuras uno a uno. Hay modos de hacerlo desde un panel único pero mi consejo es que mientras sea manejable gestiones la seguridad sitio a sitio.</p>
<h3>Crítico</h3>
<ul>
<li><strong>Superadmins de más</strong>, alguno que es un cliente, o cuentas de superadmin activas de gente que ya no está: en una red, cada una es la llave maestra de todo.</li>
<li><strong>Ejecución de PHP habilitada en la carpeta de subidas compartida</strong>: la vía más habitual para plantar una puerta trasera que afecta a toda la red desde un solo sitio.</li>
<li><strong>Un plugin o un tema con vulnerabilidad conocida activo en la red</strong>: no es un sitio en riesgo, son todos a la vez.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><strong>Plugins activados en red que solo usa un sitio</strong>: peso y superficie de ataque en todos los demás sin ningún motivo.</li>
<li><strong>Prefijo de tablas <code>wp_</code> por defecto y un único usuario de base de datos con permisos de sobra</strong>: facilita el salto de un sitio comprometido al resto.</li>
<li><strong>Sin registro de actividad en los sitios de la red</strong>: aunque casi ningún plugin ofrezca todavía un panel único para toda la red, cada sitio debería al menos registrar su actividad para saber qué pasó y quién lo hizo.</li>
<li><strong>Actualizaciones de red aplicadas sin staging</strong> previo.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Sitios de la red archivados, marcados como spam o de prueba que nadie ha limpiado: ruido que conviene revisar y retirar.</li>
<li>Copias de seguridad por sitio en lugar de una copia de toda la red: en multisitio se respalda la instalación completa, no las tablas de un sitio suelto.</li>
</ul>
<h2>El informe</h2>
<p>Una auditoría que termina en una lista de 200 problemas (o más) sin orden ni contexto no sirve para nada, o peor, sirve para asustar al cliente y que no contrate ninguna solución.</p>
<p><strong>El valor de una auditoría web no está en encontrar fallos sino en convertirlos en un plan que alguien pueda aprobar</strong>, y para eso el informe necesita tres cosas: prioridades, evidencias y separación clara entre lo urgente y lo deseable.</p>
<p>Las prioridades ya las traes hechas, porque los tres niveles de cada bloque trasladan directos al plan de trabajo:</p>
<ul>
<li><strong>Lo crítico se corrige antes de cualquier otra cosa</strong> (y si asumes el mantenimiento, antes de considerar la web «bajo tu responsabilidad»)</li>
<li><strong>Lo importante se planifica</strong> en la próxima actuación o antes de la siguiente versión mayor de WordPress o PHP</li>
<li><strong>Lo menor se documenta</strong> para resolverlo cuando se pase por ese código o esa configuración por otra razón.</li>
</ul>
<p>Deja evidencia de todo, con capturas de cada hallazgo (en lo posible), su dato o su URL. No por desconfianza, sino porque dentro de seis meses nadie recordará por qué se decidió algo, y el informe es la memoria del proyecto.</p>
<p>Este esquema, por cierto, no me lo he inventado para el artículo, <strong>es el mismo que uso en los informes iniciales <a href="https://ayudawp.com/necesidad-mantenimiento-web/" target="_blank" rel="noopener">cuando asumo el mantenimiento de una web</a></strong>, con la situación previa área por área y las soluciones en dos listas separadas, las inmediatas que se aplican de oficio (copia de seguridad, monitorización, actualizaciones seguras) y las <strong>propuestas que requieren aprobación o presupuesto</strong>.</p>
<p>Y una recomendación de cierre para el documento es que escribas la parte de conclusiones en el idioma del cliente, no en el tuyo. «El autoload de wp_options pesa 9 MB» no significa nada para quien firma las facturas, pero «tu web carga en cada visita varios <em>megas</em> de imágenes, y tus clientes pueden abandonar la web si tarda más de 3 segundos» sí.</p>
<h2>Herramientas gratuitas</h2>
<p>Las herramientas de diagnóstico que han ido apareciendo por el artículo, y más, las tienes en <a href="https://herramientas.ayudawp.com/" target="_blank" rel="ugc noopener">herramientas.ayudawp.com</a>: el análisis de seguridad externo, el analizador de visibilidad IA, el de límites de rastreo, el analizador de accesibilidad web y la auditoría de temas para documentar hallazgos e imprimir el informe.</p>
<p>Allí tienes también unos cuantos generadores que te vendrán genial cuando toque corregir lo encontrado, como el de cabeceras de seguridad, el de <code>wp-config.php</code>, el de <code>.htaccess</code>, el de <code>robots.txt</code> o el de <code>security.txt</code>, además del optimizador de imágenes, pero eso ya es otra fase y otro artículo. Son gratuitas, en español, sin registro y funcionando en tu navegador.</p>
<p>Además, luego tienes <strong>plugins que considero imprescindibles</strong>, y te resumo:</p>
<ul>
<li><strong>Seguridad</strong>: <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a> o All in one security</li>
<li><strong>SEO</strong>: <a href="https://es.wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="nofollow noopener">Visibility</a> o The SEO Framework</li>
<li><strong>Visibilidad IA</strong>: <a href="https://es.wordpress.org/plugins/vigia/" target="_blank" rel="nofollow noopener">VigIA</a>, <a href="https://es.wordpress.org/plugins/ai-share-summarize/" target="_blank" rel="nofollow noopener">AI Share &amp; Summarize</a>, <a href="https://es.wordpress.org/plugins/ai-content-signals/" target="_blank" rel="nofollow noopener">AI Content Signals</a>, <a href="https://es.wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="nofollow noopener">Visibility</a></li>
<li><strong>Rendimiento y velocidad de carga</strong>: <a href="https://es.wordpress.org/plugins/wpo-tweaks/" target="_blank" rel="nofollow noopener">DietPress</a>, <a href="https://ayudawp.com/query-monitor/" target="_blank" rel="ugc noopener">Query Monitor</a>, <a href="https://ayudawp.com/optimizar-consultas-sql/" target="_blank" rel="ugc noopener">WP Crontrol</a></li>
<li><strong>Tienda online</strong>: <a href="https://es.wordpress.org/plugins/easy-actions-scheduler-cleaner-ayudawp/" target="_blank" rel="nofollow noopener">Easy Action Scheduler Cleaner</a></li>
<li><strong>RGPD / Legal</strong>: <a href="https://es.wordpress.org/plugins/eu-withdrawal-compliance/" target="_blank" rel="nofollow noopener">EU Withdrawal Compliance</a>, <a href="https://es.wordpress.org/plugins/terms-conditions-consent-log/" target="_blank" rel="nofollow noopener">Terms &amp; Conditions Consent Log</a>, <a href="https://ayudawp.com/plugin-consentimientos-rgpd-cookies-casi-perfecto/" target="_blank" rel="ugc noopener">un buen plugin de gestión de cookies</a></li>
</ul>
<h3>Prompts de IA útiles en auditorías</h3>
<p>La IA no sustituye las comprobaciones en tiempo real ni las herramientas especializadas, pero <strong>traduce y prioriza a una velocidad que compensa usarla en cada auditoría</strong>.</p>
<p><strong>Para traducir la salud del sitio</strong> (pega el texto del informe que genera WordPress en «Herramientas → Salud del sitio → Información», botón de copiar al portapapeles):</p>
<pre>Este es el informe de Salud del sitio de un WordPress. Explícame en términos simples qué problemas hay, cuáles son graves y en qué orden los resolverías. No asumas que sé de servidores.</pre>
<p><strong>Para las cabeceras de seguridad</strong> (pega la respuesta de <code>curl -I https://laweb.com</code> o las cabeceras que muestra cualquier herramienta externa):</p>
<pre>Estas son las cabeceras HTTP de una web WordPress. Dime qué cabeceras de seguridad faltan, cuáles están mal configuradas y qué riesgo real supone cada ausencia. Ordena por importancia.</pre>
<p><strong>Para el borrador del informe al cliente</strong> (pega tu lista de hallazgos técnicos):</p>
<pre>Estos son los hallazgos técnicos de una auditoría WordPress clasificados en Crítico, Importante y Menor. Redacta un resumen ejecutivo de una página para un cliente sin conocimientos técnicos: qué pasa, qué riesgo tiene y qué propongo hacer, sin tecnicismos y sin dramatismo.</pre>
<p>Para profundizar aún más pasa <strong>Claude Code sobre la carpeta wp-content</strong> con una instrucción inicial que le pida clasificar hallazgos por gravedad te da un primer mapa priorizado del código en minutos. Con la misma limitación de siempre, que conviene no olvidar, y es que <strong>la IA analiza código estático, no ejecución</strong>, así que Query Monitor, los logs y las compras de prueba siguen siendo insustituibles.</p>
<h2>¿Cada cuánto repetir todo esto?</h2>
<p>La auditoría es una foto, y las webs se mueven. La cadencia que a mí me funciona con las webs que mantengo:</p>
<ul>
<li><strong>Completa</strong>: al asumir una web nueva, siempre, y después una vez al año, porque lo que era Menor el año pasado puede haberse convertido en Crítico si el ecosistema avanzó y la web no.</li>
<li><strong>Seguridad</strong>: revisión mensual apoyada en alertas automáticas de vulnerabilidades para los plugins instalados, con Vigilante avisando de cambios en archivos entre revisión y revisión.</li>
<li><strong>Rendimiento</strong>: tras cualquier cambio grande (tema nuevo, migración, campaña con tráfico fuerte) y un vistazo trimestral a los datos de campo.</li>
<li><strong>Con cada versión mayor de WordPress o PHP</strong>: repaso de compatibilidad en staging antes de actualizar producción.</li>
</ul>
<p>Y si todo esto te parece sensato pero no tienes cuándo hacerlo, te viene grande o prefieres derivar responsabilidades, para eso existe <a href="https://mantenimiento.ayudawp.com" target="_blank" rel="ugc noopener">mi servicio de mantenimiento web</a>, donde la auditoría inicial, las revisiones y el informe mensual van de serie, es literalmente lo que hacemos cada día.</p>
<p>Si haces tu primera auditoría con esta guía me encantará saber <strong>cómo te ha ido, qué te has encontrado y qué echas en falta</strong>, y si auditas webs a menudo seguro que tienes revisiones propias que aquí no están, para todo eso, incluso para debatir, me tienes ahí abajo, en la sección de comentarios.</p>
<p>La próxima web que te llegue sin documentación ya no te va a pillar a ciegas, pero sobre todo tendrás una lista de por dónde empezar, por lo menos.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/auditar-web-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Es peligroso eso del unfiltered_html?</title>
		<link>https://ayudawp.com/unfiltered_html/</link>
					<comments>https://ayudawp.com/unfiltered_html/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Mon, 13 Jul 2026 06:28:39 +0000</pubDate>
				<category><![CDATA[Programación + WordPress]]></category>
		<category><![CDATA[Seguridad WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[Multisitio]]></category>
		<category><![CDATA[Vigilante]]></category>
		<category><![CDATA[wp-config.php]]></category>
		<category><![CDATA[XSS]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159874</guid>

					<description><![CDATA[En WordPress cualquier administrador o editor puede meter HTML y JavaScript sin filtrar dentro de una entrada, y eso incluye un script que se ejecuta en el navegador de cada visitante. No es un fallo, es una capacidad que viene de serie, se llama unfiltered_html.]]></description>
										<content:encoded><![CDATA[<p><strong>En WordPress cualquier administrador o editor puede meter HTML y JavaScript sin filtrar</strong> dentro de una entrada, y eso incluye un <code>&lt;script&gt;</code> que se ejecuta en el navegador de cada visitante. No es un fallo, <strong>es una capacidad que viene de serie</strong>, se llama <code>unfiltered_html</code>, y la buena noticia es que, si quieres, porque tiene sus cosas, se corta con una sola línea en el <code>wp-config.php</code>.</p>
<p>Vamos a verlo, porque tiene más miga de la que parece.</p>
<h2>Para empezar ¿qué es eso del unfiltered_html y qué hace?</h2>
<p><strong>WordPress filtra el HTML que guardas en las entradas</strong> con una función llamada <code>wp_kses</code>, que viene a ser el segurata que decide qué tags pasan y cuáles no, y por eso un suscriptor o un colaborador no puede colarte un <code>&lt;script&gt;</code> ni un <code>&lt;iframe&gt;</code> raro. Hasta ahí bien.</p>
<p>El problema es quién se puede saltar esa medida de seguridad. En una instalación normal, de un solo sitio, <strong>los administradores y los editores tienen la capacidad <code>unfiltered_html</code>, que les deja escribir el HTML que les dé la gana, sin filtrar ninguno</strong>. Lo que teclean va directo a la base de datos tal cual, scripts incluidos.</p>
<blockquote><p>Si tienes una red multisitio con WordPress la cosa cambia, porque ahí solo los superadministradores la tienen, ni siquiera los administradores de cada subsitio. Así que este truco va sobre todo para las webs de un solo sitio, que son la mayoría.</p></blockquote>
<p>¿Que esto es teórico? Ni de lejos. Ya conté en su día una <a href="https://ayudawp.com/vulnerabilidad-seguridad-divi-extra/" target="_blank" rel="ugc noopener">vulnerabilidad en Divi, Extra y Divi Builder</a> por la que usuarios de perfil bajo, como un simple autor, podían usar HTML sin filtrar en el contenido cuando editaban con el maquetador, justo lo que se supone que solo pueden hacer los administradores, lo que sería un escalado de privilegios de manual.</p>
<h2>Por qué es un problema de seguridad, y no de confianza</h2>
<p><strong>El riesgo no es que tu editor sea mala gente, es que alguien se haga con su cuenta</strong>. Una contraseña reutilizada que aparece en una filtración, un phishing bien montado o un plugin comprometido que escala permisos, y de repente alguien tiene entre manos una cuenta con <code>unfiltered_html</code>.</p>
<p>Con esa cuenta no necesita romper nada, le basta con editar una entrada, pegar un <code>&lt;script&gt;</code> que robe cookies de sesión o redirija a los visitantes, guardar y a correr. Es <a href="https://ayudawp.com/ataques-xss-wordpress/" target="_blank" rel="ugc noopener">XSS almacenado</a>, del que <strong>se queda en tu base de datos y se ejecuta en el navegador de cada persona que abre esa página, tú incluido</strong> cuando entras al escritorio.</p>
<h2>Mira qué fácil es impedir el unfiltered_html</h2>
<p>La parte buena de todo esto es que el problema, que lo puede ser, se arregla simplemente definiendo una constante en el <code>wp-config.php</code>. Ábrelo por FTP o desde el gestor de archivos de tu hosting y añade esta línea antes de la que dice <code>/* That's all, stop editing! Happy publishing. */</code>:</p>
<pre>define( 'DISALLOW_UNFILTERED_HTML', true );</pre>
<p>Y ya está. A partir de ahí <strong>WordPress le quita la capacidad a todo el mundo, administradores y superadministradores incluidos</strong>, y todo lo que se guarde pasa por el filtro <code>wp_kses</code> como si lo escribiera un colaborador cualquiera. Ya no puedes meter una etiqueta <code>&lt;script&gt;</code>.</p>
<p>Para comprobar que funciona entra como administrador, mete un bloque de HTML personalizado con un <code>&lt;script&gt;alert(1)&lt;/script&gt;</code> dentro, guarda y recarga. Si la constante está bien puesta, el script habrá desaparecido solo.</p>
<h2>¿Se rompe algo si quito el unfiltered_html?</h2>
<p>Esto no es gratis del todo,porque al capar el HTML sin filtrar <strong>WordPress también va a vaciar cosas seguramente normales que metas a mano como código</strong>, como un <code>&lt;iframe&gt;</code> de un mapa pegado en un bloque de HTML personalizado, un incrustado manual, un script de seguimiento que colabas en una entrada concreta, o ciertos atributos que <code>wp_kses</code> no admite por defecto.</p>
<p>Y luego hay otro efecto colateral, y es que <strong>desaparece también la opción de CSS adicional del personalizador</strong>. WordPress usa la capacidad <code>edit_css</code> para ese cuadro donde escribes CSS, y esa capacidad está enganchada por dentro a <code>unfiltered_html</code>, así que al desactivar una te llevas la otra por delante.</p>
<p>Lo mismo pasa con el CSS personalizado del editor de sitio en los temas de bloques. Si metes tus estilos por ahí tenlo claro antes de activar la constante.</p>
<p>Entonces, ¿cuándo la activo?</p>
<ul>
<li><strong>Sí, sin pensarlo</strong>, si tienes varios redactores, editores o autores, o si mantienes webs de clientes donde no controlas quién toca qué. El riesgo de una cuenta comprometida pesa mucho más que la comodidad de pegar un iframe de vez en cuando.</li>
<li><strong>Con cuidado, o mejor no</strong>, si eres el único que edita, metes HTML crudo por el editor a menudo o dependes del CSS adicional del personalizador. En ese caso tienes salidas más finas.</li>
</ul>
<p>Sí, hay otras maneras de protegerte sin hacerlo a la brava, para este segundo caso. Una es que en vez de capárselo a todos con la constante, quites la capacidad solo a los perfiles que no la necesitan, como editores y autores, con un filtro sobre <code>map_meta_cap</code>, y dejársela a los administradores. Solo tendrías que añadir un código como este:</p>
<pre>/* Filtrar el HTML sin filtrar solo a los que no son administradores */
add_filter( 'map_meta_cap', 'ayudawp_limitar_unfiltered_html', 10, 3 );
 
function ayudawp_limitar_unfiltered_html( $caps, $cap, $user_id ) {
 
	// Solo actuamos sobre la capacidad de HTML sin filtrar
	if ( 'unfiltered_html' === $cap ) {
 
		// Leemos los datos del usuario directamente para no provocar
		// una llamada recursiva a este mismo filtro, como pasaría con user_can()
		$user = get_userdata( $user_id );
 
		// Si no es administrador (no tiene manage_options), se la denegamos
		if ( ! $user || empty( $user-&gt;allcaps['manage_options'] ) ) {
			$caps = array( 'do_not_allow' );
		}
	}
 
	return $caps;
}</pre>
<p>Con esto <strong>los administradores siguen metiendo el HTML que quieran y a los editores se les filtra igual que a un colaborador</strong>, sin tocar el <code>wp-config.php</code> ni llevarte por delante el CSS adicional del personalizador. Y si lo que buscas es que tus redactores no puedan ni acercarse al HTML a mano, tienes el otro camino, <a href="https://ayudawp.com/desactivar-editor-codigo-html/" target="_blank" rel="ugc noopener">desactivar el editor de código del editor de bloques</a>. Depende de cómo trabajéis.</p>
<h2>No te relajes que eso no es todo, aun te pueden colar código</h2>
<p>La constante cierra la puerta del editor, que es la más grande, pero no es la única. <strong>Un plugin con una vulnerabilidad de XSS, un comentario mal filtrado o un formulario pueden colar un script por otro lado</strong>, y ahí esta línea no llega.</p>
<p>Para eso está la <strong>cabecera Content-Security-Policy (CSP), que es la que de verdad frena que un script se ejecute aunque haya conseguido meterse en tu base de datos</strong>.</p>
<p>Si tu política solo permite ejecutar JavaScript de tu propio dominio, el <code>&lt;script&gt;</code> del atacante que apunta fuera se queda mirando. Es la defensa con más rentabilidad contra el XSS, como ya expliqué en la <a href="https://ayudawp.com/ataques-xss-wordpress/" target="_blank" rel="ugc noopener">guía de protección contra XSS</a>.</p>
<p>Cabeceras CSP las gestionan muchos plugins de seguridad, pero el más completo en este sentido es <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a>, que incluye incluso un comprobador de cabeceras. La idea es tener las dos capas trabajando juntas, la constante para que el script no entre por el editor y la CSP para que no se ejecute si entra por otro sitio.</p>
<h2>¿En qué quedamos, impido el unfiltered_html o no?</h2>
<p>Si en tu web publica más gente que tú, o llevas webs de clientes, la respuesta corta es sí. añade la línea al <code>wp-config.php</code> y te quitas de encima uno de los vectores de XSS más tontos y más habituales que hay. Pero administras y alimentas la web solo tú y usas el CSS adicional del personalizador o pegas iframes a mano, valora antes la alternativa de capárselo solo a ciertos perfiles.</p>
<p>Tienes más contexto en la <a href="https://ayudawp.com/constantes-de-wordpress/" target="_blank" rel="ugc noopener">lista completa de constantes de WordPress</a> por si quieres seguir apretando tuercas en el <code>wp-config.php</code>, y en la <a href="https://ayudawp.com/ataques-xss-wordpress/" target="_blank" rel="ugc noopener">guía de XSS</a> para montar la parte de la CSP como es debido.</p>
<p>¿Tú la tenías capada o acabas de descubrir que tus editores podían hacer esto? Me lo cuentas ahí abajo, en los comentarios … o no.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/unfiltered_html/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>La IA se come el tráfico de Google y cómo ser visible en las IAs gratis con WordPress</title>
		<link>https://ayudawp.com/la-ia-se-come-el-trafico-de-google-y-como-ser-visible-en-las-ias-gratis-con-wordpress/</link>
					<comments>https://ayudawp.com/la-ia-se-come-el-trafico-de-google-y-como-ser-visible-en-las-ias-gratis-con-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Fri, 10 Jul 2026 06:47:54 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Vídeos]]></category>
		<category><![CDATA[#CrónicasWordPress]]></category>
		<category><![CDATA[#DoctorWordPress]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159907</guid>

					<description><![CDATA[Esta semana ha tocado despedida, así que si andas de vacaciones o liado con el cierre antes de agosto y no pudiste verme en directo, te resumo aquí los dos vídeos para que te pongas al día en un rato. Son los dos últimos directos antes del parón de verano, que en España ya aprieta el calor y no está uno para andar mucho delante de la cámara.]]></description>
										<content:encoded><![CDATA[<p>Esta semana ha tocado despedida, así que si andas de vacaciones o liado con el cierre antes de agosto y no pudiste verme en directo, te resumo aquí los dos vídeos para que te pongas al día en un rato. Son los dos últimos directos antes del parón de verano, que en España ya aprieta el calor y no está uno para andar mucho delante de la cámara.</p>
<p>El lunes tocaron unas <strong>Crónicas WordPress cargadas hasta arriba de noticias</strong>, con la IA comiéndose el tráfico de Google como tema estrella. Y el miércoles vino un <strong>Doctor WordPress dedicado a algo que me preguntáis un montón</strong>, cómo hacer que te vean los buscadores y las IAs sin pagar un duro, tirando de lo que ya trae WordPress de serie. Te cuento.</p>
<h2>Crónicas WordPress: la semana en que la IA se comió el tráfico (y Elementor le echó la culpa)</h2>
<p>Abrí pidiendo disculpas, todo hay que decirlo, porque el miércoles anterior me salté el Doctor WordPress. ¿La razón? Pues el verano, que me fui a dar un baño y cuando quise darme cuenta eran las ocho y media y se me había pasado la hora. Cosas que pasan. Aclarado esto, vamos a la ronda de titulares, que hubo tela.</p>
<h3>Seguridad</h3>
<p>En el frente de siempre, semana movidita:</p>
<ul>
<li>Wordfence cerró la semana con casi 200 vulnerabilidades nuevas, para que te hagas una idea del ritmo al que va esto.</li>
<li>El fallo crítico de UpdraftPlus (<code>CVE-2026-10795</code>) se sigue explotando en 3 millones de webs, y menos mal que los hostings buenos ya están parcheando y avisando.</li>
<li>Y una que me encantó, la de un desarrollador que tumbó un ataque de spam de registro con un filtro hecho con ayuda de Claude y Codex. El spam de registro es de lo más pesado que hay, así que ver a alguien resolverlo con IA y buen criterio me alegró el lunes.</li>
</ul>
<h3>Comunidad</h3>
<p><strong>La bomba de la semana fue Elementor</strong>, que ha echado al 30 % de su plantilla y le echa la culpa a la IA. A ver, la IA será lo que quieras, pero <strong>la decisión de despedir la toman ellos, no ChatGPT</strong>. Echarle la culpa a la máquina queda muy moderno, pero es su decisión y su responsabilidad.</p>
<p>Más cosas de comunidad que comenté:</p>
<ul>
<li>Marina Broca, que sabe un rato de la parte legal y es buena amiga, publicó en el blog de WordPress.com un artículo estupendo sobre el botón de desistimiento para tiendas, esa directiva europea que ya está en vigor. Y mira tú por dónde, ahí recomiendan <a href="https://es.wordpress.org/plugins/eu-withdrawal-compliance/">mi plugin gratuito para cumplir con ello</a>, cosa que me hizo ilusión.</li>
<li>Salió el informe «State of WordPress Agencies 2026», sobre cómo trabajan de verdad las agencias, muy enfocado al mercado anglosajón pero con lecturas interesantes.</li>
<li>Y el informe sobre el estado de los temas, que deja una brecha curiosa, los desarrolladores se han pasado a los bloques y los usuarios ni de lejos.</li>
<li>WPBakery sacó su versión 9.0 en beta, por si todavía tiras de él.</li>
<li>Y hablé de Dismissed, ese muro de la vergüenza de los avisos que los plugins te clavan en el escritorio.</li>
</ul>
<h3>IA, SEO y el tema gordo del tráfico</h3>
<p>Aquí es donde la cosa se pone interesante de verdad. <strong>Un estudio ha desmontado el discurso de Google sobre las AI Overviews</strong>, hablamos de un 39,8 % menos de clics, y encima los que se pierden no eran de peor calidad, como quería vender Google. Te lo resumo en que esas respuestas de IA ya saltan en más del 40 % de las búsquedas, y eso se traduce en una pérdida de tráfico brutal, no solo informacional, también transaccional, gente que compraría y que ya no llega nunca a tu web.</p>
<p>¿Quieres una pista de lo gordo que es esto? Fíjate en la de anuncios de empresas financieras online que ves últimamente. Están compensando con publicidad la caída enorme de tráfico orgánico. Para que luego digan que la IA no le cambia el negocio a nadie.</p>
<p>Otras de IA y buscadores que toqué:</p>
<ul>
<li>El modo Thinking de ChatGPT cita marcas distintas según cómo lo uses, lo que me sirve para repetir una de mis manías, <strong>no pagues por nada que mida tus menciones en las IAs</strong>, porque son de lo más aleatorio, hasta el mismo modelo te recomienda cosas distintas de una vez a otra.</li>
<li>Cloudflare ya te deja bloquear a los bots de IA, aunque ojo con no cerrarle la puerta de paso a Googlebot.</li>
<li>Lo enlacé con la pregunta del millón, ¿bloqueo los crawlers de IA o mido primero su valor? Que tiene más miga de la que parece, y de ahí sale medio Doctor de esta semana.</li>
<li>Y hablé de los nuevos estándares ARD y OKF, y de si de verdad tienes que implementarlos ya en tu WordPress (con calma, que no cunda el pánico).</li>
</ul>
<p>Tienes todos los titulares con sus enlaces en la descripción del vídeo, que los dejo siempre ordenaditos.</p>
<p><strong>Aquí tienes las Crónicas WordPress completas:</strong> <a href="https://www.youtube.com/watch?v=4KHyXCbhOJ4" target="_blank" rel="noopener">Nuevos estándares IA: ARD, OKF, valor de las menciones de IA y bajada tremenda de tráfico desde Google</a>.</p>
<div class="ast-oembed-container " style="height: 100%;"><iframe title="Nuevos estándares IA: ARD, OKF, valor de las menciones de IA y bajada tremenda tráfico desde  Google" width="1600" height="900" src="https://www.youtube.com/embed/4KHyXCbhOJ4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
<h2>Doctor WordPress: SEO, AEO, GEO y cómo ser visible en las IAs gratis con WordPress</h2>
<p>Este fue el último Doctor antes del verano, y lo dediqué a lo que os había prometido, <strong>cómo posicionar hoy, cuando ya no vale solo con salir en Google</strong>. Ahora hay que aparecer también en las IAs, que más que buscadores son respondedores, te sueltan la respuesta y listo. De ahí lo del SEO de siempre más el AEO y el GEO, las siglas de moda para una misma idea, que te encuentren y te citen.</p>
<p>La buena noticia, y el motivo del directo, es que <strong>puedes hacer muchísimo gratis con lo que WordPress ya trae de serie</strong>, sin pagar por un plugin de SEO monstruoso:</p>
<ul>
<li>WordPress genera su propio mapa del sitio en <code>wp-sitemap.xml</code>. Los plugins de SEO no inventan nada nuevo, solo le cambian la ruta, cada uno la suya.</li>
<li>La etiqueta de título sale del propio título del documento, que controlas desde los ajustes generales y desde cada contenido.</li>
<li>Y las metaetiquetas y los datos estructurados también los puedes gestionar sin cargarte la web de código que no necesitas.</li>
</ul>
<p>Para enseñarlo tiré de un plugin mío, <a href="https://es.wordpress.org/plugins/native-aeo-pack/"><strong>Visibility</strong></a> (más info en <a href="https://visibility.quest/es/">visibility.quest</a>), que forma parte de esa familia de plugins gratuitos que voy soltando, como el <a href="https://vigilante.works/es/">Vigilante</a>. ¿Que por qué me meto en el jardín de hacer un plugin de SEO? Pues justo por esto, porque está montado sobre las funciones que <em>ya existen</em> en WordPress (el manejo de robots, los sitemaps, los metadatos, los canonical nativos) en lugar de duplicarlas como hacen otros. <strong>Menos grasa y más músculo</strong>.</p>
<p>Y una perla práctica que engancha con lo de Cloudflare de las Crónicas: <strong>no bloquees a lo loco a todos los bots de IA</strong>. A los de entrenamiento sí les puedes cerrar la puerta, que consumen recursos a lo bestia y no te devuelven nada. Pero a los de asistente y búsqueda ni se te ocurra, porque son justo los que te citan y te enlazan en tiempo real, y esos sí te traen visitas. Saber distinguir unos de otros es media batalla.</p>
<p>El resto del directo fue lo de siempre en el Doctor, vuestras preguntas de WordPress, SEO, IA y de casi cualquier cosa, que para eso está la consulta abierta.</p>
<p><strong>Aquí tienes el Doctor WordPress completo:</strong> <a href="https://www.youtube.com/watch?v=3oI4QiZN7E4" target="_blank" rel="noopener">SEO, AEO, GEO y Visibilidad en IAs gratis en WordPress</a>.</p>
<div class="ast-oembed-container " style="height: 100%;"><iframe title="SEO, AEO, GEO y Visibilidad en IAs gratis en WordPress" width="1600" height="900" src="https://www.youtube.com/embed/3oI4QiZN7E4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
<h2>Nos vemos después del verano</h2>
<p>Con estos dos directos me despido (de vídeos) hasta la vuelta, que toca desconectar unas semanas. Si te quedan ganas de WordPress para el verano, tienes las dos sesiones enteras ahí arriba para verlas con calma, y de paso puedes cacharrear con lo de la visibilidad gratis, que es buen plan para una tarde de estas sin prisa.</p>
<p>Y si te surge cualquier duda o te apetece debatir algo de lo que conté, me tienes en los comentarios. Buen verano, y a la vuelta más.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/la-ia-se-come-el-trafico-de-google-y-como-ser-visible-en-las-ias-gratis-con-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Sirven de algo los archivos por fecha para SEO?</title>
		<link>https://ayudawp.com/archivos-fecha-seo/</link>
					<comments>https://ayudawp.com/archivos-fecha-seo/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 09 Jul 2026 06:28:33 +0000</pubDate>
				<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[EEAT]]></category>
		<category><![CDATA[Principiante]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159736</guid>

					<description><![CDATA[Los archivos por fecha de WordPress son de esas cosas que llevan ahí desde el primer día y que casi nadie mira, hasta que un buen día ves en Google URLs tuyas del tipo tudominio.com/2025/ o tudominio.com/2025/11/ y te preguntas qué pintan ahí.]]></description>
										<content:encoded><![CDATA[<p>Los <strong>archivos por fecha</strong> de WordPress son de esas cosas que llevan ahí desde el primer día y que casi nadie mira, hasta que un buen día ves en Google URLs tuyas del tipo <code>tudominio.com/2025/</code> o <code>tudominio.com/2025/11/</code> y te preguntas qué pintan ahí.</p>
<p>La respuesta corta es que no pintan gran cosa, pero no anticipemos tanto, que si no quieres seguir leyendo ya tenías los resúmenes con IA, aquí hemos venido a aprender ¿o no?</p>
<h2>Qué son y por qué casi siempre sobran</h2>
<p><strong>WordPress crea de forma automática un archivo por cada año y cada mes</strong> en los que has publicado, un listado que agrupa las entradas por su fecha.</p>
<p>El problema es que <strong>la fecha no es un criterio por el que busque nadie</strong>, la gente busca por temas, no por «lo que publicaste en noviembre de 2025».</p>
<p>Así que <strong>esas páginas no le sirven de nada al visitante</strong> y, de paso, <strong>se llevan parte del rastreo que Google podría dedicar a tu contenido</strong> bueno.</p>
<p>A diferencia del <a href="https://ayudawp.com/indexar-archivos-autor/" target="_blank" rel="ugc noopener">archivo de autor</a>, que tiene su miga porque ancla tu autoridad y ahí la decisión no es tan obvia, <strong>los archivos de fechas no aportan ninguna señal que te interese</strong> conservar. Fácil ¿verdad?</p>
<h2>Qué hacer con los archivos por fecha de cara a SEO</h2>
<p>Tienes dos opciones razonables, y las dos sirven:</p>
<ul>
<li><strong>Desindexarlos con <code>noindex</code>, <code>follow</code>:</strong> La página desaparece de Google, pero este sigue los enlaces hacia tus entradas. Es lo mínimo y lo más seguro.</li>
<li><strong>Desactivarlos del todo:</strong> Que la URL de fecha ni exista. La mayoría de plugins permiten desactivarlos con un clic.</li>
</ul>
<p>Y lo que <strong>no debes hacer</strong>, igual que con cualquier archivo, es ni bloquearlos por <code>robots.txt</code> (Google no leería el <code>noindex</code> y podría acabar indexando la URL igual) ni poner su URL canonical apuntando a la portada.</p>
<p>Pero eso ya lo sabías, porque eres un fiel lector y <a href="https://ayudawp.com/newsletter/" target="_blank" rel="noopener">estás suscrito a la newsletter de Ayuda WordPress para no perderte nada ¿a que sí?</a></p>
<h2>Cómo <del>des</del>hacer SEO con los archivos de fecha</h2>
<p>Como siempre, para todos los gustos, con códigos y con plugins.</p>
<h3>Por código</h3>
<p>Si no quieres instalar nada, un <code>mu-plugin</code> en la carpeta <code>/wp-content/mu-plugins/</code> con este contenido deja los archivos por fecha en <code>noindex, follow</code>:</p>
<pre>&lt;?php
/**
 * Plugin Name: Noindex para archivos por fechas
 * Description: Añade noindex, follow a los archivos de fechas.
 * Author: Fernando Tellado
 */

add_filter( 'wp_robots', 'ayudawp_noindex_date_archives' );

function ayudawp_noindex_date_archives( $robots ) {
	if ( is_date() ) {
		$robots['noindex'] = true;
		$robots['follow']  = true;
	}
	return $robots;
}</pre>
<p>Funciona desde WordPress 5.7, que es cuando llegó el filtro <code>wp_robots</code>, que es el que usa el código.</p>
<h3>Por ajustes y plugins</h3>
<ul>
<li><strong>Yoast SEO</strong> los desactiva del todo desde <code>SEO &gt; Apariencia en el buscador &gt; Archivos</code>.</li>
<li><strong>Rank Math</strong> y <strong>All in One SEO</strong> te dejan desindexarlos desde sus ajustes de apariencia en el buscador.</li>
<li><a href="https://visibility.quest/es/" target="_blank" rel="noopener"><strong>Visibility</strong></a> te permite añadir el <code>noindex, follow</code> nativo, lo que hemos visto antes, con una casilla, a un clic, sin tablas en la base de datos ni código.</li>
</ul>
<h2>Lo que yo haría</h2>
<p>Con los archivos por fecha <strong>no hay mucho que debatir, desindéxalos</strong> con <code>noindex</code> <code>follow</code> o desactívalos, da igual el tamaño de tu web.</p>
<p>Donde sí tienes que pararte a pensar es en el archivo de autor, que ahí entra en juego <a href="https://ayudawp.com/tag/eeat/" target="_blank" rel="noopener">tu E-E-A-T</a> y la cosa cambia.</p>
<p>¿Dudas? Te leo en los comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/archivos-fecha-seo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Resource hints, Speculation Rule, bfcache ¿tienen algo que ver? ¿están relacionados? ¿me lo explicas?</title>
		<link>https://ayudawp.com/resource-hints-speculation-rule-bfcache/</link>
					<comments>https://ayudawp.com/resource-hints-speculation-rule-bfcache/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 06:28:35 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[WPO - Optimizar WordPress]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[bfcache]]></category>
		<category><![CDATA[DietPress]]></category>
		<category><![CDATA[dns-prefetch]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[preconnect]]></category>
		<category><![CDATA[prefetch]]></category>
		<category><![CDATA[preload]]></category>
		<category><![CDATA[prerender]]></category>
		<category><![CDATA[Resource Hints]]></category>
		<category><![CDATA[Speculation Rules]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159810</guid>

					<description><![CDATA[Si llevas tiempo leyendo sobre rendimiento en WordPress te has cruzado con palabras como prefetch, prerender o preconnect en sitios distintos, con significados que no siempre coinciden, y la culpa, todo hay que decirlo, también es un poco de este blog, o sea mía.]]></description>
										<content:encoded><![CDATA[<p>Si llevas tiempo leyendo sobre <a href="https://ayudawp.com/categoria/wpo/" target="_blank" rel="noopener">rendimiento en WordPress</a> te has cruzado con palabras como <code>prefetch</code>, <code>prerender</code> o <code>preconnect</code> en sitios distintos, con significados que no siempre coinciden, y la culpa, todo hay que decirlo, también es un poco de este blog, o sea mía.</p>
<p>En <a href="https://ayudawp.com/prefetch-preload-preconnect-prerender-wordpress/" target="_blank" rel="noopener">mi artículo sobre precarga de recursos</a>, <code>prefetch</code> y <code>prerender</code> significan una cosa, luego, en cuando escribí sobre <a href="https://ayudawp.com/carga-especulativa-nativa/" target="_blank" rel="noopener">carga especulativa nativa de WordPress</a>, las mismas dos palabras significan otra completamente distinta y, para seguir enredando, luego está eso de <a href="https://ayudawp.com/pues-no-resulta-que-hay-una-cache-que-se-llama-bfcache-no-funciona-en-mi-wordpress-y-yo-sin-enterarme/" target="_blank" rel="noopener">la <code>bfcache</code></a>, que no precarga nada de nada, va al revés.</p>
<p><strong>Son cuatro técnicas con nombres que se pisan, y cada una vive en su propia capa del navegador, con sus propias reglas</strong>, así que se me ha ocurrido que igual no está de más ponerlas en orden para que dejemos de mezclarlas.</p>
<p>Si lo que buscas es la otra caché, la que guarda resultados ya generados para no repetir trabajo (página, objetos, base de datos, OPcache, CDN), esa la tienes entera en la <a href="https://ayudawp.com/estrategias-cache-wordpress/" target="_blank" rel="ugc noopener">guía de tipos de caché en WordPress</a>.  Hoy toca hablar de <strong>la familia de cachés que adelanta o conserva trabajo del navegador, no del servidor</strong>, que es un asunto distinto aunque también se llame caché en algún sitio.</p>
<h2>Resource hints: precarga recurso a recurso</h2>
<p>Esta es la que lleva más tiempo en el navegador y la que seguramente ya conoces, aunque no la llames así. Son cuatro etiquetas <code>&lt;link&gt;</code> distintas, cada una con un trabajo muy concreto sobre <strong>un recurso suelto</strong>, nunca sobre una página entera.</p>
<ul>
<li><strong><code>dns-prefetch</code></strong>: resuelve el nombre de dominio de un origen externo antes de que haga falta, así cuando llegue el recurso de verdad esa parte ya está hecha.</li>
<li><strong><code>preconnect</code></strong>: hace lo mismo que <code>dns-prefetch</code> y además abre la conexión TCP y negocia el TLS, así que cuando el recurso llega de verdad el navegador no tiene que esperar nada de eso.</li>
<li><strong><code>prefetch</code></strong>: descarga un recurso suelto entero, un documento o un recurso cualquiera, con prioridad baja, para tenerlo ya en caché cuando se necesite.</li>
<li><strong><code>preload</code></strong>: igual que <code>prefetch</code> pero con prioridad alta y de obligado cumplimiento, el navegador no puede ignorarlo. Se usa para lo que sabes seguro que vas a necesitar ya, como la fuente del título o la <a href="https://ayudawp.com/fetchpriority-wordpress/" target="_blank" rel="noopener">imagen del LCP</a>.</li>
</ul>
<p>Los cuatro <strong>se controlan recurso a recurso, dominio a dominio</strong>, decisión que tomas tú o que automatizas con plugins como <a href="https://es.wordpress.org/plugins/wpo-tweaks/" target="_blank" rel="noopener">DietPress</a>, a golpe de clic, sin que escribas una sola línea de código.</p>
<p>WordPress trae de serie el filtro <code>wp_resource_hints</code> desde la versión 4.6 para añadir <code>dns-prefetch</code> y <code>preconnect</code> sin tocar el <code>&lt;head&gt;</code> a mano, aunque mucha gente, este blog incluido en su día, sigue escribiendo el <code>echo</code> directo en <code>wp_head</code> en vez de usarlo.</p>
<p>Si quieres un <strong>tutorial con el código y las herramientas para aplicarlo</strong> en la <a href="https://ayudawp.com/prefetch-preload-preconnect-prerender-wordpress/" target="_blank" rel="ugc noopener">guía de prefetch, preload, preconnect y prerender en WordPress</a>.</p>
<p>Un apunte para no liar (aún más) el tema es lo relativo al atributo <code>fetchpriority</code>, que suena de la misma familia, y a veces se mete en el mismo saco, pero hace algo distinto. No anticipa nada que el navegador no fuese a pedir igualmente, solo le dice con qué prioridad pedirlo, no es un resource hint en sentido estricto, es una instrucción de orden. Si quieres ampliar información puedes ver la <a href="https://ayudawp.com/fetchpriority-wordpress/" target="_blank" rel="ugc noopener">guía de fetchpriority</a>.</p>
<h2>El <code>prerender</code> <em>de siempre</em> ya no hace nada</h2>
<p>De las etiquetas de arriba hay una que solía acompañarlas, <code>&lt;link rel="prerender"&gt;</code>, y que merece su propio apartado porque <strong>hoy no sirve absolutamente para nada</strong>. Chrome la abandonó hace años, sustituida por la tecnología de la siguiente sección, y cualquier navegador actual la ignora sin más.</p>
<p>No pasa nada por tenerlo, simplemente no aporta nada.</p>
<h2>Speculation Rules: <code>prefetch</code> y <code>prerender</code> nativos de WordPress</h2>
<p>Desde WordPress 6.8, trae de serie la <a href="https://ayudawp.com/carga-especulativa-nativa/" target="_blank" rel="ugc noopener">carga especulativa</a>, creada sobre la Speculation Rules API del navegador. Y aquí empieza el lío, porque <strong>esta tecnología también tiene su propio <code>prefetch</code> y su propio <code>prerender</code></strong>, con los mismos nombres que los de la primera sección, pero que no funcionan igual ni a la misma escala.</p>
<p>Un resource hint clásico es como pedir que te dejen ya el cubierto puesto en la mesa. Speculation Rules es como si la cocina empezara a prepararte el plato entero en cuanto te ve mirar el menú, antes de que hayas pedido nada, o sea, <strong>precarga la página completa</strong>, con su HTML, su CSS y su JavaScript, no un recurso suelto.</p>
<p>Se declara en JSON dentro de un <code>&lt;script type="speculationrules"&gt;</code>, es automático, y <strong>WordPress lo activa de serie solo para visitantes que no están conectados y solo si usas enlaces permanentes bonitos</strong>. Hay tres niveles de anticipación, la conservadora espera al clic, la moderada se dispara al pasar el cursor y la ansiosa salta con solo acercarte.</p>
<p>La compatibilidad con navegadores es la otra pieza importante para decidir si te conviene. <strong>Funciona en Chrome, Edge y el resto de navegadores con motor Chromium</strong>, que es la inmensa mayoría del tráfico mundial, Safari la incluye desde la versión 26.2 pero la trae desactivada por defecto, como función experimental, y Firefox de momento no la ha implementado, aunque sí se ha posicionado a favor de la parte de <code>prefetch</code> para más adelante.</p>
<p>Puedes excluir URLs concretas con el filtro <code>plsr_speculation_rules_href_exclude_paths</code>, o apagarla entera con <code>wp_speculation_rules_configuration</code>. Tienes el desarrollo completo, con el código y los pros y contras, en <a href="https://ayudawp.com/carga-especulativa-nativa/" target="_blank" rel="ugc noopener">qué es y cómo funciona la carga especulativa nativa</a> y en <a href="https://ayudawp.com/desactivar-carga-especulativa-wordpress/" target="_blank" rel="ugc noopener">si te conviene desactivarla</a>.</p>
<h2>bfcache: la única caché que no anticipa nada, conserva lo que ya tenías</h2>
<p>Las tres técnicas anteriores miran hacia delante, adivinan qué vas a necesitar y se adelantan. Sin embargo <a href="https://ayudawp.com/pues-no-resulta-que-hay-una-cache-que-se-llama-bfcache-no-funciona-en-mi-wordpress-y-yo-sin-enterarme/" target="_blank" rel="ugc noopener">bfcache (back/forward cache)</a> hace justo lo contrario y mira hacia atrás. Cuando sales de una página el navegador la congela en memoria tal cual estaba, y si pulsas atrás te la devuelve al instante en lugar de pedirla otra vez al servidor.</p>
<p>Es <strong>una optimización nativa de los navegadores desde hace años</strong>, no necesita ningún código tuyo para existir, pero <strong>WordPress la bloquea</strong> por su cuenta para usuarios conectados al enviar la directiva <code>no-store</code> en la cabecera de respuesta. Quitar esa directiva con el filtro <code>wp_headers</code>, o con el plugin Instant Back/Forward, es lo que la reactiva.</p>
<p>No tiene relación de competencia con ninguna de las tres anteriores, todo lo contrario, <strong>se complementan</strong>, porque <code>bfcache</code> acelera las páginas que ya visitaste, Speculation Rules acelera las que aún no has visto.</p>
<h2>Las cuatro juntas y ordenadas, por aclarar</h2>
<table>
<thead>
<tr>
<th>Técnica</th>
<th>Qué anticipa</th>
<th>Automático o manual</th>
<th>Compatibilidad con navegadores</th>
<th>Cómo se controla en WordPress</th>
</tr>
</thead>
<tbody>
<tr>
<td>Resource hints clásicos<br>
(<code>dns-prefetch</code>, <code>preconnect</code>, <code>prefetch</code>, <code>preload</code>)</td>
<td>Un recurso suelto: un dominio, una conexión, un archivo concreto</td>
<td>Manual, recurso a recurso, o automatizado con plugin</td>
<td>Amplio, todos los navegadores modernos</td>
<td>Filtro <code>wp_resource_hints</code>, código directo o plugin</td>
</tr>
<tr>
<td><code>&lt;link rel="prerender"&gt;</code> clásico</td>
<td>Nada, está obsoleto</td>
<td>—</td>
<td>Ninguno, Chrome lo ignora</td>
<td>No lo uses</td>
</tr>
<tr>
<td>Speculation Rules</td>
<td>El documento completo de la siguiente página</td>
<td>Automático desde WordPress 6.8, configurable</td>
<td>Chrome y Edge sí, Safari detrás de una opción experimental, Firefox aún no</td>
<td>Filtro <code>wp_speculation_rules_configuration</code></td>
</tr>
<tr>
<td><code>bfcache</code></td>
<td>Nada, conserva lo que ya estaba cargado</td>
<td>Nativo del navegador, pero WordPress lo bloquea con usuarios conectados</td>
<td>Amplio, todos los navegadores modernos</td>
<td>Filtro <code>wp_headers</code> o plugin</td>
</tr>
</tbody>
</table>
<h2>Qué tienes activado ahora mismo en tu web</h2>
<p>No hace falta que lo adivines, las herramientas de desarrollador de Chrome te lo dicen directamente:</p>
<ul>
<li><strong>Resource hints clásicos</strong>: mira el código fuente de tu web y busca en el <code>&lt;head&gt;</code> etiquetas <code>&lt;link rel="dns-prefetch"&gt;</code>, <code>&lt;link rel="preconnect"&gt;</code> o <code>&lt;link rel="preload"&gt;</code>.</li>
<li><strong>Speculation Rules</strong>: abre DevTools, pestaña <code>Application</code>, apartado <code>Speculative loads</code>, sección <code>Speculations</code>. Pasa el cursor por algún enlace de tu web y mira si aparece algo en la lista.</li>
<li><strong>bfcache</strong>: misma pestaña <code>Application</code>, apartado <code>Background services</code>, sección <code>Back/forward cache</code>, botón <code>Run test</code>. Te dice si la página entraría en bfcache o el motivo exacto por el que no.</li>
</ul>
<p>Si en los tres casos sale en blanco, ya sabes a cuál de los artículos enlazados más arriba acudir para arreglarlo. Por dónde empezar depende de tu web. Si tienes un <strong>blog que actualiza poco</strong>, el bfcache es la ganancia más rápida y casi sin pegas, actívalo primero.</p>
<p>Si llevas una <strong>tienda con WooCommerce</strong>, revisa antes las exclusiones de Speculation Rules en el carrito y en finalizar compra, y prueba bien <code>bfcache</code> con un pedido real antes de darlo por bueno, que ahí sí hay estado que cuidar.</p>
<p>S<span style="font-size: 16px;">i todavía no has tocado nada de esto, abre las DevTools del apartado anterior antes de instalar ningún plugin nuevo, para saber de qué punto partes. </span>Y si después de mirarlo te queda alguna duda sobre cuál de las cuatro te conviene en tu caso, ya sabes dónde encontrarme, en los comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/resource-hints-speculation-rule-bfcache/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Análisis en profundidad del código de un tema WordPress a medida: qué revisar y con qué herramientas</title>
		<link>https://ayudawp.com/analizar-codigo-tema-wordpress/</link>
					<comments>https://ayudawp.com/analizar-codigo-tema-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 07 Jul 2026 06:28:56 +0000</pubDate>
				<category><![CDATA[IA + WordPress]]></category>
		<category><![CDATA[Programación + WordPress]]></category>
		<category><![CDATA[Seguridad WordPress]]></category>
		<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Temas WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Claude]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[wp_debug]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159777</guid>

					<description><![CDATA[Un tema a medida no pasa por el repositorio de WordPress.org. No tiene historial público de vulnerabilidades, ningún escáner lo conoce de antemano y nadie ha revisado su código salvo quien lo escribió, que a veces es la única persona en el mundo que sabe qué hay dentro, y normalmente ya no trabaja en el proyecto.]]></description>
										<content:encoded><![CDATA[<p>Un tema a medida no pasa por el repositorio de WordPress.org. No tiene historial público de vulnerabilidades, ningún escáner lo conoce de antemano y <strong>nadie ha revisado su código salvo quien lo escribió</strong>, que a veces es la única persona en el mundo que sabe qué hay dentro, y normalmente ya no trabaja en el proyecto.</p>
<p>Hay <strong>tres posibles situaciones</strong> en las que se me ocurre que este artículo te va a resultar útil:</p>
<ol>
<li><strong>Has encargado que te desarrollen un tema a medida</strong> y quieres saber si lo que te han entregado es sólido antes de que llegue tráfico real.</li>
<li><strong>Tu equipo asume el mantenimiento de una web que no conoce</strong>, y el tema a medida es ese territorio sin documentar donde se concentran los apaños, los atajos y los retoques de todo el que ha pasado por el proyecto antes que tú.</li>
<li><strong>Te encargan mejorar, actualizar o rediseñar un tema</strong> existente, y antes de escribir una sola línea nueva necesitas saber sobre qué base estás trabajando.</li>
</ol>
<p>En los tres casos la revisión es la misma, <strong>lo que cambia es el momento en que la haces y lo que puedes decidir con los resultados</strong>.</p>
<p>El artículo va en dos velocidades, de manera que si no te manejas con código cada bloque te indica qué puedes detectar con herramientas visuales y qué pedirle a una IA, y por otro lado, si eres el técnico del proyecto, encontrarás el análisis estático, los comandos y el nivel de detalle que completan el trabajo.</p>
<p>Pretende ser <strong>una guía para todo tipo de perfiles</strong>, aunque no te veas del todo en los propuestos, lo importante es que nadie se quede sin información útil, incluso si simplemente quieres leerlo para aprender o pillar ideas.</p>
<h2>Entorno y herramientas</h2>
<p>Antes de revisar una sola línea de código <strong>conviene tener preparado lo que vas a necesitar</strong>. No es mucho, pero todo imprescindible.</p>
<h3>Si no te manejas con código</h3>
<p>Lo primero es <strong>activar el <a href="https://ayudawp.com/que-es-wp_debug-y-como-usarlo/" target="_blank" rel="noopener">modo depuración de WordPress</a></strong>. Abre el archivo <code>wp-config.php</code> de tu instalación de pruebas (nunca en producción) y añade estas tres líneas antes de la que dice <em>«That’s all, stop editing!»</em>:</p>
<pre>define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );</pre>
<p>Con esto WordPress empezará a registrar en un archivo <code>debug.log</code> cualquier función obsoleta, aviso de compatibilidad o error que aparezca al navegar por la web. Para leer ese archivo sin salir del administrador instala <a href="https://wordpress.org/plugins/debug-log-manager/" target="_blank" rel="nofollow noopener">Debug Log Manager</a>. Luego instala también el plugin oficial <a href="https://es.wordpress.org/plugins/health-check/" target="_blank" rel="noopener nofollow">Health Check &amp; Troubleshooting</a>, que entre otras cosas te muestra la versión de PHP activa y el estado general de la instalación.</p>
<p>Con esas dos herramientas y una IA (Claude o cualquier otra) ya puedes revisar la mayor parte de lo que este artículo cubre.</p>
<h3>Si eres el técnico del proyecto</h3>
<p>La combinación que cubre la mayor parte del análisis estático son <a href="https://github.com/squizlabs/PHP_CodeSniffer" target="_blank" rel="nofollow noopener">PHP CodeSniffer</a> con los <a href="https://github.com/WordPress/WordPress-Coding-Standards" target="_blank" rel="nofollow noopener">WordPress Coding Standards</a> y el paquete <a href="https://github.com/PHPCompatibility/PHPCompatibility" target="_blank" rel="nofollow noopener">PHPCompatibility</a>. Con esa combinación puedes <strong>detectar problemas de compatibilidad PHP, funciones obsoletas y violaciones de los estándares</strong> de WordPress sin ejecutar el código, solo analizando los archivos.</p>
<p>Para análisis en tiempo real mientras navegas la instalación, <a href="https://wordpress.org/plugins/query-monitor/" target="_blank" rel="nofollow noopener">Query Monitor</a> es la referencia. Y <a href="https://wp-cli.org/" target="_blank" rel="nofollow noopener">WP-CLI</a> para los comandos que se mencionan a lo largo del artículo.</p>
<p>Si quieres una <strong>auditoría asistida por IA</strong> de toda la carpeta del tema de una vez, <strong>Claude Code</strong> con la instrucción inicial sobre el directorio completo es la forma más rápida de <strong>tener un primer mapa de problemas priorizado</strong>.</p>
<h2>Compatibilidad con PHP</h2>
<p><strong>Un tema con funciones eliminadas en PHP 8.x no da aviso: da error crítico.</strong> Es el tipo de problema que aparece el día que el hosting actualiza la versión de PHP, que es exactamente lo que van a hacer tarde o temprano.</p>
<p>Sin código, <code>WP_DEBUG</code> + Debug Log te avisa de las funciones obsoletas en cuanto navegas por la web con el tema activo. Health Check te muestra la versión de PHP que tienes y si el tema declara una versión mínima compatible.</p>
<p>Con código, PHP CodeSniffer + PHPCompatibility analiza el tema completo sin ejecutarlo, incluyendo archivos que quizás no se llaman en ninguna URL de prueba.</p>
<p>Para el nivel sin código también puedes pegar el contenido de <code>functions.php</code> en una IA con el prompt: <em>«Eres revisor de código PHP. Identifica funciones PHP eliminadas o incompatibles con PHP 8.x en este código de tema WordPress. Para cada caso dime el nombre de función, el número de línea y la alternativa recomendada.»</em></p>
<h3>Crítico</h3>
<ul>
<li>Uso de funciones eliminadas en PHP 8.x: <code>ereg()</code>, <code>ereg_replace()</code>, <code>mysql_*</code>, <code>create_function()</code>, <code>each()</code>, <code>split()</code>. Si aparecen en el código, el tema puede dejar de funcionar en cualquier actualización de PHP.</li>
<li>Operador <code>@</code> usado de forma sistemática para suprimir errores: oculta fallos reales y puede romper el comportamiento en PHP 8 sin aviso ninguno.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Comparaciones con <code>==</code> en contextos donde PHP 8 cambia el comportamiento (cadenas numéricas, comparaciones con <code>null</code>): el código parece funcionar pero produce resultados incorrectos en determinadas condiciones.</li>
<li>Versión PHP mínima declarada en la cabecera del tema muy por debajo de la que el código realmente necesita. Si el tema dice <code>Requires PHP: 5.6</code> pero usa sintaxis de PHP 7.4, la declaración es incorrecta y puede inducir a error al gestor del hosting.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Sintaxis PHP 7.0-7.3 que funciona en 8.x pero no aprovecha las mejoras disponibles: planificable para la próxima iteración, no urgente.</li>
<li>Ausencia de <code>typed properties</code> o tipado de parámetros: no es un error, es una omisión de buenas prácticas.</li>
</ul>
<p>Nota importante para WordPress 7.x: el núcleo sube el mínimo a PHP 7.4. Cualquier tema que declare una versión inferior necesita actualizar esa cabecera y revisar el código si usaba sintaxis más antigua.</p>
<h2>Funciones de WordPress obsoletas</h2>
<p><strong>Una función obsoleta no rompe hoy, pero romperá cuando WordPress decida eliminarla.</strong> Y eso pasa en cada versión mayor. La diferencia entre una función obsoleta y una eliminada es solo tiempo.</p>
<p><code>WP_DEBUG</code> registra los avisos de obsolescencia en el log cada vez que el tema llama a una función que ya no debería usar. Con eso y el log ya tienes la lista. Para el perfil técnico, PHP CodeSniffer con WPCS detecta las funciones obsoletas sin necesidad de ejecutar el tema.</p>
<h3>Crítico</h3>
<ul>
<li>Funciones de WordPress eliminadas del todo (no solo obsoletas): si aparecen en el código, el tema puede dar un error crítico en la próxima actualización del núcleo.</li>
<li>Modificaciones directas de archivos de <code>wp-includes</code> o <code>wp-admin</code> desde el tema: raro en proyectos modernos, pero ocurre en temas muy antiguos que «parchearon» algo del núcleo directamente.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Funciones obsoletas con aviso pero que siguen funcionando: <code>wp_title()</code> (obsoleta desde WP 4.4), <code>get_currentuserinfo()</code>, <code>the_attachment_link()</code>. Funcionan hoy, pero hay que planificar la sustitución.</li>
<li>Código que asume que el directorio <code>wp-content</code> está en su ruta por defecto usando rutas absolutas literales, en lugar de las constantes <code>WP_CONTENT_DIR</code> o <code>WP_CONTENT_URL</code>.</li>
<li>Hooks que fueron renombrados pero los originales siguen como alias: el alias puede desaparecer en una versión mayor sin previo aviso adicional.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Widgets registrados solo con la API clásica sin compatibilidad con el editor de bloques: funcional hoy, pero visible como deuda si el cliente trabaja con Gutenberg.</li>
<li>Template files que no usan <code>get_template_part()</code> donde deberían, con código de plantilla duplicado en varios archivos.</li>
</ul>
<p>Hay una señal que merece párrafo aparte porque no rompe nada hoy pero crea un problema real el día que el cliente quiera cambiar de tema: <strong>funcionalidades de plugin metidas dentro del tema</strong>. CPTs, shortcodes globales, taxonomías personalizadas dentro de <code>functions.php</code>. Si el cliente cambia de tema, desaparece su contenido. Es Importante a corto plazo y Crítico como estado permanente de un proyecto.</p>
<h2>Seguridad del código</h2>
<p>Este bloque tiene solapamiento con el artículo sobre <a href="/temas-wordpress-codigo-malicioso/" target="_blank" rel="ugc noopener">temas WordPress con código malicioso</a>. Lo que cubre aquel artículo es código ofuscado, backdoors y malware. Lo que cubre este bloque son los problemas de seguridad que un desarrollador descuidado introduce sin mala intención: variables sin escapar, SQL sin preparar, ausencia de nonces. Son igual de peligrosos y mucho más frecuentes.</p>
<p>PHP CodeSniffer con WPCS detecta automáticamente la mayor parte de los problemas de escapado y sanitización. Para el nivel sin código, el prompt de IA más útil para este bloque es: <em>«Identifica en este código PHP de un tema WordPress variables impresas sin escapar, datos de usuario sin sanitizar y consultas SQL sin usar <code>$wpdb-&gt;prepare()</code>. Explica cada caso en términos simples.»</em></p>
<h3>Crítico</h3>
<ul>
<li>Variables de <code>$_GET</code>, <code>$_POST</code> o <code>$_REQUEST</code> impresas directamente en el HTML sin sanitizar ni escapar: XSS directo.</li>
<li><code>$wpdb-&gt;query()</code>, <code>$wpdb-&gt;get_results()</code> o cualquier otra función de base de datos con interpolación directa de variables sin <code>$wpdb-&gt;prepare()</code>: inyección SQL activa.</li>
<li>Formularios que procesan datos sin verificar nonce con <code>check_admin_referer()</code> o <code>check_ajax_referer()</code>.</li>
<li>Acciones de administración o procesamiento de datos sin <code>current_user_can()</code>: cualquier usuario puede ejecutar esas acciones.</li>
<li>Uso de <code>eval()</code>, <code>base64_decode()</code> aplicado a variables externas, <code>system()</code> o <code>exec()</code>: señal de alerta máxima. Saltar directamente al artículo de código malicioso para saber qué hacer.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><code>echo get_the_title()</code> sin <code>esc_html()</code>: XSS potencial en contextos concretos, no siempre explotable de forma inmediata, pero hay que corregirlo.</li>
<li>Llamadas a APIs de terceros que envían datos de usuarios sin opción de desactivar y sin mención en la política de privacidad.</li>
<li>Ausencia de sanitización en campos del Customizer que no se imprimen directamente en el front: riesgo no inmediato, pero es deuda documentada.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Fuentes de Google cargadas desde <code>fonts.googleapis.com</code> sin opción de desactivar: problema de cumplimiento del RGPD, no de seguridad activa, pero requiere solución.</li>
<li>Nonces ausentes en formularios de solo lectura que no modifican datos: bajo riesgo real, pero incumple los estándares de WordPress.</li>
</ul>
<h2>Rendimiento</h2>
<p>Los problemas de rendimiento de un tema a medida no siempre aparecen en el desarrollo. Aparecen cuando la web tiene contenido real, con cientos de entradas y miles de visitas. <strong>Un N+1 que pasa desapercibido en desarrollo puede tumbar un servidor con tráfico real.</strong></p>
<p>Query Monitor es la herramienta para ambos perfiles: se instala como plugin, no necesita configuración y muestra en tiempo real las queries que ejecuta cada carga de página, cuánto tarda cada una y de dónde viene. Para el resultado agregado, PageSpeed Insights da la imagen completa del impacto en el usuario.</p>
<h3>Crítico</h3>
<ul>
<li><code>WP_Query</code> o <code>get_posts()</code> dentro de un bucle de posts: el N+1 clásico. Si tienes 50 entradas en un listado y cada una dispara su propia query adicional, son 51 queries donde debería haber 1 o 2.</li>
<li><code>wp_remote_get()</code> o llamadas <code>curl</code> en cada carga de página sin ninguna caché con transients: cada visita hace una petición HTTP a un servicio externo que puede tardar segundos o estar caído.</li>
<li>jQuery propio incluido en la carpeta del tema cargando en paralelo al de WordPress: doble carga y conflictos de versión garantizados.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Scripts y estilos encolados en todas las páginas sin condición cuando solo hacen falta en plantillas concretas: un slider de JavaScript cargando en cada entrada del blog aunque el slider solo esté en la portada.</li>
<li><code>WP_Query</code> sin <code>'no_found_rows' =&gt; true</code> en consultas que no paginarán nunca: WordPress hace un <code>COUNT(*)</code> adicional innecesario. Coste medible con tráfico real.</li>
<li>Opciones guardadas en <code>wp_options</code> con <code>autoload=yes</code> cuando no hacen falta en cada carga de página: se suman al peso de la consulta de opciones que WordPress ejecuta en cada petición.</li>
<li>CSS crítico no inline, haciendo que el navegador espere una hoja de estilos externa antes de renderizar nada visible.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Scripts encolados en el header que podrían ir al pie con el quinto parámetro a <code>true</code> en <code>wp_enqueue_script()</code>.</li>
<li>Imágenes del tema sin <code>loading="lazy"</code> donde procede.</li>
</ul>
<h2>Malas prácticas y estándares heredados</h2>
<p>Este bloque cubre los problemas que no rompen nada hoy pero que hacen el mantenimiento difícil y el comportamiento impredecible. Son los que aparecen cuando hay que cambiar el dominio, migrar el proyecto a un nuevo servidor o simplemente actualizar algo que estaba «atado con alambres».</p>
<h3>Crítico</h3>
<ul>
<li>Funciones sin prefijo o con prefijo genérico: <code>get_menu()</code>, <code>init()</code>, <code>setup()</code>. Si en algún momento se activa un plugin que declara una función con el mismo nombre, el conflicto es un error fatal.</li>
<li>IDs de páginas o entradas hardcodeados en la lógica del tema: <code>if ( $post-&gt;ID === 42 )</code>. Ese ID 42 no existe en el servidor de desarrollo, ni en el staging, ni en el siguiente proyecto que use el mismo tema base.</li>
<li>Slugs de categorías o taxonomías hardcodeados en condicionales: mismo problema exacto que los IDs.</li>
<li>URLs absolutas hardcodeadas al dominio de producción o de desarrollo: si el dominio cambia, el tema queda roto en silencio. Buscar cualquier cadena con <code>https://</code> o <code>http://</code> dentro del código PHP y las plantillas.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Rutas absolutas de servidor hardcodeadas como <code>/var/www/html/wp-content/themes/...</code> en lugar de <code>get_template_directory()</code> o <code>get_stylesheet_directory()</code>.</li>
<li>Colores, dimensiones o configuraciones hardcodeadas en JavaScript que deberían venir de variables CSS o de opciones del Customizer: cuando el cliente quiere cambiar el color corporativo, toca editar código.</li>
<li>Archivos de desarrollo dentro de la carpeta del tema: <code>node_modules</code>, <code>.git</code>, archivos <code>.log</code>, copias <code>.bak</code>, <code>.DS_Store</code>. Ninguno de esos tiene que llegar a producción.</li>
<li><code>die()</code> o <code>exit()</code> donde debería usarse <code>wp_die()</code>: WordPress pierde el control de la ejecución y el usuario recibe un pantallazo en blanco sin contexto.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Cadenas de texto no envueltas en funciones de traducción (<code>__()</code>, <code>_e()</code>): el tema no es internacionalizable, pero no rompe nada. Planificable si el proyecto va a necesitar varios idiomas.</li>
<li><code>functions.php</code> de varios miles de líneas sin estructura de includes ni documentación: no rompe nada, pero hace el mantenimiento muy difícil.</li>
<li>Comentarios en el código en el idioma del desarrollador original cuando no es el del equipo que hereda el proyecto.</li>
<li>Código comentado con funcionalidades a medias o parches rápidos sin explicación.</li>
</ul>
<h2>Dependencias y servidumbres</h2>
<p>Un tema a medida acumula dependencias que no siempre son visibles en el código. Algunas son técnicas, otras son contractuales. <strong>El momento de descubrirlas no es cuando algo deja de funcionar, sino antes de comprometerte a mantener el proyecto.</strong></p>
<h3>Crítico</h3>
<ul>
<li>Plugins bundled (empaquetados) dentro de la carpeta del tema sin los cuales el tema da error crítico: si ese plugin falla, se desactiva o deja de existir en WordPress.org, la web se cae. Los plugins son plugins, van en su carpeta, no dentro del tema.</li>
<li>Código que llama a <code>is_plugin_active()</code> sin manejar el caso de que el plugin no esté activo: en el momento en que alguien desactiva ese plugin por lo que sea, el tema da un error fatal.</li>
<li>Librerías JavaScript o CSS de terceros copiadas dentro del tema con versiones que tienen vulnerabilidades conocidas. Buscar en <a href="https://patchstack.com/" target="_blank" rel="nofollow noopener">Patchstack</a> o <a href="https://wpscan.com/" target="_blank" rel="nofollow noopener">WPScan</a> las versiones incluidas.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Dependencia de un page builder integrado en el tema de forma que desinstalarlo afecta al contenido existente: es una decisión de arquitectura que hay que documentar y comunicar al cliente.</li>
<li>APIs de terceros integradas sin fallback: si la API no responde, ¿la página da error o simplemente no muestra esa sección? Hay que saberlo antes de que le pase al usuario.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Fuentes de Adobe Fonts, Typekit u otros servicios de pago integrados sin documentar la licencia activa ni quién la controla: funciona mientras la licencia esté vigente, pero hay que saber quién paga eso.</li>
<li>Tema hijo de un tema padre comercial (Divi, Avada, Genesis): la dependencia de la licencia del padre hay que documentarla y saber quién la controla.</li>
</ul>
<h2>SEO y estructura semántica</h2>
<p>Aquí es donde más destrozos se acumulan en temas a medida y donde menos gente mira. Un tema puede pasar todos los controles anteriores y seguir siendo un problema grave para el posicionamiento y para los lectores de pantalla. <strong>La estructura semántica incorrecta no da error ninguno, pero Google y los motores de búsqueda la leen y la valoran cada vez que rastrean la página.</strong></p>
<p>Para el propietario sin código, las herramientas más útiles aquí son el inspector del navegador (clic derecho &gt; Ver código fuente para el HTML completo) y la extensión <a href="https://chromewebstore.google.com/detail/headings-map/flbjommegcjonpdmenkdiocclhjacmbi" target="_blank" rel="nofollow noopener">Headings Map</a> para Chrome o Firefox, que visualiza el árbol completo de encabezados de una página de un vistazo. Lighthouse en DevTools detecta imágenes sin alt y otros problemas de accesibilidad. Para el análisis semántico asistido por IA, pegar el código fuente HTML completo de la página con el prompt: <em>«Analiza la estructura de encabezados de este HTML. Dime cuántos H1 hay, si hay saltos de jerarquía y si algún encabezado está en un lugar estructuralmente incorrecto.»</em></p>
<h3>Crítico</h3>
<ul>
<li>Múltiples etiquetas <code>&lt;h1&gt;</code> en la misma página: el logotipo, el nombre del sitio y el título de la entrada con el mismo nivel de importancia. Google espera un solo <code>&lt;h1&gt;</code> por página.</li>
<li><code>&lt;h1&gt;</code> ausente en páginas de contenido o colocado en elementos decorativos sin contenido relevante.</li>
<li>El tema genera su propia etiqueta <code>&lt;title&gt;</code> hardcodeada ignorando WordPress y el plugin SEO activo: el resultado es dos etiquetas <code>&lt;title&gt;</code> en el HTML.</li>
<li>Meta description o canonical generados por el tema en paralelo a los del plugin SEO: conflicto directo entre dos fuentes que dicen cosas distintas.</li>
<li>Etiquetas Open Graph (<code>og:title</code>, <code>og:image</code>, <code>og:description</code>) hardcodeadas en el tema: invalida completamente lo que configuren tanto el cliente como el plugin SEO.</li>
<li>Schema markup emitido por el tema en paralelo al del plugin SEO: datos estructurados duplicados o contradictorios que Google puede ignorar o interpretar mal.</li>
<li>Meta <code>robots</code> hardcodeado en el tema: puede estar bloqueando la indexación de páginas enteras sin que nadie lo sepa.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Saltos de jerarquía de encabezados: pasar de <code>&lt;h1&gt;</code> a <code>&lt;h4&gt;</code> directamente porque visualmente quedaba mejor así.</li>
<li>Encabezados <code>&lt;h2&gt;</code> o <code>&lt;h3&gt;</code> usados en menús de navegación, sidebars o footer por razones de estilo: rompen la jerarquía del contenido de cada página.</li>
<li>Paginación implementada con JavaScript sin etiquetas <code>&lt;a href&gt;</code> reales: Google no puede rastrear el contenido paginado si no hay URLs enlazables.</li>
<li>Botones de acción o elementos de navegación implementados con <code>onclick</code> o <code>&lt;div&gt;</code> sin <code>href</code> real: invisibles para Google y para el teclado.</li>
<li>Imágenes sin atributo <code>alt</code>, incluso las decorativas que deberían llevar <code>alt=""</code>: problema de accesibilidad y de SEO de imágenes.</li>
<li>Links sin texto visible (solo icono sin <code>aria-label</code>): los motores de búsqueda no saben qué enlaza ese elemento.</li>
<li>Microdata (<code>itemscope</code>, <code>itemtype</code>) incompleta o mezclada con JSON-LD del plugin SEO: la fuente única de schema debería ser el plugin SEO, no el tema.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Imágenes con <code>alt</code> que contiene el nombre de archivo literal (<code>IMG_4582.jpg</code>): no aporta nada y el buscador lo sabe.</li>
<li>Elementos semánticos HTML5 (<code>&lt;article&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;footer&gt;</code>) ausentes o usados de forma incorrecta: impacto principalmente en accesibilidad, menor en SEO directo.</li>
<li>Múltiples elementos <code>&lt;nav&gt;</code> sin <code>aria-label</code> que los distinga: los lectores de pantalla no pueden diferenciarlos.</li>
<li>Atributos <code>target="_blank"</code> en links externos sin <code>rel="noopener"</code>.</li>
<li>Texto oculto con <code>display:none</code> o <code>visibility:hidden</code> sobre contenido con palabras clave: puede interpretarse como intento de manipulación aunque no lo sea.</li>
</ul>
<h2>Estructura general del código</h2>
<p>Antes de tocar nada conviene saber exactamente qué tienes entre manos. No para arreglarlo de inmediato, sino para no romper algo que no sabías que existía.</p>
<h3>Crítico</h3>
<ul>
<li>Tema que es en realidad un tema padre comercial modificado directamente (Divi, Avada, Elementor Hello con cambios en los archivos del padre): en la próxima actualización del padre, los cambios desaparecen sin dejar rastro.</li>
<li>Ausencia total de tema hijo cuando se trabaja sobre un tema padre: cualquier actualización borra las personalizaciones sin aviso.</li>
<li>Código del tema que escribe o modifica archivos del servidor en tiempo de ejecución fuera de la carpeta de uploads: señal de alerta que puede ser un mecanismo de persistencia.</li>
</ul>
<h3>Importante</h3>
<ul>
<li><code>functions.php</code> monolítico de varios miles de líneas sin estructura de includes ni organización visible: funciona, pero el mantenimiento es costoso y el riesgo de romper algo al editar es alto.</li>
<li>Mezcla de lógica de tema y lógica de negocio en los mismos archivos: hace difícil separar qué es el tema y qué es personalización específica del proyecto.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Ausencia de changelog o historial de cambios, aunque sea en comentarios: no rompe nada, pero hace imposible saber qué se tocó y cuándo.</li>
<li>Tema hijo con un <code>style.css</code> vacío o con cabecera incorrecta o incompleta: técnicamente funcional, pero señal de que se creó con prisas.</li>
</ul>
<h2>Tiendas online</h2>
<p>Si no hay WooCommerce en la instalación, este bloque no aplica y puedes saltarlo. Si la hay, es igual de importante que cualquiera de los anteriores.</p>
<p><strong>Plantillas de WooCommerce</strong></p>
<p>Cuando un tema a medida copia plantillas de WooCommerce a su propia carpeta <code>woocommerce/</code>, esas plantillas quedan congeladas en la versión de WC que había cuando se programó el tema. Cada actualización de WooCommerce puede cambiar esas plantillas, y si el tema no las actualiza al mismo ritmo, la tienda empieza a comportarse de formas inesperadas y a veces invisibles hasta que el cliente llama.</p>
<p>WooCommerce avisa en <code>WooCommerce &gt; Estado &gt; Herramientas</code> si hay plantillas obsoletas, con la versión de la plantilla original y la que tiene el tema. Si hay plantillas en esa lista, hay trabajo pendiente.</p>
<p><strong>Schema y breadcrumbs de WooCommerce</strong></p>
<p>Si el tema emite su propio schema de producto (JSON-LD o microdata) en las páginas de producto de WooCommerce, entra en conflicto con el que genera el plugin SEO. Uno de los dos debe ganar, y lo razonable es que sea el plugin SEO, no el tema. Revisar el código fuente de una página de producto y buscar bloques <code>&lt;script type="application/ld+json"&gt;</code>: si hay más de uno, hay un problema.</p>
<p>Lo mismo con las migas de pan: si el tema tiene los suyos y los de WooCommerce también están activos, el resultado puede ser dos migas de pan en la misma página o ninguna en las páginas de producto.</p>
<h3>Crítico</h3>
<ul>
<li>Acceso directo a pedidos mediante <code>wp_posts</code> o <code>wp_postmeta</code> con <code>post_type='shop_order'</code>: desde WooCommerce 7.1, HPOS (High Performance Order Storage) mueve los pedidos a tablas propias. Si el tema consulta pedidos de la forma antigua, falla en cualquier instalación con HPOS activo.</li>
<li>Uso de <code>$woocommerce-&gt;cart</code>, <code>$woocommerce-&gt;session</code> u otros accesos directos al global <code>$woocommerce</code>: reemplazados por <code>WC()-&gt;cart</code>, <code>WC()-&gt;session</code> hace años. Funcionan en instalaciones antiguas, rompen en las nuevas.</li>
<li>Funciones de WooCommerce eliminadas en versiones recientes: igual que con las funciones de WordPress, si aparecen en el código el tema puede dar error crítico en la próxima actualización mayor de WC.</li>
<li>Código que llama a funciones de WooCommerce sin comprobar previamente si WC está activo: si WC se desactiva aunque sea temporalmente, el tema da error fatal en lugar de degradar con gracia.</li>
</ul>
<h3>Importante</h3>
<ul>
<li>Plantillas de WooCommerce sobreescritas con versiones muy por detrás de la actual: el riesgo de rotura es proporcional a la diferencia de versiones.</li>
<li>Hooks de WooCommerce obsoletos con alias activos: funcionan, pero el alias puede desaparecer en una actualización mayor. Planificar sustitución.</li>
<li>Assets de WooCommerce desactivados globalmente en el tema cuando solo deberían desactivarse fuera de las páginas de tienda: puede producir carrito roto o checkout sin estilos en algún caso concreto.</li>
</ul>
<h3>Menor</h3>
<ul>
<li>Plantillas sobreescritas con una o dos versiones de diferencia y sin cambios funcionales conocidos en esas versiones: bajo riesgo inmediato, pero hay que revisarlas en la próxima actualización de WC.</li>
</ul>
<h2>Por dónde empezar</h2>
<p>Los tres niveles del artículo trasladan directamente a la priorización del trabajo:</p>
<h3>Crítico: corregir antes de entregar, publicar o tocar nada más</h3>
<p>No hay entrega válida con críticos abiertos. Si el encargo es asumir el mantenimiento de un proyecto heredado, los críticos se resuelven antes de cualquier otra tarea.</p>
<ul>
<li>Vulnerabilidades de seguridad activas: SQL sin preparar, variables sin escapar impresas, ausencia de nonces en formularios que modifican datos.</li>
<li>Incompatibilidades PHP que pueden dar error crítico con la próxima actualización del servidor.</li>
<li>Funciones de WordPress o WooCommerce eliminadas del todo.</li>
<li>Conflictos SEO activos: doble etiqueta <code>&lt;title&gt;</code>, metas duplicadas, meta robots hardcodeado.</li>
<li>N+1 queries en producción con tráfico real.</li>
<li>Tema padre comercial modificado directamente sin tema hijo.</li>
</ul>
<h3>Importante: planificar en la próxima actuación</h3>
<p>Antes de la siguiente actualización mayor de WordPress o PHP.</p>
<ul>
<li>Funciones WP o PHP obsoletas con sustitución conocida.</li>
<li>Scripts y estilos sin condición que cargan en todas las páginas.</li>
<li>IDs, slugs y URLs hardcodeados en la lógica del tema.</li>
<li>APIs de terceros sin fallback documentado.</li>
<li>Plantillas WooCommerce con varias versiones de diferencia.</li>
<li>Saltos de jerarquía de encabezados y paginación sin links reales.</li>
</ul>
<h3>Menor: documentar y corregir</h3>
<p>Cuando se pase por ese código por otra razón.</p>
<ul>
<li>Estilo de código y cumplimiento de estándares de WordPress.</li>
<li>Cadenas sin traducir, comentarios en el idioma incorrecto, archivos sobrantes.</li>
<li>Scripts que podrían ir al pie, imágenes sin lazy load.</li>
<li>Alt de imagen con nombre de archivo, elementos semánticos HTML5 ausentes.</li>
</ul>
<p>Una vez el tema está limpio y en producción, <strong>el escáner de cambios de archivos de <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a> avisa si alguien modifica un archivo del tema sin que lo sepas</strong>, que es exactamente lo que ocurre cuando un ataque planta un backdoor en un archivo que ya existía. No te libra de hacer la auditoría, pero cierra la puerta después de haberla hecho.</p>
<h2>Compatibilidad futura</h2>
<p>La auditoría que acabas de hacer es una foto del tema en este momento. Un tema bien hecho hoy puede dejar de funcionar en seis meses si nadie vigila lo que viene. Este bloque no es sobre arreglar nada: es sobre no tener que volver a arreglar las mismas cosas en la siguiente revisión porque nadie las anticipó.</p>
<h3>PHP</h3>
<p>El patrón de PHP es siempre el mismo: lo que hoy es un aviso de obsolescencia, en la siguiente versión mayor desaparece sin más. <strong>La lista de lo que PHP 9 va a eliminar ya existe hoy, en forma de avisos de obsolescencia en PHP 8.x.</strong> Eso significa que si el tema genera avisos de obsolescencia con PHP 8.5 o con la 8.6 que llega a finales de 2026, esos avisos son exactamente lo que va a romper cuando llegue PHP 9.</p>
<p>PHP 9 no tiene fecha oficial todavía, pero eso no cambia la lógica: las obsolescencias actuales son las eliminaciones futuras. PHPCompatibility te permite pasar como parámetro una versión objetivo futura para que analice el código contra lo que sabe que vendrá. Si aún no tienes configurado PHP CodeSniffer con PHPCompatibility, este es el argumento más práctico para hacerlo.</p>
<p>Para seguir el roadmap de PHP sin tener que buscar manualmente, <a href="https://php.watch/versions" target="_blank" rel="nofollow noopener">PHP.Watch</a> mantiene una lista actualizada de todas las versiones en desarrollo, con las obsolescencias y eliminaciones previstas para cada una. Suscribirse a su feed RSS o newsletter es el método más directo de no perderse nada relevante antes de que llegue al servidor.</p>
<p>Lo que hay que comprobar con PHPCompatibility al auditar un tema a medida no es solo la versión de PHP actual del servidor, sino también las siguientes:</p>
<ul>
<li>PHP 8.5 (estable desde noviembre de 2025): la versión que muchos hostings tienen como recomendada para 2026.</li>
<li>PHP 8.6 (prevista para finales de 2026): ya tiene calendario oficial y los primeros RFCs de obsolescencias aprobados.</li>
<li>PHP 9.x (sin fecha oficial): usar PHPCompatibility en modo <code>--runtime-version=9.0</code> avisa de lo que ya está marcado como candidato a eliminación en los milestones públicos de <code>php-src</code>.</li>
</ul>
<h3>WordPress</h3>
<p>WordPress avisa con antelación de todo lo que deja obsoleto y de todo lo que planea eliminar. El problema es saber dónde mirarlo. Estos son los canales que importan si mantienes un tema a medida:</p>
<ul>
<li><strong><a href="https://make.wordpress.org/core/" target="_blank" rel="nofollow noopener">Make WordPress Core</a>:</strong> el blog de desarrollo del núcleo. Aquí se publican las agendas de los dev chats semanales, los field guides de cada versión y las propuestas de cambios que afectarán a temas y plugins. Si solo sigues un canal, que sea este.</li>
<li><strong><a href="https://developer.wordpress.org/news/" target="_blank" rel="nofollow noopener">WordPress Developer Blog</a>:</strong> el canal oficial para desarrolladores de plugins y temas. Las dev notes de cada versión se publican aquí con el detalle de qué cambia, qué queda obsoleto y qué hay que actualizar antes de la siguiente mayor.</li>
<li><strong><a href="https://make.wordpress.org/security/" target="_blank" rel="nofollow noopener">Make WordPress Security</a>:</strong> el blog del equipo de seguridad. Publica las notas de los problemas resueltos en cada versión puntual y las iniciativas de seguridad del ecosistema.</li>
</ul>
<p>Ambos blogs tienen feed RSS. Añadirlos al lector de feeds del equipo es suficiente. No hace falta revisar Make Core a diario: las entradas importantes son fáciles de identificar por las etiquetas <em>dev-notes</em> y <em>field-guide</em>.</p>
<p>Para el perfil técnico, el comando <code>wp core check-update</code> de WP-CLI comprueba si hay actualizaciones pendientes del núcleo. Y revisar periódicamente con PHP CodeSniffer + WPCS las funciones del tema contra la versión de WPCS actualizada detecta lo que el equipo de WordPress Core ya ha marcado como <code>deprecated</code> en el estándar, aunque el tema aún funcione hoy sin avisos visibles.</p>
<h3>Seguridad</h3>
<p>Un tema a medida no está en ninguna base de datos de vulnerabilidades públicas, así que las alertas que importan aquí son las de las librerías de terceros que incluya y las del ecosistema general de WordPress. <strong>El 91% de las vulnerabilidades reportadas en WordPress en 2025 estaban en plugins y temas de terceros, no en el núcleo.</strong></p>
<p>Si el tema incluye librerías JavaScript o PHP copiadas en su carpeta, esas librerías sí pueden aparecer en las bases de datos.</p>
<p>Las fuentes que conviene tener activas:</p>
<ul>
<li><strong><a href="https://patchstack.com/database" target="_blank" rel="nofollow noopener">Patchstack Database</a>:</strong> base de datos gratuita de vulnerabilidades en plugins, temas y el núcleo de WordPress. El plan gratuito incluye alertas por email con hasta 48 horas de antelación sobre nuevas vulnerabilidades reportadas. Útil tanto para los plugins de la instalación como para identificar si alguna librería incluida en el tema tiene CVE conocido.</li>
<li><strong><a href="https://wpscan.com/" target="_blank" rel="nofollow noopener">WPScan Vulnerability Database</a>:</strong> base de datos pública con vulnerabilidades de WordPress clasificadas por severidad. Tiene API gratuita para consultas automatizadas y se puede integrar en pipelines de CI/CD.</li>
<li><strong><a href="https://wordpress.org/news/category/security/" target="_blank" rel="nofollow noopener">WordPress.org Security</a>:</strong> las notas oficiales de cada versión de seguridad del núcleo. Feed RSS disponible. Las versiones menores de WordPress (las que tienen tres números, como x.x.1) suelen ser parches de seguridad, y el equipo de WordPress las publica con descripción de lo que corrigen.</li>
<li><strong>Wordfence Intelligence:</strong> el blog de inteligencia de amenazas de Wordfence publica análisis de vulnerabilidades activas, con descripción técnica y estado de explotación. Especialmente útil cuando una vulnerabilidad está siendo explotada masivamente y el tema puede incluir el componente afectado.</li>
</ul>
<h3>WooCommerce</h3>
<p>WooCommerce sigue un ciclo de lanzamientos propio, independiente del de WordPress, con versiones mayores que introducen cambios de API y obsolescencia propias. Para mantenerse al día conviene seguir el <a href="https://developer.woocommerce.com/" target="_blank" rel="nofollow noopener">WooCommerce Developer Blog</a> y revisar el changelog de cada versión mayor antes de actualizar en producción. Las plantillas sobreescritas que ya revisaste en el bloque anterior son exactamente el tipo de deuda que se acumula cuando el mantenedor no sigue ese ritmo.</p>
<h3>Periodicidad mínima de revisión</h3>
<p>Todo lo anterior tiene sentido si se convierte en un hábito, no en una tarea puntual. Esta es la cadencia mínima razonable para un tema a medida en producción:</p>
<ul>
<li><strong>Mensual:</strong> revisar las alertas de Patchstack o WPScan para los componentes que incluye el tema. Aplicar las actualizaciones de seguridad pendientes del núcleo y los plugins.</li>
<li><strong>Con cada versión mayor de WordPress:</strong> ejecutar PHP CodeSniffer + WPCS actualizado sobre el tema para detectar lo que la nueva versión ha dejado obsoleto. Revisar las dev notes del Developer Blog antes de actualizar en producción.</li>
<li><strong>Con cada versión mayor de PHP disponible en el hosting:</strong> ejecutar PHPCompatibility contra esa versión en staging antes de cambiarla en producción.</li>
<li><strong>Anual:</strong> repetir la auditoría completa de este artículo. Lo que era Menor el año pasado puede haberse convertido en Crítico si el ecosistema ha avanzado y el tema no.</li>
</ul>
<h2>La IA como herramienta de auditoría: los prompts que más uso</h2>
<p>Estos son los prompts prácticos para las revisiones más habituales. No sustituyen al análisis en tiempo de ejecución (Query Monitor, el log de errores) pero cubren gran parte del análisis estático sin instalar nada.</p>
<p><strong>Para el propietario sin código (pegar el contenido de <code>functions.php</code>):</strong></p>
<pre>Lee este archivo functions.php y dime en términos simples si hay algo peligroso, algo obsoleto y algo que podría dar problemas de rendimiento. No asumas que sé programar.</pre>
<p><strong>Para el análisis SEO (pegar el código fuente HTML completo de la página):</strong></p>
<pre>Analiza la estructura de encabezados de este HTML. Dime cuántos H1 hay, si hay saltos de jerarquía y si algún encabezado está en un lugar estructuralmente incorrecto. Busca también si hay más de una etiqueta title o más de una meta description.</pre>
<p><strong>Para el técnico (Claude Code sobre la carpeta completa del tema):</strong></p>
<pre>Audita este tema WordPress a medida. Busca: 1) vulnerabilidades de seguridad (XSS, SQL injection, ausencia de nonces y de comprobaciones de capacidades); 2) funciones PHP eliminadas o incompatibles con PHP 8.x; 3) funciones WordPress obsoletas; 4) N+1 queries; 5) scripts encolados sin condición en todas las páginas. Clasifica los hallazgos en Crítico, Importante y Menor, y dame el archivo y la línea de cada uno.</pre>
<p>Una limitación que hay que tener clara es que <strong>la IA detecta problemas en el código estático, no en la ejecución</strong>, no rastrea el comportamiento en tiempo real, no ejecuta el tema ni simula una carga real. Es complementaria a Query Monitor y al log de errores, no los reemplaza.</p>
<h2>Un regalo para terminar</h2>
<p>Y ya que has llegado hasta aquí, <strong>para no tener que documentar la auditoría en un Excel improvisado ni en un bloc de notas</strong>, hay <strong>una herramienta gratuita, la <a href="https://herramientas.ayudawp.com/theme-audit/" target="_blank" rel="noopener">auditoría de temas WordPress</a></strong>, que he creado exactamente para esto.</p>
<p>La abres al lado de lo que estés revisando, vas añadiendo hallazgos con el bloque, la descripción, la gravedad y la acción propuesta, y cuando terminas un botón genera el informe completo listo para exportar, descargar en PDf, imprimir o enviar al cliente. Sin cuenta, sin IA, sin conexión necesaria, todo en tu navegador.</p>

<a href="https://ayudawp.com/analizar-codigo-tema-wordpress/auditar-tema-online/" rel="nofollow"><img width="1200" height="1558" src="https://ayudawp.com/wp-content/uploads/2026/07/auditar-tema-online.jpg" class="attachment-medium size-medium" alt="" decoding="async" fetchpriority="high"></a>
<a href="https://ayudawp.com/analizar-codigo-tema-wordpress/informe-auditoria-tema-wordpress/" rel="nofollow"><img width="1200" height="1664" src="https://ayudawp.com/wp-content/uploads/2026/07/informe-auditoria-tema-WordPress.jpg" class="attachment-medium size-medium" alt="" loading="lazy" decoding="async" fetchpriority="low"></a>

<p>Si tienes dudas sobre lo que encuentres, o quieres apoyo en el mantenimiento continuo de la web una vez resuelta la auditoría, en <a href="https://mantenimiento.ayudawp.com" target="_blank" rel="ugc noopener">mi servicio de mantenimiento web</a> tienes la opción de delegar eso. Y para cualquier cosa que no quede clara me tienes en los comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/analizar-codigo-tema-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>De repente las búsquedas de mi web dan resultados raros en Google, en japonés y cosas de vender relojes o viagra ¿me han hackeado?</title>
		<link>https://ayudawp.com/spam-seo-injection/</link>
					<comments>https://ayudawp.com/spam-seo-injection/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Mon, 06 Jul 2026 06:30:03 +0000</pubDate>
				<category><![CDATA[Seguridad WordPress]]></category>
		<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[pharma hack]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[Vigilante]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159771</guid>

					<description><![CDATA[Si buscas tu dominio en Google y aparecen páginas con caracteres japoneses o títulos que venden Viagra, tienes un problema. Y si no aparece nada raro, ojo, porque los ataques más sofisticados son exactamente esos: los que no ves desde el escritorio de WordPress, pero que Google lleva meses rastreando mientras tú no ves nada fuera de lo normal.]]></description>
										<content:encoded><![CDATA[<p>Si <strong>buscas tu dominio en Google y aparecen páginas con caracteres japoneses o títulos que venden Viagra, tienes un problema</strong>. Y si no aparece nada raro, ojo, porque los ataques más sofisticados son exactamente esos: los que no ves desde el escritorio de WordPress, pero que Google lleva meses rastreando mientras tú no ves nada fuera de lo normal.</p>
<p>A eso se le llama <strong>spam SEO inyectado</strong>, y no persigue tumbar tu web ni robarte datos, <strong>lo que busca es aprovechar la autoridad que llevas años construyendo para posicionar webs basura</strong> de farmacias ilegales, tiendas de imitaciones de lujo o casinos online. Usan tu dominio como trampolín, y mientras ellos cobrando las comisiones de afiliados.</p>
<p>El informe State of WordPress Security de Patchstack recoge datos de Sucuri que cifran en más de <strong>422.000 los incidentes de spam SEO detectados en 2024</strong>, con el spam japonés como la variante más extendida, responsable del 27,77% de todos los casos. No es un problema marginal ni de lejos.</p>
<p>Vamos a ver <strong>qué formas tiene este ataque de inyección de spam, cómo detectarlo y cómo cerrarlo</strong>, desde lo más básico hasta lo más potente.</p>
<h2>Tres tipos de spam SEO, tres niveles de problema</h2>
<p><a href="https://ayudawp.com/?attachment_id=159790" rel="nofollow"><img decoding="async" class="sombra alignnone wp-image-159790" src="https://ayudawp.com/wp-content/uploads/2026/07/spam-comentarios-WordPress.jpg" alt="" width="1200" height="664"></a></p>
<p>No todos los ataques de spam SEO son iguales ni entran por el mismo sitio ni se detectan igual. Conviene distinguirlos antes de ponerse a tapar agujeros a ciegas.</p>
<h3>El más visible: spam en los comentarios</h3>
<p>El atacante (o casi siempre un bot automatizado) publica <strong>comentarios que incluyen enlaces a las webs que quieren posicionar</strong>. Google rastrea esos enlaces cuando visita tu web y les transfiere autoridad, el resultado es que tu web contribuye al SEO de una farmacia sin receta, una tienda de relojes falsificados o cualquier <strong>otra web de mierda</strong>.</p>
<p>Es el nivel básico, es feo, molesto y contraproducente para tu propio perfil de enlazado, pero por otro lado <strong>es fácil de detectar</strong> porque lo ves tú mismo en la sección de comentarios.</p>
<h3>El nivel medio: inyección de enlaces en la base de datos</h3>
<p>Aquí ya <strong>el atacante ha conseguido entrar en tu instalación</strong>, pues en lugar de dejar un comentario, <strong>inyecta enlaces directamente en el contenido de tus entradas o páginas, en campos de la base de datos</strong> como <code>wp_options</code> o <code>wp_postmeta</code>, o en el código del tema. Los enlaces pueden ir con CSS que los oculta visualmente a los visitantes humanos, pero que los rastreadores de los buscadores leen perfectamente.</p>
<p>No lo ves navegando tu web, pero <strong>lo puedes ver revisando el código fuente de la página o auditando la base de datos</strong>.</p>
<h3>El más peligroso: el pharma hack y el spam japonés con cloaking</h3>
<p>Este es el nivel que da más guerra, nunca mejor dicho, pues <strong>el atacante instala en tus archivos o en la base de datos un código que comprueba <em>quién</em> está visitando la página antes de decidir qué contenido servir</strong>.</p>
<p>Si detecta que es un rastreador de Google, Bing o Yandex, sirve páginas llenas de palabras clave farmacéuticas o texto en japonés, si detecta a un visitante humano normal, muestra tu contenido de siempre. Podríamos decir que <strong>es hackeo <em>inteligente</em></strong>.</p>
<p>El resultado es que tú entras a tu web y ves todo perfecto, pero ve un catálogo de medicamentos sin receta con miles de páginas generadas automáticamente.</p>
<p>Esta técnica se llama <strong><em>cloaking</em></strong> (camuflaje), y es deliberada porque <strong>los atacantes no quieren que lo descubras</strong>. Cuanto más tiempo lleve activo, más autoridad de tu dominio han aprovechado, y cuanto más tarde en detectarse, más difícil es la recuperación del SEO después.</p>
<h4>El truco que hace invisible la infección</h4>
<p>Para entender por qué no lo ves desde el escritorio de WordPress hay que entender cómo funciona el cloaking.</p>
<p>El código malicioso, que puede vivir en tu <code>.htaccess</code>, en tu <code>wp-config.php</code>, en el <code>functions.php</code> del tema o en archivos de plugins, lee la cabecera <code>User-Agent</code> de cada petición que llega al servidor. Esa cabecera identifica quién hace la petición: si es Chrome, Firefox, Safari o un bot de Google.</p>
<p>Si el <code>User-Agent</code> es <code>Googlebot</code>, <code>Bingbot</code>, <code>baiduspider</code> o cualquier rastreador conocido, el código conecta con el servidor del atacante, descarga el contenido de spam del momento y lo sirve. Si eres tú entrando desde el navegador, con tu sesión de WordPress activa o simplemente con un <code>User-Agent</code> de navegador normal, ves tu web tal cual.</p>
<p>Este mecanismo explica por qué <strong>muchos propietarios de WordPress llevan meses o incluso años con la infección activa sin saber nada</strong>. Y explica también por qué la primera señal de alarma suele venir de fuera, como de un <strong>aviso de Google Search Console</strong>, un cliente que lo vio en Google, o <strong>una caída inexplicable del tráfico orgánico</strong>.</p>
<p>El código malicioso se esconde habitualmente en estos sitios:</p>
<ul>
<li>Las primeras o últimas líneas del <code>wp-config.php</code>, camuflado como comentario o como código de configuración aparentemente legítimo.</li>
<li>El archivo <code>.htaccess</code>, con reglas de redirección condicionales.</li>
<li>El <code>functions.php</code> del tema activo, aprovechando que se ejecuta en cada carga.</li>
<li>La carpeta <code>mu-plugins/</code> (de <em>must-use plugins</em>), que se ejecuta automáticamente en cada carga de página y no aparece en la lista de plugins del escritorio, lo que la convierte en el escondite preferido para la persistencia después del hackeo.</li>
<li>La carpeta <code>uploads/</code>, donde a veces aparecen archivos <code>.php</code> disfrazados de imágenes.</li>
<li>Opciones de la base de datos en <code>wp_options</code>, codificadas en base64 para dificultar la detección.</li>
</ul>
<p>Y sobre <strong>la cadena de suministro como vector de entrada</strong>, si no leíste el artículo de <a href="https://ayudawp.com/ataques-cadena-suministro-plugins/" target="_blank" rel="ugc noopener">los ataques a la cadena de suministro en WordPress</a> que publiqué hace unas semanas, te lo resumo en que el caso Essential Plugin fue exactamente esto, <strong>una puerta trasera que servía spam SEO camuflado solo a los rastreadores, invisible para los propietarios</strong>. El ataque más sofisticado posible a través del canal oficial de actualización de plugins.</p>
<h2>Cómo saber si te han inyectado spam SEO antes de enterarte por Google</h2>
<p><a href="https://ayudawp.com/?attachment_id=159792" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-159792" src="https://ayudawp.com/wp-content/uploads/2026/07/example-japanese-seo-spam.png" alt="" width="1200" height="777"></a></p>
<p>No esperes al aviso de Search Console. Para cuando Google te manda la alerta, la infección lleva semanas o meses activa y el daño al SEO ya está hecho, es mucho mejor buscarlo activamente ¿a que sí?.</p>
<h3>La búsqueda más directa</h3>
<p>Ve a Google y escribe <code>site:tudominio.com</code>, revisa los resultados que aparecen, y si ves páginas con caracteres japoneses, títulos sobre medicamentos, casinos o productos que no tienen nada que ver con tu contenido real, <strong>date por inyectado</strong>.</p>
<p>También puedes añadir términos sospechosos: <code>site:tudominio.com viagra</code>, <code>site:tudominio.com casino</code>. Si aparece algo ya tienes la confirmación.</p>
<h3>Google Search Console</h3>
<p>En la sección de seguridad y acciones manuales aparecerán los avisos si Google ya ha detectado el problema. Pero no esperes solo a eso, en el inspector de URLs puedes comparar cómo procesa Google una URL concreta de tu web frente a cómo la ves tú. <strong>Si el contenido que ve Google no coincide con el que ves tú, ¡te han cloakeado!</strong></p>
<p><strong>Ojo también con los usuarios que tienen acceso a tu Search Console</strong>. Una técnica habitual es añadir un usuario del atacante como propietario o delegado para poder <strong>manipular el sitemap e indexar las páginas de spam</strong>. Revísalo en <code>Ajustes → Usuarios y permisos</code>.</p>
<h3>Herramientas de escáner externo</h3>
<p>El escáner gratuito <a href="https://sitecheck.sucuri.net" target="_blank" rel="nofollow noopener">Sucuri SiteCheck</a> analiza tu web desde fuera, como lo haría un motor de búsqueda, y detecta código malicioso, listas negras y redirecciones sospechosas. No necesitas instalar nada.</p>
<p>También <a href="https://wpscan.com/plugins/" target="_blank" rel="nofollow noopener">la base de datos de WPScan</a> te permite comprobar si alguno de tus plugins tiene vulnerabilidades conocidas activas.</p>
<h3>Lo que puedes ver desde el escritorio de WordPress</h3>
<p>Ve a <code>Usuarios → Todos los usuarios</code> y filtra por el perfil de administrador. ¿Los reconoces todos? Una práctica habitual tras un hackeo es crear usuarios administradores falsos para mantener el acceso aunque limpies los archivos. <strong>Borra sin piedad cualquier usuario que no reconozcas</strong>.</p>
<h3>WP-CLI si tienes acceso por SSH</h3>
<p>Si tienes acceso al servidor, estos tres comandos te dan una imagen rápida del estado:</p>
<pre>wp core verify-checksums
wp plugin verify-checksums --all
wp user list --role=administrator --format=table</pre>
<p>El primero compara los archivos del núcleo de WordPress con los oficiales y te dice si alguno ha sido modificado, el segundo hace lo mismo con los plugins que tienen <code>checksums</code> en WordPress.org (esto mismo <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="noopener">puedes hacerlo con Vigilante</a>), y el último lista todos los administradores para que compruebes quién está ahí.</p>
<p><strong>Para buscar código sospechoso en PHP lanza esto</strong> en la raíz de tu instalación:</p>
<pre>grep -ri "base64_decode\|eval(" wp-content/ --include="*.php" -l
find wp-content/uploads -name "*.php" -ls</pre>
<p>El primer comando busca los patrones de ofuscación más comunes, el segundo lista todos los archivos PHP que hay en <code>uploads/</code>, donde no debería haber ninguno.</p>
<h2>De lo más básico a lo más serio: así cierras la puerta</h2>
<p>Ninguna medida por sí sola es suficiente. <strong>La defensa funciona por capas</strong>, y cada capa tapa los agujeros que la anterior deja sin cubrir.</p>
<h3>Capa básica: comentarios y acceso público</h3>
<p>La primera y más sencilla. No protege contra el <code>pharma hack</code> ni el spam japonés, pero sí contra el spam de comentarios y contra que atacantes anónimos inyecten contenido.</p>
<ul>
<li><strong>Cierra los comentarios en entradas antiguas:</strong> En <strong><code>Ajustes → Comentarios</code></strong>, activa «Cerrar automáticamente los comentarios de entradas con más de X días de antigüedad». Los bots de spam atacan preferentemente entradas viejas porque suelen tener menos supervisión.</li>
<li><strong>Modera todos los comentarios antes de publicarlos:</strong> En el mismo panel, activa «<strong>El comentario debe aprobarse manualmente</strong>». Ningún enlace de spam se publica sin que tú lo veas primero.</li>
<li><strong>Instala un filtro de spam:</strong> Akismet sigue siendo la referencia, aunque requiere clave de API. Alternatives gratuitas como Antispam Bee o CleanTalk funcionan bien en la mayoría de casos.</li>
<li><strong>Desactiva los pingbacks:</strong> En <strong>Ajustes → Comentarios</strong>, desmarca «Permitir avisos de enlace de otros blogs». Los pingbacks tienen un uso muy limitado en 2026 y son un vector de abuso.</li>
<li><strong>Desactiva el registro de usuarios si no es imprescindible:</strong> En <strong><code>Ajustes → Generales</code></strong>, desmarca «<strong>Cualquiera puede registrarse</strong>». Si tu web no necesita que los visitantes tengan cuenta, no hay razón para exponerlo.</li>
</ul>
<h3>Capa media: archivos, permisos y credenciales</h3>
<p>Aquí va el grueso de la protección contra los ataques más sofisticados. Patchstack registró en 2025 la cifra de 11.334 vulnerabilidades en el ecosistema WordPress, con un tiempo medio de apenas 5 horas desde que se publica la vulnerabilidad hasta que los bots la explotan. <strong>Mantener todo actualizado no es opcional, es la primera línea de defensa real.</strong></p>
<ul>
<li style="list-style-type: none;">
<ul>
<li><strong>Actualiza siempre y cuanto antes:</strong> WordPress, plugins y temas. El 91% de las vulnerabilidades de 2025 estaban en plugins, no en el núcleo. Cada plugin sin actualizar es una puerta potencialmente abierta.</li>
<li><strong>Permisos de archivos correctos:</strong> Los archivos deben estar a 644 y los directorios a 755. El <code>wp-config.php</code> puede ir a 440 o 400 si tu servidor lo permite.</li>
<li><strong>Protege los archivos sensibles desde el servidor:</strong> Añade esto por encima del bloque <code># BEGIN WordPress</code>:</li>
</ul>
</li>
</ul>
<pre># Proteger wp-config.php
&lt;Files wp-config.php&gt;
  Order Allow,Deny
  Deny from all
&lt;/Files&gt;

# Proteger .htaccess
&lt;Files .htaccess&gt;
  Order Allow,Deny
  Deny from all
&lt;/Files&gt;

# Bloquear ejecución de PHP en uploads
&lt;IfModule mod_rewrite.c&gt;
  RewriteEngine On
  RewriteRule ^wp-content/uploads/.*\.php$ - [F,L]
&lt;/IfModule&gt;

# Deshabilitar listado de directorios
Options -Indexes</pre>
<ul>
<li><strong>Bloquea la ejecución de PHP en la carpeta <code>uploads/</code>:</strong> Esta carpeta tiene que poder recibir archivos subidos, pero nunca ejecutar PHP. Es uno de los vectores de acceso más habituales una vez que un atacante ha conseguido subir un archivo malicioso.</li>
<li><strong>Contraseñas fuertes y únicas para todos los administradores:</strong> Si tienes varios usuarios con rol de Administrador, cada uno con su propia contraseña segura. Un gestor de contraseñas como Bitwarden lo hace fácil y gratuito.</li>
<li><strong>Elimina el usuario <code>admin</code> si todavía lo tienes:</strong> Es el primer nombre de usuario que prueban todos los ataques automatizados.</li>
<li><strong>Elimina temas y plugins nulled o piratas:</strong> Esto no lo negocies: los temas y plugins de fuentes no oficiales son el vector de infección más rápido y más evitable. Si los tienes, quítalos.</li>
<li><strong>Desactiva XML-RPC si no lo usas:</strong> La mayoría de webs WordPress no lo necesitan actualmente y es un vector de ataque muy usado para inyectar contenido de forma remota.</li>
</ul>
<h3>Capa avanzada: monitorización activa</h3>
<p>Llegamos al punto donde la defensa deja de ser reactiva y se vuelve proactiva. No solo cerramos puertas sino que detectamos cuando alguien intenta abrirlas.</p>
<p><strong>El archivo <code>.htaccess</code> y <code>wp-config.php</code> son los primeros objetivos de cualquier atacante que consiga acceso a tu servidor.</strong> Si esos archivos cambian sin que tú hayas tocado nada, tienes una infección activa. El problema es que nadie mira esos archivos todos los días.</p>
<p>Puedes usar Vigilante para monitorizar ambos archivos contra su línea base original, muestra un <code>diff</code> línea a línea de cualquier cambio y manda un aviso por correo en el momento en que detecta la modificación. En vez de enterarte semanas después porque Google te manda un aviso de acción manual, <strong>te enteras cuando el atacante toca el archivo</strong>. Eso es la diferencia entre limpiar una infección de horas y limpiar meses de daño en el SEO.</p>
<p>Más allá de eso, <strong>un escáner periódico de integridad de archivos</strong> compara los archivos de tu instalación con los oficiales de WordPress.org y detecta modificaciones, archivos añadidos o código sospechoso en temas y plugins. Lo ideal es que esto corra de forma automática y te mande el informe.</p>
<p>Otras medidas avanzadas:</p>
<ul>
<li><strong>Activa la identificación en dos pasos (2FA) para todos los administradores:</strong> Si las credenciales quedan expuestas en una filtración, el 2FA es lo que evita que sirvan de algo.</li>
<li><strong>Registra toda la actividad con un log de auditoría:</strong> Logins, cambios de contraseña, activaciones de plugins, modificaciones de entradas, así todo queda registrado y con alerta si algo parece raro. Si un atacante crea un usuario administrador o activa un plugin que no reconoces, necesitas saberlo en el momento.</li>
<li><strong>Revisa la carpeta <code>mu-plugins/</code> periódicamente:</strong> Los archivos que hay ahí se ejecutan en cada carga de página sin aparecer en la lista de plugins. Si encuentras algo que no pusiste tú, bórralo.</li>
<li><strong>Usa un cortafuegos a nivel de aplicación:</strong> Cloudflare como primera capa (gratis en su plan básico) más un plugin de seguridad con WAF dentro de WordPress bloquea la mayor parte del tráfico malicioso antes de que llegue a intentar explotar nada.</li>
<li><strong>Activa la detección de plugins cerrados:</strong> WordPress.org cierra plugins cuando se descubren problemas de seguridad. Si tienes uno instalado y lo cierran, necesitas saberlo ese mismo día, no cuando busques en Google por qué tu web se comporta raro. Esto lo tiene Vigilante, nadie más.</li>
</ul>
<p>Para completar la defensa contra fuerza bruta, tienes una guía específica en <a href="https://ayudawp.com/fuerza-bruta/" target="_blank" rel="ugc noopener">el plan de batalla contra ataques de fuerza bruta</a> con el detalle de cómo montar la protección por capas desde Cloudflare hasta el plugin.</p>
<h2>Ya lo tengo ¿qué hago?</h2>
<p>Si llegas a este punto con la confirmación de que tu web está infectada, para. No borres nada todavía. El orden importa porque si limpias sin cerrar el vector de entrada, la infección vuelve en horas.</p>
<ol>
<li><strong>Haz una copia de seguridad completa ahora mismo</strong>, incluyendo archivos y base de datos. Incluso de la versión infectada. La necesitarás como referencia para saber exactamente qué cambió y para no perder el contenido legítimo si algo sale mal durante la limpieza.</li>
<li><strong>Pon el sitio en modo mantenimiento</strong> para que los visitantes no lleguen a las páginas infectadas mientras limpias.</li>
<li><strong>Ejecuta un escáner completo</strong> (Wordfence, Sucuri o Vigilante) y guarda el informe completo antes de tocar nada. Necesitas la lista de todo lo afectado antes de empezar a limpiar.</li>
<li><strong>Limpia el núcleo de WordPress.</strong> Descarga la versión exacta que tienes de <a href="https://wordpress.org/download/releases/" target="_blank" rel="nofollow noopener">wordpress.org</a> y sustituye las carpetas <code>wp-admin/</code> y <code>wp-includes/</code> por las originales. No toques <code>wp-content/</code> ni <code>wp-config.php</code> en este paso.</li>
<li><strong>Elimina todos los plugins y temas y reinstálalos desde cero.</strong> Descarga versiones limpias desde WordPress.org o de sus fuentes oficiales. No reactivar los plugins nulled.</li>
<li><strong>Revisa <code>wp-config.php</code></strong> buscando código inyectado al principio o al final del archivo, y revisa <code>.htaccess</code> buscando redirecciones condicionales que no pusiste tú. Si usas Vigilante y tenías el monitoreo activado, el diff te muestra exactamente qué líneas cambiaron.</li>
<li><strong>Audita la carpeta <code>mu-plugins/</code></strong> y la carpeta <code>uploads/</code> buscando archivos PHP que no deberían estar ahí.</li>
<li><strong>Limpia la base de datos.</strong> Revisa <code>wp_posts</code> buscando contenido con enlaces ocultos o contenido que no reconoces. Revisa <code>wp_options</code> buscando valores codificados en base64. Busca en <code>wp_users</code> usuarios administradores que no reconoces.</li>
<li><strong>Elimina todos los usuarios administrador que no reconozcas</strong> y cambia las contraseñas de todos los que sí reconozcas.</li>
<li><strong>Cambia las credenciales de todo: WordPress, base de datos, FTP y cuenta de hosting.</strong> Si la contraseña que usaban para entrar sigue activa, vuelven.</li>
<li><strong>Actualiza WordPress, todos los plugins y todos los temas</strong> a la última versión disponible.</li>
<li><strong>Ejecuta un segundo escáner completo</strong> para verificar que la limpieza ha sido efectiva antes de quitar el modo mantenimiento.</li>
</ol>
<p>Si después de limpiar la infección vuelve en horas o días, hay algún punto de re-entrada que no has cerrado: un plugin vulnerable que no actualizaste, un usuario comprometido que no eliminaste, o una puerta trasera en <code>mu-plugins/</code> o en <code>uploads/</code> que te has dejado. Vuelve al escáner y revisa esos puntos específicamente.</p>
<p>Si el proceso te supera o si el sitio tiene un volumen de páginas infectadas que hace que la limpieza manual sea inviable, el servicio de <a href="https://servicios.ayudawp.com/producto/wordpress-hackeado/" target="_blank" rel="ugc noopener">recuperación de web hackeada</a> existe exactamente para esto.</p>
<h2>Recuperar el SEO después del golpe</h2>
<p>Limpiar la infección es la mitad del trabajo, la otra es <strong>convencer a Google de que ya no hay problema</strong>.</p>
<p>Si Google emitió una acción manual contra tu sitio, aparecerá en <strong><code>Search Console → Seguridad y acciones manuales → Acciones manuales</code></strong>. Una vez limpias la web, puedes solicitar revisión desde esa misma pantalla. El equipo de calidad de Google suele responder en unos días en los casos más claros.</p>
<p>Si no hay acción manual sino penalización algorítmica (tu tráfico cayó pero no hay aviso explícito), el proceso es más lento porque <strong>Google necesita volver a rastrear las páginas afectadas</strong> y procesar que el contenido ya no está. Puedes acelerar esto enviando tu mapa del sitio actualizado desde Search Console y usando la herramienta de inspección de URLs para solicitar la indexación de tus páginas principales.</p>
<p>Las páginas de spam que Google tenía indexadas (los miles de URLs con contenido japonés o farmacéutico) irán desapareciendo del índice a medida que Google las reindexe y confirme que el contenido ya no está. <strong>Este proceso puede tardar semanas, no es inmediato</strong>, pero sí progresivo.</p>
<p>Monitoriza desde Search Console el número de páginas indexadas de tu dominio durante las semanas siguientes a la limpieza. Si vas bien, verás cómo esas URLs spam van desapareciendo del recuento.</p>
<h2>Una última cosa</h2>
<p>El spam SEO inyectado no es un ataque de película que requiere un hacker sofisticado persiguiendo tu web específicamente. Son ataques automatizados que explotan vulnerabilidades conocidas a escala industrial. El destino del ataque no eres tú, es el plugin sin actualizar que tienes instalado, y hay <strong>bots que escanean millones de webs</strong> buscando exactamente eso.</p>
<p>La buena noticia es que <strong>la defensa tampoco es complicada</strong>, se basa en mantener todo actualizado, cerrar los comentarios donde no hacen falta, monitorizar los archivos que más se tocan en un hackeo (<code>wp-config.php</code> y <code>.htaccess</code>) y tener un escáner que avise cuando algo cambia cubre la inmensa mayoría de los casos. Para eso desarrollé <a href="https://vigilante.works/es/" target="_blank" rel="noopener">Vigilante</a>, para que no tengas que pagar por todas esas funcionalidades des seguridad imprescindibles.</p>
<p>El trabajo hay que hacerlo antes de que llegue el problema, no después. Cuando Google te manda el aviso el daño ya lleva semanas hecho.</p>
<p>Si tienes dudas o has pasado por esto y quieres compartir cómo fue el proceso, me tienes ahí abajo en los comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/spam-seo-injection/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Operación Endgame, quejas sobre el congelador de plugins, WordPress 7.1 y mucho SEO + IA #CrónicasWordPress</title>
		<link>https://ayudawp.com/operacion-endgame-quejas-sobre-el-congelador-de-plugins-wordpress-7-1-y-mucho-seo-ia-cronicaswordpress/</link>
					<comments>https://ayudawp.com/operacion-endgame-quejas-sobre-el-congelador-de-plugins-wordpress-7-1-y-mucho-seo-ia-cronicaswordpress/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Fri, 03 Jul 2026 06:44:02 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Vídeos]]></category>
		<category><![CDATA[#CrónicasWordPress]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159831</guid>

					<description><![CDATA[Cada semana me planto en directo en YouTube para contarte lo que se cuece en WordPress, y esta ha venido cargadita. Seguridad a mansalva, dos WordCamps que ya asoman por el horizonte, movimiento serio en el desarrollo del core y la eterna partida entre WordPress y la inteligencia artificial. Te lo resumo todo aquí abajo y, al final de cada bloque, te dejo el vídeo por si te apetece verlo enterito.]]></description>
										<content:encoded><![CDATA[<p>Cada semana me planto en directo en YouTube para contarte lo que se cuece en WordPress, y esta ha venido cargadita. Seguridad a mansalva, dos WordCamps que ya asoman por el horizonte, movimiento serio en el desarrollo del core y la eterna partida entre WordPress y la inteligencia artificial. Te lo resumo todo aquí abajo y, al final, te dejo el vídeo por si te apetece verlo enterito.</p>
<h2>Crónicas WordPress: la actualidad de la semana, sin anestesia</h2>
<p>El lunes toca <strong>Crónicas WordPress</strong>, mi repaso a la actualidad con opinión incluida, que para eso es mi casa. Y esta semana <strong>la seguridad se llevó el protagonismo, y no precisamente para bien</strong>.</p>
<h3>Seguridad: semana movidita</h3>
<p>Arrancamos fuerte con la <strong>Operación EndGame</strong>, el operativo internacional que ha desmantelado una red enorme de malware, con un montón de webs infectadas de por medio. De ahí saltamos a los sospechosos habituales del jardín WordPress, que no dieron tregua:</p>
<ul>
<li><strong>Gravity SMTP:</strong> una vulnerabilidad ha dejado las claves de correo a la intemperie, con millones de intentos de ataque aprovechando el agujero. Si lo tienes instalado, actualiza ya mismo.</li>
<li><strong>Avada Builder:</strong> fallo crítico que permitía borrar archivos sin ni siquiera estar autenticado, o sea, cualquiera desde fuera. De los que quitan el sueño.</li>
<li><strong>Secuestro de cookies de sesión:</strong> te conté cómo alguien puede colarse en tu WordPress sin contraseña ni 2FA (el doble factor de autenticación), robándote la sesión, y qué hacer para taparlo. Lo tienes con calma en mi artículo sobre <a href="https://ayudawp.com/seguridad-cookies-sesion/">la seguridad de las cookies de sesión</a>.</li>
</ul>
<h3>El «congelador» de 24 horas y la rebelión de los desarrolladores</h3>
<p>WordPress.org ha decidido retrasar 24 horas la publicación de las actualizaciones de plugins para poder revisarlas antes de que lleguen a tu web. La idea, sobre el papel, tiene sentido. El problema es que <strong>los desarrolladores se le han rebelado en bloque</strong>, y hay razones para las dos posturas. Le dediqué el último Doctor entero, así que te lo cuento un poco más abajo.</p>
<h3>Comunidad: dos WordCamps, un adiós y culebrón judicial</h3>
<ul>
<li><strong>WordCamp Costa Rica 2026:</strong> los días 18 y 19 de septiembre en San José.</li>
<li><strong>WordCamp Galicia 2026:</strong> 17 y 18 de octubre en A Coruña, y las entradas ya están a la venta, así que ya sabes.</li>
<li><strong>Om Malik:</strong> nos ha dejado a los 59 años uno de los primerísimos usuarios de WordPress. Un recuerdo desde aquí.</li>
<li><strong>Automattic contra WP Engine:</strong> el culebrón judicial sigue su curso y Automattic se ha apuntado un tanto en la pelea por los mensajes de Slack. A río revuelto…</li>
<li><strong>Panel de contribuciones:</strong> estrena escalas personalizables, un detalle majo para quien echa una mano al proyecto.</li>
</ul>
<h3>Versiones y producto: WordPress 7.0.1, 7.1 y compañía</h3>
<p>En el frente del desarrollo también hubo tela que cortar:</p>
<ul>
<li><strong>WordPress 7.0.1</strong> viene de camino, con su candidata a versión final y lanzamiento a la vuelta de la esquina.</li>
<li><strong>WordPress 7.1</strong> va a esconder el bloque Clásico del insertor. Que no eliminarlo, ojo, que aquí nadie se toca nada todavía.</li>
<li><strong>WooCommerce 10.9</strong> llega con registro de emails transaccionales y mejoras de interfaz.</li>
<li><strong>IA en el propio core:</strong> el equipo de inteligencia artificial propone meter <code>wp_knowledge</code> en WordPress. El melón está abierto.</li>
</ul>
<h3>IA y SEO ¡ya está liada!</h3>
<p>Y cerramos por donde más se mueve el suelo últimamente, la IA y el SEO. Los plugins se están poniendo las pilas: <strong>SEOPress 10</strong> se abre a los agentes de IA, trae asistente en el editor y compatibilidad con la Abilities API, mientras que <a href="https://visibility.quest/" target="_blank" rel="noopener"><strong>Visibility</strong></a> mete SEO, AEO y GEO (el posicionamiento de toda la vida más el de los buscadores y las respuestas de IA) en un mismo plugin. Sobre si te puedes fiar de los plugins hechos con IA, ya te di mi opinión con matices en <a href="https://ayudawp.com/fiabilidad-plugins-ia/">este artículo</a>.</p>
<p>En el lado de Google, la <strong>actualización de spam de junio de 2026</strong> se completó en tiempo récord, y como muestra del terremoto conté el caso de <strong>WPBeginner, que ha pasado de 2,6 millones a 27.000 clics mensuales</strong>. Ahí es nada. Si te preguntas qué pintas tú en todo esto, la respuesta pasa por el E-E-A-T, que te expliqué en <a href="https://ayudawp.com/eeat-wordpress/">esta guía</a>.</p>
<p><a href="https://www.youtube.com/watch?v=9zJxv8bb1ko">Ver el directo completo de Crónicas WordPress en YouTube</a>.</p>
<div class="ast-oembed-container " style="height: 100%;"><iframe loading="lazy" title="Operación EndGame, WordCamps Galicia y Costa Rica, WordPress 7.1, Google Spam Update y muucho más…" width="1600" height="900" src="https://www.youtube.com/embed/9zJxv8bb1ko?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
<p>Y ya está, porque esta semana no pude hacer el Doctor WordPress por temas de agenda, y ya que lo siento.</p>
<h2>Nos vemos en el próximo directo</h2>
<p>Y hasta aquí el repaso de la semana. Si te ha quedado alguna duda de cualquiera de los temas, o quieres soltarme tu opinión sobre lo del congelador de plugins (que seguro que tienes la tuya), me tienes ahí abajo, en los comentarios.</p>
<p>Recuerda que hago directo dos veces por semana: <strong>Crónicas los lunes y Doctor los miércoles</strong>, a partir de las 19:30, en el <a href="https://www.youtube.com/@AyudaWPes">canal de Ayuda WordPress</a>. Si te suscribes y le das a la campanita, no se te escapará ninguno.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/operacion-endgame-quejas-sobre-el-congelador-de-plugins-wordpress-7-1-y-mucho-seo-ia-cronicaswordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>