<?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>Fri, 30 Oct 2026 12:41:52 +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>Autopsia de un hackeo de 2021 que seguía en el servidor en 2026: cinco años alojando phishing sin saberlo</title>
		<link>https://ayudawp.com/alojando-phishing/</link>
					<comments>https://ayudawp.com/alojando-phishing/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Mon, 02 Nov 2026 07:28:07 +0000</pubDate>
				<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[phishing]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160623</guid>

					<description><![CDATA[Hace unos días me llegó por correo un aviso de Vigilante con seis archivos PHP dentro de wp-admin y wp-includes que no forman parte de WordPress. La web en cuestión tenía WordPress y todos sus plugins al día, ¿entonces?]]></description>
										<content:encoded><![CDATA[<p>Hace unos días me llegó un aviso de <a href="https://vigilante.works/es/" target="_blank" rel="noopener">Vigilante</a> con <strong>seis archivos PHP dentro de <code>wp-admin</code> y <code>wp-includes</code> que no forman parte de WordPress</strong>.</p>
<p>La web en cuestión, una cuyo nombre no puedo nombrar, tenía WordPress y todos sus plugins al día, ¿entonces?.</p>
<p><a href="https://ayudawp.com/?attachment_id=160626" rel="nofollow"><img fetchpriority="high" decoding="async" class="sombra alignnone wp-image-160626 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/phising-terra-brasil-detectado-plugin-WordPress-Vigilante-1200x912.jpg" alt="" width="1200" height="912" srcset="https://ayudawp.com/wp-content/uploads/2026/10/phising-terra-brasil-detectado-plugin-WordPress-Vigilante-1200x912.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/phising-terra-brasil-detectado-plugin-WordPress-Vigilante-768x583.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/phising-terra-brasil-detectado-plugin-WordPress-Vigilante-1536x1167.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/phising-terra-brasil-detectado-plugin-WordPress-Vigilante.jpg 1664w" sizes="(max-width: 1200px) 100vw, 1200px"></a></p>
<p>Pues <strong>no era una falsa alarma ni un resto de alguna versión antigua</strong>, y tirando del hilo apareció en la raíz una carpeta llamada, literalmente, <code>-</code> (un guion y nada más), y dentro <strong>un kit de <em>phishing</em> completo</strong>, tres <code>webshells</code> y un registro de visitas que llegaba hasta el 30 de septiembre de 2026.</p>
<p>Todo había entrado el 2 de abril de 2021, o sea, que <strong>un hackeo llevaba más de cinco años viviendo dentro de un WordPress que se actualizaba con normalidad</strong>. Y antes de que te pongas en lo peor, te adelanto que, por lo que dejaron escrito los propios archivos, no hay rastro de que nadie llegara a caer en la trampa.</p>
<p>Ya mismo te cuento lo qué había, cómo se escondía, qué dicen las fechas y, sobre todo, cómo puedes comprobar en un rato si tu WordPress tiene algo parecido, que seguro que ya te está corroyendo el misterio ¿a que sí?</p>
<h2>Un aviso, el rastro y una carpeta con nombre de guion</h2>
<p>Aquí tiré de <strong>uno de mis superpoderes</strong>, que es conocerme de memoria las carpetas de WordPress. En vez de caer en el automatismo de «<em>bah, serán archivos normales</em>», entré en el gestor de archivos del hosting a revisar las carpetas y los archivos, y enseguida vi que <strong>aquello no era ni medio normal</strong>.</p>
<p>Los seis archivos del aviso eran tres nombres repetidos en dos sitios, <code>index.php</code>, <code>up.php</code> y <code>contador.php</code>, dentro de <code>wp-admin/js/</code> y de <code>wp-includes/IXR/</code>.</p>
<p>Ninguna de esas dos carpetas lleva archivos así en WordPress, y <strong>un PHP que no reconoce la versión instalada de WordPress dentro de sus carpetas siempre merece que lo abras y lo leas</strong>.</p>
<p><img decoding="async" class="sombra alignnone wp-image-160629" src="https://ayudawp.com/wp-content/uploads/2026/10/ixr-phishing-terra-brasil-1200x392.jpg" alt="" width="1077" height="351" srcset="https://ayudawp.com/wp-content/uploads/2026/10/ixr-phishing-terra-brasil-1200x392.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/ixr-phishing-terra-brasil-768x251.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/ixr-phishing-terra-brasil.jpg 1434w" sizes="(max-width: 1077px) 100vw, 1077px"></p>
<p>Dentro había <strong>código que no pintaba nada ahí</strong>, y al mirar la raíz de la web (el <code>public_html</code>) apareció <strong>la carpeta <code>-</code></strong>.</p>
<p><img decoding="async" class="sombra alignnone wp-image-160630 size-full" src="https://ayudawp.com/wp-content/uploads/2026/10/carpeta-raiz-phising-terra-brasil-wordpress.jpg" alt="" width="1077" height="875" srcset="https://ayudawp.com/wp-content/uploads/2026/10/carpeta-raiz-phising-terra-brasil-wordpress.jpg 1077w, https://ayudawp.com/wp-content/uploads/2026/10/carpeta-raiz-phising-terra-brasil-wordpress-768x624.jpg 768w" sizes="(max-width: 1077px) 100vw, 1077px"></p>
<p>No sé si el nombre está elegido a propósito, pero <strong>desde luego era raro</strong>. En un listado largo pasa desapercibida, y muchos programas de la línea de comandos interpretan un guion suelto como otra cosa (si escribes <code>cd -</code> no entras en ella, vuelves a la carpeta en la que estabas antes).</p>
<p>Un nombre que cuesta ver y cuesta manejar es <strong>un buen nombre para esconder algo</strong>.</p>
<h2>Lo que había dentro del bicho…</h2>
<p>Había tres cosas distintas, montadas en la misma sesión y pensadas para trabajar juntas, pero ninguna tenía nada que ver con la web ni con sus visitantes.</p>
<h3>Un kit de phishing contra los clientes de Terra (Brasil)</h3>
<p>Dentro de la carpeta <code>-</code> había otra llamada <code>fatura</code> (factura, en portugués), y dentro <strong>un clon del área de clientes de Terra, un portal brasileño muy popular</strong>.</p>
<p>El recorrido de la víctima estaba bien pensado, eso hay que reconocerlo:</p>
<ul>
<li><strong>Entrada rotativa:</strong> la página inicial mandaba al azar a una de once copias idénticas con nombres aleatorios, para que bloquear una sola URL no sirviera de nada.</li>
<li><strong>Primer paso:</strong> una pantalla de acceso que pedía el correo y la contraseña de Terra.</li>
<li><strong>Segundo paso:</strong> con la excusa de «actualizar la forma de pago», pedía la tarjeta completa (número, caducidad, código de seguridad y titular), el RG y el CPF, que vienen a ser el DNI y el NIF brasileños.</li>
<li><strong>Salida limpia:</strong> un mensaje de «pago efectuado con éxito» y redirección al correo web real de Terra, para que la víctima no sospechara nada.</li>
</ul>
<p>Los datos robados se guardaban añadiéndolos a un archivo <code>.html</code> dentro del propio kit, que cualquiera que conociese la URL podía leer, y además se enviaban por correo con la función <code>mail()</code> de PHP, es decir, <strong>usando el servidor de la web como servicio de entrega de correo</strong>.</p>
<p><strong>El atacante tenía hasta su panel de control</strong>, con usuario y contraseña, una sección titulada «Infos capturadas [CC’s]» y botones para borrar los registros.</p>
<p><a href="https://ayudawp.com/?attachment_id=160631" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160631 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/Terra-Central-do-Assinante-phising-1200x984.jpg" alt="" width="1200" height="984" srcset="https://ayudawp.com/wp-content/uploads/2026/10/Terra-Central-do-Assinante-phising-1200x984.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/Terra-Central-do-Assinante-phising-768x630.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/Terra-Central-do-Assinante-phising-1536x1260.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/Terra-Central-do-Assinante-phising.jpg 1882w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p><strong>El servidor no era la víctima, era la infraestructura</strong>, y a los que montan estas campañas les da igual de quién sea la web o de qué país, <strong>lo que buscan es un servidor con buena reputación donde colgar sus mierdas malignas</strong>.</p>
<h3>Tres webshells disfrazados de archivo de WordPress</h3>
<p>Repartidos por la carpeta había <strong>tres copias idénticas de un archivo</strong> llamado <code>laj.php</code>. El susodicho es un <code>webshell</code> (un panel de control que permite manejar el servidor desde el navegador como si estuvieras dentro), en concreto una variante de WSO 2.5, muy conocida y muy usada. Con eso se pueden ver, editar y subir archivos, ejecutar comandos, consultar la base de datos y enviar correos.</p>
<p>Lo curioso es el disfraz. El archivo empieza con un comentario copiado de <code>default-filters.php</code>, un archivo real del núcleo de WordPress, y usa nombres de variables y funciones que suenan a WordPress de toda la vida (<code>$wp_nonce</code>, <code>$wpautop</code>, <code>pre_term_name()</code>). Si lo abres deprisa cuela.</p>
<p><strong>El código chungo está escondido dentro de algo que se presenta como una imagen PNG</strong> incrustada, una sola línea de 19.813 caracteres.</p>
<p>Para ejecutarla el archivo la decodifica, la descomprime y la pasa a <code>eval()</code>, pero sin escribir en ningún sitio los nombres de esas funciones, sino construyendolos al revés:</p>
<pre>$filterfunc = strrev('46esab')."_".strrev('edoced');
$preparefunc = strrev('etalfnizg');</pre>
<p>Si te fijas, <code>46esab</code> y <code>edoced</code> al revés son <code>base64</code> y <code>decode</code>, y <code>etalfnizg</code> es <code>gzinflate</code>. ¿Que por qué tanto lío para escribir <code>base64_decode</code>? Pues porque muchos escáneres buscan exactamente ese texto, y así no lo encuentran. <strong>Cabrones pero listos</strong>.</p>
<p>Y ahora un detalle que tiene su gracia (irónicamente), porque esta copia traía una sección añadida que funciona <strong>antes</strong> de pedir la contraseña, y que permite cambiar la contraseña del shell con un simple parámetro en la URL. O sea, que <strong>cualquiera que encontrase el archivo podía quedarse con el shell sin saber la contraseña</strong>.</p>
<p>Junto al shell había también un <code>php.ini</code> que intentaba desactivar el modo seguro de PHP y vaciar la lista de funciones prohibidas, y el propio shell lo reescribía en cada visita.</p>
<h3>Un redireccionador con puerta trasera incluida</h3>
<p>Los seis archivos del aviso de Vigilante eran la tercera pieza, la misma en las dos carpetas de WordPress:</p>
<ul>
<li><strong><code>index.php</code>:</strong> apuntaba cada visita en una carpeta llamada <code>avisos</code> y redirigía a una IP en la nube de Amazon, que sería el destino real de la campaña (no te recomiendo ir a mirar qué hay).</li>
<li><strong><code>contador.php</code>:</strong> una página titulada «CLIENTES ATIVOS» que contaba los clics registrados.</li>
<li><strong><code>up.php</code>:</strong> un formulario para subir cualquier archivo al servidor sin contraseña ni comprobación alguna.</li>
<li><strong>Un archivo de reglas de Apache:</strong> solo dejaba pasar a las IP que empiezan por ciertos números, la mayoría rangos de Latinoamérica, y bloqueaba unos cuantos proxies de Google y algunas IP concretas, seguramente de analistas de seguridad.</li>
</ul>
<p>El <code>up.php</code> es <strong>la pieza más peligrosa</strong> de todas, porque era la llave de repuesto para volver a entrar si alguien limpiaba lo demás.</p>
<p>Este archivo <code>up.php</code> empieza con una cabecera de imagen GIF antes del código PHP, para que algunas herramientas lo tomen por una imagen:</p>
<pre>GIF88GHZ
&lt;?php
if( file_exists($_FILES["uploadfile"]["tmp_name"]) )</pre>
<h2>El catálogo de trucos para pasar desapercibido</h2>
<p>Si juntas todo lo anterior sale un pequeño <strong>manual de camuflaje de código inyectado</strong>, y conviene conocerlo porque son <strong>trucos que se repiten en muchísimos hackeos de WordPress</strong>:</p>
<ul>
<li><strong>Vestirse de WordPress:</strong> carpetas que existen en cualquier instalación y que nadie abre, archivos llamados <code>index.php</code> y comentarios copiados del núcleo.</li>
<li><strong>Escribir al revés:</strong> nombres de funciones peligrosas construidos con <code>strrev()</code> para que no aparezcan en las búsquedas.</li>
<li><strong>Imágenes que no son imágenes:</strong> el código metido en un falso <code>data:image/png</code>, o un PHP que empieza como si fuera un GIF.</li>
<li><strong>Fechas falsas:</strong> el shell se pone a sí mismo la fecha del <code>index.php</code> que tenga al lado (<code>touch(__FILE__, filemtime("index.php"))</code>), así que si ordenas por fecha no destaca.</li>
<li><strong>Filtro por país casero:</strong> reglas de Apache para que solo lleguen las víctimas que interesan y no los curiosos.</li>
<li><strong>Cortina para buscadores:</strong> un <code>robots.txt</code> de 969 líneas que bloquea a unos 320 bots, y un shell que devuelve un error 404 si quien llama se identifica como Google, Bing, Yahoo o Yandex.</li>
<li><strong>URL rotativas:</strong> once copias de la misma página para que bloquear una no sirva.</li>
</ul>
<p>Ninguno es nuevo ni sofisticado, pero juntos funcionan, y <strong>la prueba es que han aguantado más de cinco años</strong>.</p>
<h2>Lo que cuentan las fechas (y lo que no)</h2>
<p>Aquí es donde <strong>la cosa se pone interesante</strong> de verdad, porque <strong>los archivos conservaban las fechas del servidor</strong>, y leídas deeeespaacito te cuentan bastantes detalles.</p>
<p>Todo se inyectó el 2 de abril de 2021, en menos de media hora y en una sola sesión. Los archivos del kit, en cambio, traen fechas de 2020 y de febrero de 2021, señal de que se subió ya empaquetado y de que <strong>se había usado antes en otros sitios</strong>.</p>
<p>Al día siguiente, el 3 de abril de 2021, el atacante probó su formulario con unas credenciales falsas que decían «TEST». Esa prueba es lo único que hay en el archivo donde se guardaban los datos robados, y el archivo no se ha vuelto a modificar desde entonces.</p>
<p>Como cada envío del formulario escribe ahí antes de mandar el correo, <strong>no hay rastro de que nadie llegara a introducir sus datos a través de este servidor</strong>.</p>
<p>Las carpetas <code>avisos</code> del redireccionador están vacías y con la fecha del primer día, así que tampoco registró ni un clic.</p>
<p>¿Y los shells? Pues todo indica que no llegaron a ejecutarse ahí. Recuerda que se ponen la fecha del <code>index.php</code> que tienen al lado cada vez que alguien las abre, y siguen con su fecha original de 2020. Además, el <code>php.ini</code> que reescriben en cada visita sigue con fecha de diciembre de 2020.</p>
<p>Ahora la cifra que es para flipar, porque <strong>el kit llevaba su propio registro de visitas a la página de acceso falsa</strong>, y son 453 visitas desde 285 direcciones IP distintas, la última el 30 de septiembre de 2026.</p>
<p><strong>Suena peor de lo que es</strong>, porque la mayoría de esas visitas se identifican con navegadores que ya no usa nadie (Internet Explorer 10, versiones de Chrome de hace años) o directamente sin identificar, que es el patrón típico de los verificadores automáticos que comprueban URL de phishing. Lo más probable es que <strong>la dirección estuviese fichada en alguna lista antiphishing y la siguieran revisando</strong>, no que hubiera cientos de víctimas.</p>
<p>Dicho esto, las fechas de un archivo se pueden falsificar (el propio shell lo hace, como acabas de ver), así que todo esto son indicios sólidos y coherentes entre sí, no pruebas. Ah, y el <code>up.php</code> no dejaba registro, así que si alguien lo usó, lo que subiera tendría que estar en esas mismas carpetas. No había nada más, y nada menos.</p>
<h2>Qué le puede pasar a una web que sirve phishing (aunque no sea culpa suya)</h2>
<p>Que no haya víctimas registradas no quiere decir que una web con un kit de phishing dentro se vaya de rositas. Para el resto de Internet <strong>esa web está sirviendo un fraude</strong>, da igual que su dueño no lo sepa, y <strong>las consecuencias le caen al dominio y al servidor</strong>, no al que montó el kit, que casi nunca se le pilla:</p>
<ul>
<li><strong>La pantalla roja del navegador:</strong> Chrome, Firefox y Safari usan las listas de navegación segura de Google, y cuando una URL está fichada como engañosa enseñan un aviso rojo a pantalla completa antes de dejarte entrar. Puede afectar solo a las páginas del kit o a todo el dominio, y espanta a casi todo el mundo, porque en un <a href="https://www.usenix.org/conference/usenixsecurity13/technical-sessions/presentation/akhawe" target="_blank" rel="noopener">estudio de investigadores de Google y de la Universidad de Berkeley publicado en 2013</a> solo el 18 % de los usuarios de Chrome y el 9 % de los de Firefox seguían adelante tras un aviso de phishing.</li>
<li><strong>Avisos en Google:</strong> en Search Console aparece un problema de seguridad de tipo «ingeniería social», y los resultados de búsqueda también pueden mostrar advertencias hasta que limpies y pidas una revisión.</li>
<li><strong>Correo que no llega:</strong> los filtros antispam consultan listas de dominios peligrosos, y alguna, como la DBL de Spamhaus, tiene hasta una <a href="https://www.spamhaus.org/resource-hub/dnsbl/changes-in-spamhaus-dbl-dnsbl-return-codes/" target="_blank" rel="noopener">categoría específica para dominios legítimos usados para phishing</a>. Si el tuyo entra, los correos que lleven enlaces a tu web (tus boletines y tu propia firma incluidos) pueden acabar en spam o rechazados. Y si el kit envía correos desde tu servidor, como hacía este, la que se quema es la IP del servidor, lo que en un alojamiento compartido arrastra también a tus vecinos.</li>
<li><strong>Tu servicio de newsletter:</strong> hay servicios de email marketing que comprueban los enlaces de cada campaña contra estas listas y no te dejan enviarla si alguno está fichado, y en una newsletter casi todos los enlaces van a tu propia web. Otros revisan tu web antes de aprobarte la cuenta, y no parece que un dominio marcado por phishing vaya a pasar ese filtro. Y si llegas a enviar y los correos rebotan o acaban marcados como spam, saltan los umbrales de calidad del servicio, que son motivo de suspensión de la cuenta (Brevo, por ejemplo, habla de más de un 2 % de rebotes duros o de un 0,2 % de quejas).</li>
<li><strong>El hosting:</strong> las denuncias de phishing llegan al proveedor de alojamiento, y lo normal es que desactive el contenido o suspenda la cuenta hasta que limpies. Hace bien, porque está protegiendo a terceros y al resto de sus clientes, pero si no te has enterado antes te encuentras la web caída sin saber por qué.</li>
<li><strong>El dominio:</strong> desde abril de 2024 los registradores de dominios .com, .net y compañía están obligados por sus contratos con ICANN a actuar contra el phishing en cuanto tienen pruebas. Eso sí, <a href="https://www.icann.org/en/contracted-parties/advisories/documents/advisory-compliance-with-dns-abuse-obligations-in-the-registrar-accreditation-agreement-and-the-registry-agreement-05-02-2024-en" target="_blank" rel="noopener">la propia ICANN reconoce</a> que en una web hackeada suspender el dominio entero no suele ser lo adecuado, y lo que plantea es avisar primero al titular y al hosting.</li>
<li><strong>La reputación:</strong> INCIBE cuenta el <a href="https://www.incibe.es/empresas/blog/historias-reales-mi-reputacion-perdida-phishing-mi-web" target="_blank" rel="noopener">caso real de un pequeño negocio</a> cuya web alojaba una página falsa de PayPal, con mensajes y comentarios públicos de gente avisando del fraude, y concluye que el daño a su reputación era más difícil de reparar que borrar la página.</li>
<li><strong>Los datos de tus usuarios:</strong> con una webshell el atacante puede llegar a la base de datos. Si en ella hay datos personales de tus clientes o usuarios y no puedes descartar que alguien los haya visto, el RGPD te obliga a valorarlo y, si hay riesgo para ellos, a <a href="https://www.aepd.es/derechos-y-deberes/cumple-tus-deberes/medidas-de-cumplimiento/brechas-de-seguridad" target="_blank" rel="noopener">notificarlo a la AEPD</a> en un máximo de 72 horas desde que lo sabes.</li>
</ul>
<p>Ahora la parte buena, que también la hay, y es que cuando pides la revisión, <a href="https://web.dev/articles/request-a-review" target="_blank" rel="noopener">Google tarda en torno a un día</a> en revisar una web marcada por phishing, y si está limpia retira los avisos en menos de 72 horas.</p>
<p>Las listas de bloqueo tienen sus procedimientos para salir de ellas y, como acabas de ver, ni el registrador debería suspenderte el dominio a la primera.</p>
<p>O sea, que <strong>el daño crece con el tiempo que el kit pasa publicado sin que lo sepas</strong>, y por eso enterarte pronto vale más que cualquier otra medida.</p>
<p>Por cierto, por si te lo preguntas, la web afectada, sorprendentemente, no tenía ningún aviso de nada, <strong>fue algo que detectó <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="noopener">el plugin Vigilante</a></strong> y tuvimos tiempo de borrar todo este bicho y reforzar la instalación para evitar sustos futuros.</p>
<h2>¿Cómo sobrevive un hackeo cinco años a las actualizaciones?</h2>
<p><strong>Las actualizaciones de WordPress funcionan muy bien</strong>, eso es así, y que hoy se apliquen solas ha evitado muchísimos hackeos, y es de las funcionalidades de WordPress que más han hecho por la seguridad en Internet.</p>
<p>Pero el actualizador del núcleo de WordPress sobrescribe los archivos que conoce, y borra una lista de archivos antiguos que él mismo ha ido retirando con los años. Lo que WordPress no sabe que existe, simplemente porque no es parte de la instalación propia WordPress, ni lo mira, y se le puede colar.</p>
<blockquote><p>Actualizar WordPress sustituye los archivos que WordPress conoce. Los que no conoce se quedan donde están.</p></blockquote>
<p>Por este motivo los archivos de <code>wp-admin/js</code> y <code>wp-includes/IXR</code> sobrevivieron a todas las actualizaciones desde abril de 2021.</p>
<p>Con los plugins pasa algo distinto. Al actualizar un plugin WordPress borra su carpeta entera y pone la nueva, así que <strong>un archivo cabrón metido dentro de un plugin suele desaparecer en la siguiente actualización, pero uno metido en <code>wp-admin</code>, en <code>wp-includes</code> o en la raíz no</strong>.</p>
<p>Y la carpeta <code>-</code> estaba fuera de WordPress, en la raíz, donde no la toca ninguna actualización, ni del núcleo, ni de plugins, ni de temas, así que <strong>ahí podría haber seguido otros cinco años</strong>.</p>
<h2>¿Y por dónde entraron? Pues ni puta idea</h2>
<p>La primera tentación es pensar que, como dejaron archivos en carpetas de WordPress, entraron por un fallo de WordPress, y tiene su lógica, no te digo que no, pero no se sostiene.</p>
<p><strong>Dónde deja los archivos un atacante no dice nada de por dónde entró</strong>, porque esas carpetas se eligen por camuflaje. Además, la parte principal, el kit de phishing, ni siquiera estaba en carpetas de WordPress, estaba en el directorio raíz.</p>
<p>Un fallo del núcleo es, de hecho, la explicación menos probable. En abril de 2021 la versión vigente era la 5.7, y la <a href="https://wordpress.org/news/2021/04/wordpress-5-7-1-security-and-maintenance-release/" target="_blank" rel="noopener">5.7.1, publicada el 15 de abril de 2021</a>, corrigió dos fallos de seguridad. Una de las vulnerabilidades era un <a href="https://www.sonarsource.com/blog/wordpress-xxe-security-vulnerability/" target="_blank" rel="noopener">XXE en la biblioteca de medios</a> que solo afectaba a sitios con PHP 8 y exigía poder subir archivos, y permitía leer archivos del servidor, no escribirlos. La otra era una fuga de datos en la API REST que requería ser colaborador. <strong>Ninguno de los dos permite escribir archivos en el servidor</strong>, así que haría falta un fallo del núcleo que nadie ha documentado nunca.</p>
<p>Lo que sí encaja sería más algo como una campaña masiva contra webs WordPress, de más a menos probable en mi opinión:</p>
<ol>
<li><strong>Un plugin o un tema vulnerable de aquella época</strong>, que no tiene por qué seguir instalado hoy.</li>
<li><strong>Credenciales robadas o adivinadas</strong> de un administrador de WordPress. Con acceso de administrador no hace falta ninguna vulnerabilidad, basta con subir un plugin que lleve una shell dentro.</li>
<li><strong>Credenciales de SFTP o del panel del hosting</strong>.</li>
</ol>
<p>¿Por qué no puedo saberlo? Pues porque han pasado más de cinco años y los registros del servidor de aquellas fechas ya no existen en ninguna parte.</p>
<p>Y esa es, al menos para mí, una de las lecciones más importantes de todo esto, que <strong>cuanto más tarde descubres un hackeo, menos rastro queda para saber por dónde entró</strong>, y sin saber por dónde entró no puedes estar seguro de haber cerrado la puerta.</p>
<h2>Cómo comprobar tu WordPress en un momentito</h2>
<p>Para lo básico no necesitas nada más que el gestor de archivos de tu hosting, que es justo lo que usé yo para la primera revisión, y muchas veces es más que de sobra.</p>
<p>Si además tienes acceso SSH (la consola del servidor), al final te dejo unas búsquedas que afinan bastante más, y si no lo tienes, un plugin que lo hace todo por ti.</p>
<h3>Compara con una copia limpia de WordPress</h3>
<p>Descarga la misma versión de WordPress que tienes instalada (las anteriores están en el <a href="https://es.wordpress.org/download/releases/" target="_blank" rel="noopener">archivo de versiones de WordPress.org</a>), descomprímela en tu ordenador y abre <code>wp-admin</code> y <code>wp-includes</code> de tu web en el gestor de archivos.</p>
<p>Compara carpeta por carpeta, porque <strong>cualquier archivo que esté en tu web y no en la descarga limpia merece que lo abras</strong>.</p>
<p>Lleva su rato, y por eso <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="noopener"><strong>es fundamental tener un plugin de seguridad que compare los archivos del núcleo con los originales y te avise de lo que sobra, que es justo el tipo de aviso que destapó este caso</strong></a>. Si te conoces la estructura de WordPress, lo que es raro salta a la vista enseguida.</p>
<h3>Mira qué hay en la carpeta raíz</h3>
<p>Abre la carpeta principal de tu web (normalmente <code>public_html</code>) y repasa todo lo que no sea <code>wp-admin</code>, <code>wp-content</code>, <code>wp-includes</code> o los archivos sueltos de WordPress (<code>index.php</code>, <code>wp-config.php</code>, <code>wp-login.php</code> y compañía).</p>
<p>Saldrán cosas legítimas (archivos de verificación de Google, otras aplicaciones, alguna carpeta tuya de pruebas), pero cada una debería tener una explicación. <strong>Una carpeta que no reconoces en la raíz de tu web no es un detalle, es lo primero que hay que abrir</strong>.</p>
<p>Y si ves copias del <code>wp-config.php</code> con otra extensión (<code>wp-config.php.bak</code>, <code>wp-config-old.txt</code> y cosas así), bórralas. El servidor no las ejecuta como PHP, así que puede entregarlas como texto a quien las pida, <strong>contraseña de la base de datos incluida</strong>.</p>
<h3>Busca PHP donde no debería haberlo</h3>
<p>La carpeta <code>wp-content/uploads</code> es para imágenes y documentos. Algunos plugins guardan ahí algún PHP propio (un <code>index.php</code> vacío para que no se pueda listar la carpeta, o la caché de plantillas de WPML, por ejemplo), pero cualquier otro merece una mirada.</p>
<p>Si tu gestor de archivos tiene buscador, busca <code>.php</code> dentro de esa carpeta y te ahorras ir subcarpeta por subcarpeta.</p>
<h3>Si tienes SSH busca los trucos de camuflaje por su contenido</h3>
<p>Estos comandos se lanzan desde la carpeta donde está WordPress y ninguno modifica nada, solo miran:</p>
<pre>grep -rlE 'strrev\(.(46esab|edoced|etalfnizg)' --include='*.php' .
grep -rlE 'eval\s*\(\s*\$' --include='*.php' .
grep -rl --include='*.php' -m1 '^GIF8' .
find . \( -name 'php.ini' -o -name '.user.ini' \) -exec grep -lE '^\s*disable_functions\s*=\s*$' {} +</pre>
<p>El primero busca funciones peligrosas escritas al revés, el segundo código que ejecuta el contenido de una variable, el tercero archivos PHP que empiezan como un GIF y el cuarto archivos <code>php.ini</code> que vacían la lista de funciones prohibidas.</p>
<p>Ojo con el segundo, porque algún plugin legítimo usa <code>eval()</code> de esta forma (los que te dejan añadir fragmentos de código desde el escritorio, por ejemplo). Si aparece un archivo, mira de qué plugin es antes de asustarte. Los demás no deberían dar ningún resultado en una web limpia.</p>
<p>Fíjate en que <strong>se busca por contenido, no por nombre ni por fecha</strong>, porque este shell podía copiarse a sí misma con otro nombre y, como ya has visto, se cambiaba la fecha.</p>
<h3>Revisa los cambios recientes sin fiarte de las fechas</h3>
<p>También por SSH, esto lista los PHP cambiados en los últimos 30 días:</p>
<pre>find . -name '*.php' -ctime -30</pre>
<p>El truco está en el <code>-ctime</code>, que mira el momento en que el sistema registró el último cambio del archivo y no la fecha de modificación que muestra un listado normal. Esa segunda fecha se puede falsificar con una línea de PHP, como hacía esta shell, pero el <code>ctime</code> no.</p>
<p>Tras una actualización saldrán muchos archivos, lo normal, así que interesa más lanzarlo de vez en cuando y fijarte en lo que no cuadre con ninguna actualización tuya.</p>
<h3>¿Sin SSH y sin ganas de ir carpeta por carpeta? Un plugin que lo revisa por ti</h3>
<p>Para que no tengas que hacerlo todo a mano <strong>he preparado un plugin de revisión que hace estas mismas comprobaciones sin necesidad de SSH</strong>. Es un solo archivo PHP y lo puedes instalar de dos formas:</p>
<ul>
<li><strong>Como cualquier otro plugin:</strong> en «Plugins &gt; Añadir plugin &gt; Subir plugin» eliges el zip que lo contiene, lo instalas y lo activas. Es lo más sencillo.</li>
<li><strong>Como mu-plugin:</strong> subes el archivo PHP con el gestor de archivos a la carpeta <code>wp-content/mu-plugins</code> (si no existe, la creas) y listo. Los mu-plugins son plugins «obligatorios», de los que WordPress carga siempre sin que tengas que activarlos.</li>
</ul>
<p>El código del plugin <a href="https://github.com/fernandotellado/ayudawp-file-review" target="_blank" rel="nofollow noopener">está en mi GitHub</a>, donde también tienes <a href="https://github.com/fernandotellado/ayudawp-file-review/releases/download/1.0.0/ayudawp-file-review.zip" rel="nofollow">el zip en descarga directa</a>.</p>
<p>Una vez instalado aparece una página en <strong>Herramientas &gt; Revisión de archivos</strong>, y cuando pulsas el botón revisa esto:</p>
<ul>
<li>Los archivos del núcleo, comparados con los originales de tu versión usando los checksums oficiales de WordPress.org, así que verás los modificados, los que sobran en <code>wp-admin</code> y <code>wp-includes</code> y los que faltan.</li>
<li>Lo que hay en la raíz y no es de WordPress, marcando las carpetas que tienen PHP dentro.</li>
<li>Los PHP que haya en <code>wp-content/uploads</code>. La caché de plantillas que guardan ahí algunos plugins, como WPML, la reconoce y no la marca como sospechosa.</li>
<li>Los trucos de camuflaje de este caso, buscados por contenido: funciones escritas al revés, código escondido en una línea codificada de miles de caracteres, <code>eval()</code> de variables, PHP que empieza como un GIF, el truco de la fecha, <code>php.ini</code> que quitan restricciones, formularios de subida sin control y páginas que piden datos de tarjeta.</li>
<li>Las copias de <code>wp-config.php</code> con otra extensión, que el servidor puede entregar como texto con la contraseña de la base de datos dentro.</li>
<li>Los PHP cambiados en los últimos días según el <code>ctime</code>, el que no se puede falsificar.</li>
<li>Los administradores de WordPress, con su fecha de alta.</li>
</ul>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160639 size-full" src="https://ayudawp.com/wp-content/uploads/2026/10/revision-archivos-resumen-avisos.jpg" alt="" width="1200" height="1017" srcset="https://ayudawp.com/wp-content/uploads/2026/10/revision-archivos-resumen-avisos.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/revision-archivos-resumen-avisos-768x651.jpg 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></p>
<p><strong>Solo mira, no toca nada.</strong> No borra, no mueve ni envía nada a ningún sitio, salvo la consulta de los checksums a WordPress.org, y solo se ejecuta cuando un administrador pulsa el botón.</p>
<p>Antes de publicarlo lo he probado con los archivos reales de este caso, que salen todos, y con los 80 plugins más populares de WordPress.org y 20 de los temas más usados, más de 48.000 archivos PHP en los que <strong>no da ni un aviso grave en falso</strong>.</p>
<p>Lo único que aparece son cuatro avisos de nivel medio por <code>eval()</code>, en plugins como Code Snippets o WPCode que ejecutan código a propósito, y el propio aviso te explica que en esos casos es normal.</p>
<p>Al terminar te enseña un informe con cada hallazgo, qué es y qué hacer, y un botón para copiarlo en texto plano. La idea es que, si no tienes claro qué significa algo, lo pegues en Claude, ChatGPT o la IA que uses y le pidas que te lo explique.</p>
<p>El informe lleva rutas, fechas y el motivo de cada aviso, nunca el contenido de los archivos ni los nombres de usuario, así que no vas a acabar pegando tu <code>wp-config.php</code> en un chat.</p>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160640 size-full" src="https://ayudawp.com/wp-content/uploads/2026/10/revision-archivos-informe-copiar.jpg" alt="" width="1200" height="515" srcset="https://ayudawp.com/wp-content/uploads/2026/10/revision-archivos-informe-copiar.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/revision-archivos-informe-copiar-768x330.jpg 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></p>
<p>Cuando acabes, bórralo (tiene un botón que lo elimina, lo hayas instalado como plugin o como mu-plugin), porque es una herramienta de revisión puntual, no algo para tener instalado.</p>
<p>Y ojo, que <strong>no encontrar nada no significa que tu web esté limpia</strong>, solo que no tiene nada de lo que este plugin busca.</p>
<p><strong>Si te lías con todo esto, no te compliques. <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="noopener">Vigilante</a> compara por su cuenta los archivos del núcleo con los originales y te avisa</strong> por correo de lo que sobra, como hizo en este caso, <strong>sin subir ningún plugin de revisión, ni exportar informes, ni gastar la suscripción o los tokens de tu IA en interpretarlos</strong>.</p>
<h2>Si encuentras algo tienes tarea</h2>
<p>Sin prisas pero sin pausa, y en este orden:</p>
<ol>
<li><strong>Guarda una copia de lo que encuentres fuera del servidor</strong> antes de borrarlo. Te servirá para entender qué ha pasado, y si hace falta para pedir ayuda.</li>
<li><strong>Borra lo que sobre:</strong> Si está en <code>wp-admin</code> o <code>wp-includes</code>, lo más limpio es sustituir esas dos carpetas enteras por las de una descarga limpia de tu misma versión.</li>
<li><strong>Sigue buscando:</strong> Repite todas las comprobaciones anteriores, porque donde hay una shell suele haber otra, y esta en concreto sabía copiarse con otro nombre.</li>
<li><strong>Revisa los administradores</strong> de WordPress y borra cualquiera que no reconozcas.</li>
<li><strong>Cambia todas las credenciales:</strong> SFTP y SSH, panel del hosting, administradores de WordPress, contraseña de la base de datos y las claves de seguridad (las <em>salts</em>) del <code>wp-config.php</code>. Si no sabes por dónde entraron, es lo razonable aunque no haya indicios de que tocaran nada más.</li>
<li><strong>Mira la reputación del dominio</strong> en el <a href="https://transparencyreport.google.com/safe-browsing/search" target="_blank" rel="noopener">informe de Navegación Segura de Google</a> y en la sección de problemas de seguridad de Search Console. Cuando borres, las URL del kit devolverán un error 404, que es justo lo que hace falta para que salgan de las listas antiphishing.</li>
</ol>
<p>El proceso completo, paso a paso, lo tienes en mi guía para <a href="https://ayudawp.com/limpiar-wordpress-hackeado-infectado/">limpiar y recuperar un WordPress hackeado o infectado</a>. Y si prefieres no pelearte con ello, para eso está mi <a href="https://servicios.ayudawp.com/producto/wordpress-hackeado/">servicio de limpieza de WordPress hackeado</a>, aunque con la guía, algo de paciencia, y <a href="https://ayudawp.com/comprobaciones-limpiar-wordpress-infectado/">la hoja de cálculo que tienes aquí para limpiar un WordPress infectado</a> lo puedes hacer tú.</p>
<h2>Bueno ¿y de qué me sirve a mi esto?</h2>
<p>Llevo más de 20 años con WordPress y mantengo decenas de webs, y nunca había visto algo así, y si no fuese por ese plugin que desarrollé por mis manías de que tengamos buenos plugins gratis, esto <strong>podría haber seguido ahí otros cinco años más</strong> sin hacer ruido pero robando a mucha gente. No te lo cuento para asustarte, te lo cuento porque <strong>actualizar es imprescindible, pero no es lo mismo que estar limpio</strong>.</p>
<p>Las actualizaciones cierran puertas, pero es también posible que no limpien lo que ya entró. Para eso hace falta mirar de vez en cuando qué archivos tienes, con un escáner que te avise o a mano, como te he contado arriba, y <strong>hacer caso cuando algo te dice que hay un archivo que no debería estar</strong>, porque en este caso ese aviso fue lo que destapó todo.</p>
<p>Y no, no hace falta vivir con miedo, en este caso no hubo víctimas registradas que. yo sepa, la web siguió funcionando con normalidad y todo lo que había se limpia con los pasos de arriba. Lo que hace falta es la costumbre de mirar.</p>
<p>Ahora te toca a ti decidir cada cuánto revisas tus webs. Si al lanzar los comandos o el plugin de revisión te aparece algo raro y no sabes qué es, me tienes ahí abajo, en la sección de comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/alojando-phishing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP2Shell, troyanos en plugins de pago y el tráfico que la IA no manda #CrónicasWordPress</title>
		<link>https://ayudawp.com/php2shell-troyanos-en-plugins-de-pago-y-el-trafico-que-la-ia-no-manda-cronicaswordpress/</link>
					<comments>https://ayudawp.com/php2shell-troyanos-en-plugins-de-pago-y-el-trafico-que-la-ia-no-manda-cronicaswordpress/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Fri, 30 Oct 2026 12:41:52 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Vídeos]]></category>
		<category><![CDATA[#CrónicasWordPress]]></category>
		<category><![CDATA[#DoctorWordPress]]></category>
		<category><![CDATA[#TrucosWordPress]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160831</guid>

					<description><![CDATA[Crónicas WordPress: PHP2Shell, debacle del tráfico desde ChatGPT y Google, y WordPress 7.2 a la vista
Una de las peores semanas de seguridad que recuerdo]]></description>
										<content:encoded><![CDATA[<p>Esta semana solo ha habido un directo, el de <strong>Crónicas WordPress del lunes 26 de octubre</strong>, y venía cargadito porque me tocó repasar quince días de actualidad de golpe (sí, fallé alguna semana anterior, lo reconozco).</p>
<p>El Doctor WordPress del miércoles no lo hice por un asunto personal que no podía mover, así que <strong>la semana que viene volvemos a la doble ración habitual</strong>.</p>
<p>Te cuento lo más importante de lo que hablé, y al final tienes el enlace al vídeo completo, con todas las fuentes en la descripción.</p>
<h2>Crónicas WordPress: PHP2Shell, debacle del tráfico desde ChatGPT y Google, y WordPress 7.2 a la vista</h2>
<h3>Una de las peores semanas de seguridad que recuerdo</h3>
<p>Lo más gordo fue <strong>PHP2Shell</strong>. El 21 de octubre el proyecto PHP sacó parches de urgencia para todas las ramas con soporte (8.2, 8.3, 8.4 y 8.5) por dos fallos de memoria que, combinados, permitían a un atacante <strong>ejecutar código en el servidor sin tener ni siquiera una cuenta</strong>, y de paso leer de la memoria contraseñas, tokens y claves de API. Los parches estaban previstos para el 22, pero los identificadores se filtraron el 20 con una puntuación de 10, así que tocó correr.</p>
<p>Todo hay que decirlo, los buenos hosting hicieron su trabajo. SiteGround metió reglas en el servidor para desactivar las funciones afectadas antes de que saliera el parche, Kinsta tiró de reglas de Cloudflare y protección propia, y otros aplicaron mitigaciones temporales. Ahora bien, <strong>todavía hay hostings que no han actualizado PHP</strong>, y que tu sitio te diga «8.5.3» no te dice si estás a salvo (la segura, en esa rama, es la 8.5.12).</p>
<p>Por eso publiqué un <a href="https://ayudawp.com/php2shell/">post con un mini plugin que te dice qué versión tienes y cuál deberías tener</a>, y <a href="https://vigilante.works/es/">actualicé <strong>Vigilante</strong></a> para que te avise si estás en una versión de PHP insegura.</p>
<p>Y no fue solo PHP. Ese mismo día Node.js corrigió diez fallos, uno de ellos en el descompresor Brotli que usa medio internet, y NGINX y MySQL también tuvieron su ración. O sea, <strong>en una semana cayeron el lenguaje, el servidor web, la base de datos y la librería de compresión</strong>.</p>
<h3>Cuando el peligro viene de la versión de pago</h3>
<p>En WordPress lo más preocupante fueron dos ataques a la cadena de suministro, y ojo, que <strong>no hablamos de plugins gratuitos de WordPress.org, sino de versiones de pago</strong>:</p>
<ul>
<li>A UpdraftPlus le entraron en la base de datos de clientes y robaron las claves que conectan las webs con UpdraftCentral, su panel de gestión. Con ellas metían puertas traseras que se saltaban el inicio de sesión y el 2FA. Ya está parcheado, pero si lo usas, revisa.</li>
<li>Rank Math PRO 3.0.123 salió de sus propios servidores con un troyano dentro, entre la noche del 15 y la mañana del 16 de octubre. Si activaste esa versión, lo más probable es que estés hackeado, y el consejo no es actualizar sino <strong>borrar la versión afectada e instalar la nueva desde cero</strong>.</li>
</ul>
<p>También comenté el mercado negro de accesos a escritorios de WordPress, que se venden a cien dólares para estafas de falso soporte técnico. Si quieres entender cómo funcionan estos ataques, te dejo <a href="https://ayudawp.com/ataques-cadena-suministro-plugins/">por qué ya ni siquiera puedes fiarte de los plugins de WordPress.org</a> (el titular tiene su punto de clickbait, lo admito).</p>
<p>Y ya que estamos, conté cómo <a href="https://ayudawp.com/skill-revisar-seguridad-plugins/">reviso ahora la seguridad de mis plugins</a>, por qué cambié el proceso y dónde tienes las skills que uso. Tardo bastante más en sacar cada versión, pero salen bastante más seguras. Me ayudo de la IA, claro, porque <strong>si los malos te atacan con metralletas no te vas a defender con una navaja</strong>.</p>
<h3>Comunidad: herramientas para contribuir y un nuevo patinazo de Mullenweg</h3>
<p>La parte buena es el <strong>Contributor Toolkit 2.0</strong>, una aplicación que te montas en el ordenador con un WordPress dentro y desde la que puedes enviar al Trac un ticket del fallo que encuentres sin pelearte con toda la instalación. No es lo más intuitivo del planeta, pero es mucho más fácil que antes.</p>
<p>La parte mala: Matt Mullenweg apartó a Andrea Fercia, especialista en accesibilidad que lleva contribuyendo desde 2015 y ha participado en 33 versiones de WordPress, y revirtió una mejora para que los avisos del escritorio se pudieran leer con lectores de pantalla. Una persona ciega le ha escrito una carta abierta pidiendo explicaciones. <strong>Sigo sin entender estas decisiones</strong>, salvo que vea la accesibilidad como un freno a la innovación, que ya sería grave.</p>
<p>Y no pude ir a WordCamp Valencia, donde tenía charla en el meetup y en la WordCamp. Si puedes, ve, que hay gente estupenda que lo va a hacer muy bien sin mí.</p>
<h3>WordPress 7.2 beta 1 y lo que viene en desarrollo</h3>
<p>Ya está la beta 1 de <strong>WordPress 7.2</strong>, prevista para el 8 de diciembre. Mucho Gutenberg, mejoras en estilos globales, en la subida de medios y algún widget nuevo de escritorio que no juraría que llegue. Para mí lo importante es la <strong>nueva API de secretos, que por fin da a los desarrolladores un modo de guardar cifradas claves de API y tokens</strong>, algo que le faltaba a WordPress y que, con todo lo que acabamos de contar, llega en buen momento.</p>
<p>Otras novedades de desarrollo:</p>
<ul>
<li>Vuelven las notificaciones unificadas de WordPress, con versión funcional prevista para diciembre. No sé a qué versión irán, yo apostaría más por la 7.3 que por la 7.2.</li>
<li>Firefox ya apoya, y Safari deja de oponerse, a la política de aislamiento de documentos que necesita WordPress para procesar imágenes en el navegador, así que eso ya no dependerá solo de Chrome.</li>
<li>El MCP (el protocolo que permite a las IA comunicarse con tu WordPress) va camino del núcleo, con la 7.3 como posible objetivo.</li>
</ul>
<p>También repasé varios posts que he publicado estas semanas, por si te los perdiste:</p>
<ul>
<li><a href="https://ayudawp.com/allowed-memory-size-exhausted/">«Allowed memory size exhausted», cómo leerlo antes de subir el límite</a>.</li>
<li><a href="https://ayudawp.com/opcode/">El aviso de la caché Opcode</a> y <a href="https://ayudawp.com/error-you-do-not-have-permission-to-manage-plugins/">el error «You do not have permission to manage plugins»</a>, dos avisos del escritorio que no dicen lo que parece.</li>
<li><a href="https://ayudawp.com/plugins-beta-wordpress-org/">Los plugins experimentales de WordPress.org</a>, que deberían avisar mejor de lo que son. Performance Lab tiene más de 100.000 instalaciones, Speculative Loading 70.000 y el plugin oficial de IA 60.000, y <strong>son experimentos para probar, no para tenerlos activos de serie</strong>.</li>
</ul>
<h3>Las ventas de plugins caen y la IA no manda visitas</h3>
<p>Katie Keith, fundadora de Barn2, ha hecho un ejercicio de transparencia que se agradece: <strong>sus ventas nuevas han caído un 48 % en dos años</strong>, sus visitas orgánicas un 86 % y las búsquedas de tutoriales un 91 %, y en 21 de sus 22 búsquedas objetivo aparece un resumen de IA. Ya tenemos culpable. Su respuesta ha sido menos blog y más redes, YouTube y presencia en otros sitios. Le pone números a lo que muchos notamos y casi nadie cuenta.</p>
<p>A esto se suma el estudio de Marie Haynes: 12 meses de Analytics en 100 webs, más de 145 millones de sesiones, y <strong>ChatGPT trajo el 0,62 % de las visitas que trajo Google orgánico</strong>, que ya de por sí manda poco. Y sus anuncios, de momento, no venden.</p>
<p>Mi consejo, que es lo que me ha funcionado a mí y a clientes: <strong>deja de escribir para la pregunta «cómo hago X», que la IA responde sola, y escribe para «dónde aprendo X» o «qué web me recomiendas para X»</strong>, que es cuando el usuario ya quiere visitar webs y la IA le manda a ellas.</p>
<p>Mientras tanto, Google mete más enlaces en sus respuestas con IA, pero sin datos de clics en Search Console y asociados a textos que se inventa a partir del tuyo. Por eso escribí sobre <a href="https://ayudawp.com/nosnippet-data-nosnippet-ia-google/">nosnippet y data-nosnippet</a>, que ahora Google también documenta en su ayuda, y que te permiten <strong>sacar de las respuestas de IA páginas enteras o párrafos concretos</strong>. Te explico cómo hacerlo con varios plugins, con mi plugin Visibility [ENLAZAR: Visibility] o con un filtro de código si no quieres plugins.</p>
<p>Y cerré con algo que hemos visto en varias webs de los clientes de mantenimiento, que de repente se caían: <a href="https://ayudawp.com/trampa-rastreo/">los filtros de WooCommerce pueden convertirse en una trampa de rastreo</a>, un laberinto de URL del que los bots no saben salir y que puede tumbar tu tienda.</p>
<p><strong>Vídeo completo:</strong> <a href="https://www.youtube.com/watch?v=beuMMlqGIXo">PHP2Shell, debacle del tráfico desde ChatGPT y Google, WordPress 7.2 a la vista #CrónicasWordPress</a></p>
<div class="ast-oembed-container " style="height: 100%;"><iframe loading="lazy" title="PHP2Shell, Debacle del tráfico desde ChatGPT y Google, WordPress 7.2 a la vista #CrónicasWordPress" width="1600" height="900" src="https://www.youtube.com/embed/beuMMlqGIXo?feature=oembed&amp;enablejsapi=1" 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 el lunes</h2>
<p>El lunes vuelven las Crónicas y el miércoles el Doctor WordPress, con su truco y sus preguntas en directo. Si quieres que trate algún tema, o tienes una duda para el Doctor, me tienes ahí abajo, en los comentarios, y si no quieres perderte ningún directo, <a href="https://www.youtube.com/AyudaWordPressES">suscríbete al canal</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/php2shell-troyanos-en-plugins-de-pago-y-el-trafico-que-la-ia-no-manda-cronicaswordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Sirve de algo el favicon para el SEO? ¿por qué no sale el de tu WordPress en Google?</title>
		<link>https://ayudawp.com/favicon-seo/</link>
					<comments>https://ayudawp.com/favicon-seo/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 29 Oct 2026 07:28:15 +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[Favicon]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[SERP]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160692</guid>

					<description><![CDATA[El favicon sigue saliendo en Google, pero solo admite BMP, GIF, ICO, PNG, JPEG, PPM y TIFF. Para qué sirve en SEO, qué funciona y las trampas de WordPress, eso vamos a ver…]]></description>
										<content:encoded><![CDATA[<p>Te confieso que yo daba por hecho que Google había quitado los iconos de las webs de sus resultados, igual que quitó en 2014 las fotos de los autores. Pero resulta que no, <strong>el favicon sigue saliendo en los resultados de Google, en el móvil y en el ordenador, junto al nombre del sitio y la URL</strong>, aunque, que se sepa, no te sube ni una posición.</p>
<p>Lo que sí ha cambiado es que desde el 28 de agosto de 2026 <strong>Google dice con todas las letras qué formatos admite para el favicon, y en la lista no están ni WebP, ni AVIF, ni SVG</strong>. Y resulta que WordPress te deja subir el icono del sitio en WebP o AVIF, o te lo convierte un plugin de optimización sin que te enteres.</p>
<p>Vamos a ver <strong>si el favicon pinta algo en el SEO, qué formatos y etiquetas funcionan y cuáles no</strong>, dónde están las trampas de WordPress y cómo comprobar el tuyo en cinco minutos.</p>
<h2>¿Pero Google no había quitado los favicons?</h2>
<p>Lo que quitó Google fueron las fotos de los autores, en 2014, y poco después toda la autoría que venía de Google+ (¿a que ni te acordabas que Google tuvo su red social?).</p>
<p>Los iconos de las webs son otra historia, y bastante más movida:</p>
<ul>
<li>En mayo de 2019 Google <a href="https://blog.google/products/search/new-design-google-search/" target="_blank" rel="nofollow noopener">rediseñó los resultados del móvil</a> y puso el nombre de la web y su icono encima de cada resultado.</li>
<li>En enero de 2020 llevó ese diseño al ordenador y, tras una buena ración de críticas porque los anuncios se confundían con los resultados normales, a los pocos días empezó a quitarlos. Sospecho que de ahí viene la idea de que Google los había eliminado, al menos la mía.</li>
<li>En octubre de 2022, cuando estrenó los nombres de sitio en el móvil, Google dejó claro <a href="https://developers.google.com/search/blog/2022/10/introducing-site-names-on-search?hl=es" target="_blank" rel="nofollow noopener">en su blog</a> que seguía mostrando los favicons, y recomendó un icono de al menos 48 píxeles.</li>
<li>En marzo de 2023 los nombres de sitio y los iconos llegaron al ordenador, y el 7 de septiembre de 2023 los nombres de sitio <a href="https://developers.google.com/search/blog/2023/09/site-names-global-rollout?hl=es" target="_blank" rel="nofollow noopener">llegaron a todos los idiomas</a>, español incluido.</li>
</ul>
<p>Hoy la <a href="https://developers.google.com/search/docs/appearance/visual-elements-gallery?hl=es" target="_blank" rel="nofollow noopener">galería oficial de elementos visuales</a> de Google incluye el favicon como parte de la atribución de cada resultado, es decir, lo que le dice al usuario de dónde viene, junto al nombre del sitio y la URL visible. El nombre del sitio se controla de otra forma, con datos estructurados, y da para otro artículo.</p>
<p>Y si en agosto de 2026 viste el icono de tu web cambiado por un globo gris, la culpa no era tuya, porque entre el 16 y el 23 de agosto le pasó a muchísimas webs y <a href="https://seroundtable.com/google-search-favicons-breaking-41904.html" target="_blank" rel="nofollow noopener">Google reconoció que el fallo era suyo</a>.</p>
<h2>¿Sirve el favicon para el SEO? ¿da autoridad o E-E-A-T?</h2>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160695 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/favicon-ayudawp-serp-google-1200x638.jpg" alt="" width="1200" height="638" srcset="https://ayudawp.com/wp-content/uploads/2026/10/favicon-ayudawp-serp-google-1200x638.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/favicon-ayudawp-serp-google-768x408.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/favicon-ayudawp-serp-google.jpg 1430w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></p>
<p>Por ahí leerás que un buen favicon «transmite confianza» y «mejora tu E-E-A-T». Vamos a poner las cartas sobre la mesa, porque si nos quedamos con lo que dice Google, <strong>no encontrarás en su documentación nada que relacione el favicon con el posicionamiento</strong>.</p>
<ul>
<li><strong>Dónde lo pone Google:</strong> la <a href="https://developers.google.com/search/docs/appearance/favicon-in-search?hl=es" target="_blank" rel="nofollow noopener">información sobre el favicon</a> está en la parte de la documentación que trata del aspecto de tu web en los resultados, con el nombre del sitio, los títulos y los fragmentos, y no en la que explica cómo ordena Google los resultados.</li>
<li><strong>El E-E-A-T:</strong> las <a href="https://services.google.com/fh/files/misc/hsw-sqrg.pdf" target="_blank" rel="nofollow noopener">directrices para los evaluadores de calidad</a>, el documento de 182 páginas (versión del 11 de septiembre de 2025) donde Google explica qué es eso del E-E-A-T, no mencionan el favicon ni una sola vez.</li>
<li><strong>La única relación es en negativo:</strong> en el apartado 4.5.3 de esas directrices, entre las webs engañosas que se llevan la nota más baja, están las que se hacen pasar por otra copiando el logo o la imagen de marca de un sitio con el que no tienen nada que ver. Y ni eso te hunde por sí solo, porque las propias directrices aclaran que ninguna valoración individual afecta directamente a cómo aparece una página en Google.</li>
</ul>
<p>Lo que sí hace es ayudar a que te reconozcan. Cuando alguien ve una lista de resultados, o las fuentes que enlaza la respuesta de la IA de Google, <strong>el icono es una de las primeras cosas que distinguen tu web de las demás, sobre todo si esa persona ya te conoce</strong>. Y fuera de Google es lo que ves en la pestaña del navegador, en los marcadores y en la pantalla de inicio del móvil cuando alguien guarda tu web, que tampoco es poca cosa.</p>
<p>Y aquí va mi opinión, que no es de Google ni la he medido, y es que un lector que reconoce tu icono entre diez resultados tiene más papeletas para hacer clic en el tuyo, mientras que un globo gris genérico no ayuda nada a que te reconozcan.</p>
<blockquote><p>El favicon no te sube posiciones, pero es lo que hace que te reconozcan entre los demás resultados.</p></blockquote>
<p>Si quieres trabajar el E-E-A-T de verdad, tienes mi guía sobre <a href="https://ayudawp.com/eeat-wordpress/" target="_blank" rel="ugc noopener">el E-E-A-T en WordPress</a>, y ya te adelanto que el icono no sale.</p>
<h2>Los formatos de favicon que admite Google, y los que no</h2>
<p>El 28 de agosto de 2026 Google cambió la ficha del favicon para enumerar los formatos admitidos, que son <strong>BMP, GIF, ICO, PNG, JPEG, PPM y TIFF</strong>. En su <a href="https://developers.google.com/search/updates?hl=es" target="_blank" rel="nofollow noopener">registro de cambios</a> explica que los formatos no han cambiado, que antes enlazaba a una referencia externa que se iba actualizando y que eso creaba confusión.</p>
<p>O sea, que <strong>el SVG nunca ha estado admitido para el favicon en Google</strong>, aunque la referencia de antes llevara a pensar lo contrario.</p>
<table>
<thead>
<tr>
<th>Formato</th>
<th>Búsqueda de Google</th>
<th>Icono del sitio de WordPress</th>
</tr>
</thead>
<tbody>
<tr>
<td>PNG</td>
<td>Sí</td>
<td>Sí, y es el que te recomiendo</td>
</tr>
<tr>
<td>JPEG</td>
<td>Sí</td>
<td>Sí, aunque no admite transparencias</td>
</tr>
<tr>
<td>GIF</td>
<td>Sí</td>
<td>Sí</td>
</tr>
<tr>
<td>ICO</td>
<td>Sí</td>
<td>En mi prueba no me dejó subirlo</td>
</tr>
<tr>
<td>BMP</td>
<td>Sí</td>
<td>Depende del editor de imágenes de tu servidor</td>
</tr>
<tr>
<td>PPM y TIFF</td>
<td>Sí</td>
<td>Ni te los plantees para un icono</td>
</tr>
<tr>
<td>WebP</td>
<td>No</td>
<td>Sí, y ahí está la trampa</td>
</tr>
<tr>
<td>AVIF</td>
<td>No</td>
<td>Sí, si tu servidor lo procesa</td>
</tr>
<tr>
<td>SVG</td>
<td>No</td>
<td>No te deja subirlo de serie</td>
</tr>
</tbody>
</table>
<p>El SVG merece un comentario aparte, porque los navegadores sí lo admiten como favicon (Chrome y Edge desde la versión 80, Firefox desde la 41 y Safari desde la 26, más del 92 % de los usuarios según <a href="https://caniuse.com/link-icon-svg" target="_blank" rel="nofollow noopener">Can I use</a>) y muchos generadores de favicons lo incluyen. <strong>Para la pestaña del navegador te vale, pero para Google no</strong>.</p>
<p>Y no lo confundas con el logo de los <a href="https://developers.google.com/search/docs/appearance/structured-data/organization?hl=es" target="_blank" rel="nofollow noopener">datos estructurados de organización</a>, que es otra cosa y sí admite WebP, SVG y AVIF, porque sigue los <a href="https://developers.google.com/search/docs/appearance/google-images?hl=es" target="_blank" rel="nofollow noopener">formatos de Google Imágenes</a>, con un mínimo de 112 × 112 píxeles. El favicon tiene su propia lista, y es más corta.</p>
<p>Mi consejo es que <strong>uses un PNG cuadrado de 512 × 512 píxeles y te olvides</strong>, porque es lo que pide WordPress y cumple de sobra con Google.</p>
<h2>Las etiquetas <code>rel</code> de toda la vida, y cuáles lee Google</h2>
<p>Google saca el favicon de una etiqueta <code>&lt;link&gt;</code> en la cabecera de tu portada, y de esa etiqueta solo se fija en dos atributos, <code>rel</code> y <code>href</code>. Los valores de <code>rel</code> que admite son estos:</p>
<ul>
<li><strong><code>icon</code>:</strong> el estándar actual.</li>
<li><strong><code>shortcut icon</code>:</strong> la forma antigua, que Google sigue leyendo por razones históricas.</li>
<li><strong><code>apple-touch-icon</code>:</strong> el icono pensado para iPhone y iPad.</li>
<li><strong><code>apple-touch-icon-precomposed</code>:</strong> la variante para versiones antiguas de iOS.</li>
</ul>
<p>Una declaración a mano, como se ha hecho siempre, sería algo así:</p>
<pre>&lt;link rel="icon" href="https://tudominio.com/favicon-192.png" sizes="192x192"&gt;
&lt;link rel="apple-touch-icon" href="https://tudominio.com/apple-touch-icon.png"&gt;</pre>
<p>Los atributos <code>sizes</code> y <code>type</code> le sirven al navegador para elegir, pero Google no los menciona. Tampoco nombra el manifiesto (<code>site.webmanifest</code> o <code>manifest.json</code>), el <code>mask-icon</code> de Safari ni la etiqueta <code>msapplication-TileImage</code> de Windows, así que no cuentes con ellos para salir en Google.</p>
<p>Además del formato la <a href="https://developers.google.com/search/docs/appearance/favicon-in-search?hl=es" target="_blank" rel="nofollow noopener">documentación de Google</a> pone estas condiciones:</p>
<ul>
<li><strong>En la portada:</strong> la etiqueta tiene que estar en la página de inicio, que es de donde la lee Google.</li>
<li><strong>Cuadrado:</strong> proporción 1:1 y al menos 8 × 8 píxeles, aunque Google recomienda más de 48 × 48.</li>
<li><strong>Rastreable:</strong> Googlebot tiene que poder rastrear la portada y Googlebot-Image el archivo del icono, así que ninguno de los dos puede estar bloqueado.</li>
<li><strong>Con una URL estable:</strong> no cambies la dirección del icono cada dos por tres.</li>
<li><strong>Uno por nombre de host:</strong> <code>tudominio.com</code> y <code>tienda.tudominio.com</code> pueden tener cada uno el suyo, pero <code>tudominio.com/blog</code> comparte el de la raíz.</li>
<li><strong>Representativo y apropiado:</strong> tiene que representar tu marca, y si Google ve en él pornografía o símbolos de odio lo cambia por un icono por defecto.</li>
</ul>
<p>El icono puede estar alojado fuera de tu web, en un CDN por ejemplo. Y aunque cumplas todo lo anterior, <strong>Google no garantiza que lo muestre</strong>.</p>
<p>Ojo también con el <code>favicon.ico</code> de toda la vida, porque muchas webs tienen ese archivo en la raíz sin ninguna etiqueta que lo declare, ya que los navegadores lo buscan ahí por su cuenta. <strong>Google no documenta que haga lo mismo</strong>, así que no te fíes de que lo encuentre si no lo declaras en la portada. Al final te cuento qué me he encontrado yo con esto.</p>
<h2>Dónde se pone el favicon en WordPress y qué sale</h2>
<p>En WordPress se llama icono del sitio, y lo puedes poner en tres sitios:</p>
<ul>
<li>En «<strong>Ajustes &gt; Generales &gt; Icono del sitio</strong>», desde WordPress 6.5.</li>
<li>En «<strong>Apariencia &gt; Personalizar &gt; Identidad del sitio</strong>», con los temas clásicos.</li>
<li>En los temas de bloques, en el bloque «<strong>Logotipo del sitio</strong>», activando «<strong>Usar como icono del sitio</strong>».</li>
</ul>
<p>WordPress te pide una imagen cuadrada de al menos 512 × 512 píxeles, la recorta y genera varios tamaños. En la cabecera de todas tus páginas, portada incluida, imprime algo así:</p>
<pre>&lt;link rel="icon" href="https://tudominio.com/wp-content/uploads/2026/10/cropped-icono-32x32.png" sizes="32x32" /&gt;
&lt;link rel="icon" href="https://tudominio.com/wp-content/uploads/2026/10/cropped-icono-192x192.png" sizes="192x192" /&gt;
&lt;link rel="apple-touch-icon" href="https://tudominio.com/wp-content/uploads/2026/10/cropped-icono-180x180.png" /&gt;
&lt;meta name="msapplication-TileImage" content="https://tudominio.com/wp-content/uploads/2026/10/cropped-icono-270x270.png" /&gt;</pre>
<p>Con un PNG lo hace bien, porque declara uno de 32 × 32 para la pestaña del navegador y otro de 192 × 192 que cumple de sobra con lo que recomienda Google. La etiqueta de 270 × 270 es para los mosaicos de Windows, y Google no la menciona.</p>
<p>El método de toda la vida, pegar la etiqueta en el <code>header.php</code> del tema o colgarla de <code>wp_head</code>, sigue funcionando, pero en WordPress ya no tiene mucho sentido, porque el icono del sitio hace lo mismo y no se pierde al cambiar de tema.</p>
<h2>Las trampas del icono del sitio en WordPress</h2>
<p>Para no quedarme en lo que dice el código he montado un WordPress 7.1.3 de pruebas y he repetido con iconos en distintos formatos el mismo proceso de subida y recorte que hace la pantalla del icono del sitio. Esto es lo que ha salido.</p>
<h3>El icono conserva el formato que subes</h3>
<p>WordPress admite imágenes WebP desde la versión 5.8 y AVIF desde la 6.5, y <strong>el icono del sitio se queda en el formato del archivo que subes</strong>. Con un PNG las cuatro etiquetas salen en PNG, pero con un WebP las cuatro salen en WebP, y ese formato no está en la lista de Google.</p>
<p>El navegador lo enseña sin problema en la pestaña, así que no notas nada raro, y por eso pasa desapercibido.</p>
<p>Con AVIF no pude completar la prueba porque el editor de imágenes de mi servidor de pruebas no lo procesaba bien, pero el código sigue el mismo camino que con WebP, así que cuenta con el mismo resultado. Si tu servidor no sabe procesarlo, al recortar verás el aviso «No se ha podido procesar la imagen».</p>
<h3>Un plugin de optimización te lo convierte sin preguntarte</h3>
<p>Esta es la más traicionera, porque ni siquiera has subido un WebP. <a href="https://wordpress.org/plugins/webp-uploads/" target="_blank" rel="nofollow noopener">Modern Image Formats</a>, el plugin del equipo de rendimiento de WordPress, con más de 100.000 instalaciones activas, convierte a WebP los PNG y JPEG que subes, y el icono del sitio no se libra. En mi prueba, con la versión 2.7.1 y su configuración por defecto, <strong>subí un PNG y las etiquetas del icono salieron en WebP</strong>.</p>
<p>La solución está en <strong>Ajustes &gt; Medios</strong>, en la sección <strong>Formatos modernos de imagen</strong>, donde tienes que marcar en <strong>Salida de imágenes de reserva</strong> la casilla <strong>Genera también imágenes de reserva en el formato de subida original</strong>. Con esa casilla marcada el icono que subí después salió en PNG.</p>
<p>El ajuste solo cuenta para lo que subas a partir de ese momento, así que <strong>el icono que ya tenías sigue en WebP hasta que lo vuelvas a subir</strong>.</p>
<p>Si usas otro plugin que convierta las imágenes al subirlas y sustituya el original, o algún fragmento de código que use el filtro <code>image_editor_output_format</code>, te puede pasar lo mismo. La forma de saberlo es mirar la extensión de las etiquetas, como te cuento más abajo.</p>
<h3>No te deja subir un ICO ni un SVG</h3>
<p>En mi prueba la biblioteca de medios rechazó el <code>.ico</code> con el aviso «Lo siento, no tienes permisos para subir este tipo de archivo», y el SVG no está permitido de serie. Con BMP depende del editor de imágenes del servidor, porque con GD el recorte falló y con Imagick funcionó.</p>
<p>Si quieres un <code>favicon.ico</code> de los de siempre, súbelo a la raíz de tu web con el gestor de archivos de tu hosting o por FTP, y el servidor lo entregará directamente, sin pasar por WordPress. Eso sí, acuérdate de lo que te decía antes, porque <strong>Google lee las etiquetas de la portada y el archivo de la raíz no sustituye al icono del sitio</strong>.</p>
<h3>Sin icono del sitio, /favicon.ico lleva al logo de WordPress</h3>
<p>Si no configuras un icono del sitio, WordPress no imprime ninguna etiqueta. Y si alguien pide <code>tudominio.com/favicon.ico</code> y no tienes ese archivo en la raíz, WordPress lo redirige con un 302 a <code>wp-includes/images/w-logo-gray-white-bg.png</code>, la W gris de WordPress de 80 × 80 píxeles.</p>
<p>Si tienes icono del sitio esa misma dirección redirige a la versión de 32 × 32 de tu icono, en el formato que tenga.</p>
<h3>Otras cosas que lo pueden estropear</h3>
<ul>
<li><strong>Un icono pequeño:</strong> WordPress te pide 512 × 512, pero no te impide subir uno más pequeño, y en ese caso no lo agranda. En mi prueba con uno de 39 × 39 píxeles, la etiqueta de 192 × 192 apuntaba a la imagen original de 39 × 39, por debajo de lo que recomienda Google.</li>
<li><strong>Varias fuentes de iconos a la vez:</strong> algunos temas antiguos tienen su propio campo para el favicon, y los plugins generadores de favicons meten su propio paquete de etiquetas, a veces con un SVG y un manifiesto. Google no documenta cuál elige si hay varios, así que lo sensato es <strong>tener una sola fuente de iconos y que lo que declares esté en un formato admitido</strong>.</li>
<li><strong>La caché:</strong> después de cambiar el icono vacía la caché de página y la del CDN, porque Google lee el HTML de la portada que le sirves, y si tu caché sigue sirviendo la antigua verá las etiquetas viejas.</li>
<li><strong>El robots.txt:</strong> el icono del sitio vive en <code>wp-content/uploads</code>, así que si bloqueas esa carpeta, o bloqueas a Googlebot-Image para que tus imágenes no salgan en Google Imágenes, Google no podrá leer el icono. Si tienes dudas con los bloqueos, te lo explico en <a href="https://ayudawp.com/disallow-noindex-sitemap/" target="_blank" rel="ugc noopener">cuándo usar Disallow, noindex o el sitemap</a>.</li>
<li><strong>Multisitio en subdirectorios:</strong> cada sitio de la red puede tener su icono, pero para Google todos comparten el de la portada principal, porque están en el mismo nombre de host. Con subdominios cada uno tiene el suyo, igual que pasa con <a href="https://ayudawp.com/robots-txt-wordpress-multisitio/" target="_blank" rel="ugc noopener">el robots.txt en multisitio</a>.</li>
<li><strong>Cambiarlo a menudo:</strong> cada vez que subes un icono nuevo, WordPress crea archivos con otro nombre, y Google pide una URL estable. Cambiarlo cuando renuevas tu imagen está bien, pero cada mes no.</li>
</ul>
<h2>Lo que funciona y lo que no con los favicon y Google</h2>
<table>
<thead>
<tr>
<th>Qué haces</th>
<th>¿Sirve para Google?</th>
<th>Por qué</th>
</tr>
</thead>
<tbody>
<tr>
<td>Icono del sitio de WordPress en PNG, JPEG o GIF</td>
<td>Sí</td>
<td>Formato admitido y etiquetas en la portada</td>
</tr>
<tr>
<td><code>rel="icon"</code> o <code>rel="shortcut icon"</code> a mano en la portada</td>
<td>Sí</td>
<td>Son los valores de <code>rel</code> que lee Google</td>
</tr>
<tr>
<td><code>rel="apple-touch-icon"</code></td>
<td>Sí</td>
<td>También está en su lista</td>
</tr>
<tr>
<td>Icono del sitio en WebP o AVIF</td>
<td>No, según Google</td>
<td>Formato fuera de su lista</td>
</tr>
<tr>
<td>PNG que un plugin convierte a WebP al subirlo</td>
<td>No</td>
<td>Cuenta el formato que imprime WordPress, no el que subiste</td>
</tr>
<tr>
<td>Solo un SVG</td>
<td>No</td>
<td>Lo admiten los navegadores, no Google</td>
</tr>
<tr>
<td>Solo un <code>favicon.ico</code> en la raíz, sin etiqueta</td>
<td>Sin documentar</td>
<td>Google pide la etiqueta en la portada, aunque en una de mis webs lo ha encontrado igualmente</td>
</tr>
<tr>
<td>Icono solo en el manifiesto o con <code>mask-icon</code></td>
<td>No consta</td>
<td>Google no los menciona</td>
</tr>
<tr>
<td>Icono de menos de 48 × 48 píxeles</td>
<td>Puede salir, pero mal</td>
<td>Mínimo de 8 × 8 y recomendado más de 48 × 48</td>
</tr>
<tr>
<td>Icono rectangular</td>
<td>No</td>
<td>Tiene que ser cuadrado</td>
</tr>
<tr>
<td>Portada o icono bloqueados en el robots.txt</td>
<td>No</td>
<td>Google tiene que poder rastrear los dos</td>
</tr>
<tr>
<td>Un icono distinto para <code>tudominio.com/blog</code></td>
<td>No</td>
<td>Uno por nombre de host</td>
</tr>
<tr>
<td>Logo en los datos estructurados de organización</td>
<td>No sustituye al favicon</td>
<td>Es otro elemento, con otras reglas</td>
</tr>
<tr>
<td>Copiar el icono de otra marca</td>
<td>Mala idea</td>
<td>Es suplantación para los evaluadores de Google</td>
</tr>
</tbody>
</table>
<h2>Cómo comprobar si tu favicon es visible en Google</h2>
<ol>
<li>Abre tu portada y mira el código fuente (<code>Ctrl+U</code> en Windows, <code>Cmd+Option+U</code> en Chrome para Mac). Busca <code>icon</code> y fíjate en la extensión de cada dirección, porque <code>.png</code>, <code>.ico</code>, <code>.jpg</code> o <code>.gif</code> están bien, y <code>.webp</code>, <code>.avif</code> o <code>.svg</code> no.</li>
<li>Abre en el navegador la dirección del icono más grande, para ver que carga y que es cuadrado.</li>
<li>Mira tu <code>tudominio.com/robots.txt</code> y comprueba que no bloquea <code>wp-content/uploads</code> ni a Googlebot-Image.</li>
<li>En Search Console inspecciona la URL de tu portada, pulsa <strong>Probar URL publicada</strong> y, en <strong>Ver página probada</strong>, busca las etiquetas en el HTML. Así ves lo mismo que ve Google.</li>
<li>Si has cambiado algo vacía la caché y pulsa <strong>Solicitar indexación</strong> en esa misma inspección.</li>
<li>Ten paciencia, porque Google avisa de que volver a rastrear la portada puede llevar de varios días a varias semanas.</li>
</ol>
<h3>Una comprobación en la salud del sitio</h3>
<p>Si llevas varias webs, o quieres que WordPress te avise si algún plugin te cambia el formato del icono, te dejo un pequeño plugin que añade una comprobación a <strong>Herramientas &gt; Salud del sitio</strong>.</p>
<p>Te avisa si no tienes icono del sitio, si WordPress lo está imprimiendo en WebP, AVIF, SVG o HEIC, y si el icono más grande que puede servir mide menos de 48 × 48 píxeles. No mira tu robots.txt, ni tu caché, ni lo que muestra Google, así que úsalo como complemento de la comprobación manual.</p>
<p>Crea en tu ordenador un archivo llamado <code>ayudawp-site-icon-check.php</code> con este contenido, súbelo a <code>wp-content/plugins</code> con el gestor de archivos de tu hosting o por FTP y actívalo en la pantalla de Plugins:</p>
<pre>&lt;?php
/**
 * Plugin Name: AyudaWP - Comprobar el icono del sitio para Google
 * Description: Añade a la salud del sitio una comprobación del formato y el tamaño del icono del sitio, según los formatos que admite la Búsqueda de Google.
 * Plugin URI: https://ayudawp.com/
 * Version: 1.0.0
 * Author: Fernando Tellado
 * Author URI: https://ayudawp.com/
 * License: GPLv2 or later
 * Text Domain: ayudawp-site-icon-check
 */

defined( 'ABSPATH' ) || exit;

/**
 * Register the check as a direct Site Health test.
 *
 * @param array $tests Site Health tests.
 * @return array
 */
function ayudawp_site_icon_register_test( $tests ) {
	$tests['direct']['ayudawp_site_icon'] = array(
		'label' =&gt; __( 'Icono del sitio para Google', 'ayudawp-site-icon-check' ),
		'test'  =&gt; 'ayudawp_site_icon_test',
	);

	return $tests;
}
add_filter( 'site_status_tests', 'ayudawp_site_icon_register_test' );

/**
 * Check the format and size of the icons WordPress prints in the head.
 *
 * @return array Site Health test result.
 */
function ayudawp_site_icon_test() {
	$result = array(
		'label'       =&gt; __( 'El icono del sitio está en un formato que Google admite', 'ayudawp-site-icon-check' ),
		'status'      =&gt; 'good',
		'badge'       =&gt; array(
			'label' =&gt; 'SEO',
			'color' =&gt; 'blue',
		),
		'description' =&gt; '',
		'actions'     =&gt; sprintf(
			'&lt;p&gt;&lt;a href="%s"&gt;%s&lt;/a&gt;&lt;/p&gt;',
			esc_url( admin_url( 'options-general.php' ) ),
			esc_html__( 'Ir a Ajustes &gt; Generales', 'ayudawp-site-icon-check' )
		),
		'test'        =&gt; 'ayudawp_site_icon',
	);

	// No site icon: WordPress prints no icon tags and /favicon.ico redirects to the WordPress logo.
	if ( ! has_site_icon() ) {
		$result['status']      = 'recommended';
		$result['label']       = __( 'No has configurado un icono del sitio', 'ayudawp-site-icon-check' );
		$result['description'] = '&lt;p&gt;' . esc_html__( 'Sin icono del sitio, WordPress no imprime ninguna etiqueta de icono en la portada y la dirección /favicon.ico redirige al logo de WordPress, salvo que tengas un archivo favicon.ico propio en la raíz de la web.', 'ayudawp-site-icon-check' ) . '&lt;/p&gt;';

		return $result;
	}

	// Formats Google Search does not list as supported for favicons.
	$unsupported = array( 'image/webp', 'image/avif', 'image/svg+xml', 'image/heic', 'image/heif' );
	$bad_formats = array();

	foreach ( array( 32, 192, 180 ) as $size ) {
		$url = get_site_icon_url( $size );
		if ( ! $url ) {
			continue;
		}

		$filetype = wp_check_filetype( (string) wp_parse_url( $url, PHP_URL_PATH ) );
		if ( $filetype['type'] &amp;&amp; in_array( $filetype['type'], $unsupported, true ) ) {
			$bad_formats[] = strtoupper( $filetype['ext'] );
		}
	}

	// Largest icon WordPress can serve (a small upload is served as is).
	$image   = wp_get_attachment_image_src( (int) get_option( 'site_icon' ), array( 192, 192 ) );
	$largest = $image ? (int) min( $image[1], $image[2] ) : 0;

	$messages = array();

	if ( $bad_formats ) {
		$messages[] = sprintf(
			/* translators: %s: image format, such as WEBP or AVIF. */
			esc_html__( 'WordPress está imprimiendo tu icono en formato %s, y la Búsqueda de Google solo admite BMP, GIF, ICO, PNG, JPEG, PPM y TIFF. Sube el icono otra vez en PNG y comprueba que ningún plugin lo convierta a WebP o AVIF al subirlo.', 'ayudawp-site-icon-check' ),
			esc_html( implode( ', ', array_unique( $bad_formats ) ) )
		);
	}

	if ( $largest &amp;&amp; $largest &lt; 48 ) {
		$messages[] = sprintf(
			/* translators: 1: width in pixels, 2: height in pixels. */
			esc_html__( 'El icono más grande que puede servir WordPress mide %1$d por %2$d píxeles. Google pide un mínimo de 8 por 8 y recomienda más de 48 por 48. Sube una imagen cuadrada de al menos 512 por 512 píxeles.', 'ayudawp-site-icon-check' ),
			$largest,
			$largest
		);
	}

	if ( $messages ) {
		$result['status']      = 'recommended';
		$result['label']       = __( 'El icono del sitio puede no salir en los resultados de Google', 'ayudawp-site-icon-check' );
		$result['description'] = '&lt;p&gt;' . implode( '&lt;/p&gt;&lt;p&gt;', $messages ) . '&lt;/p&gt;';

		return $result;
	}

	$result['description'] = '&lt;p&gt;' . esc_html__( 'El formato y el tamaño del icono cumplen lo que pide Google. Que salga en los resultados depende además de que Google pueda rastrear la portada y el icono, y de que vuelva a pasar por tu web.', 'ayudawp-site-icon-check' ) . '&lt;/p&gt;';

	return $result;
}</pre>
<p>Lo he probado en el WordPress de pruebas sin icono, con iconos en PNG, GIF, BMP y WebP, con el PNG convertido por Modern Image Formats y con el de 39 × 39 píxeles. En cada caso sale el aviso que toca.</p>
<p><a href="https://ayudawp.com/?attachment_id=160801" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160801 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/salud-del-sitio-sin-icono-del-sitio-1200x567.jpg" alt="" width="1200" height="567" srcset="https://ayudawp.com/wp-content/uploads/2026/10/salud-del-sitio-sin-icono-del-sitio-1200x567.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/salud-del-sitio-sin-icono-del-sitio-768x363.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/salud-del-sitio-sin-icono-del-sitio-1536x726.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/salud-del-sitio-sin-icono-del-sitio.jpg 1726w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Cuando hayas revisado tus webs desactívalo y bórralo, o déjalo puesto si quieres que vigile. Si no tienes claro dónde poner este tipo de códigos, tienes mi guía sobre <a href="https://ayudawp.com/functions-plugin-mu-snippets/" target="_blank" rel="ugc noopener">plugin, functions.php, snippets o mu-plugin</a>.</p>
<h2>¿Que ha pasado con mis webs?</h2>
<p>El 14 de octubre de 2026 busqué en Google, desde el ordenador y con el operador <code>site:</code>, cada una de mis webs para ver qué icono enseña. Del móvil no tengo datos, y el diseño de los resultados no es el mismo, así que no lo extrapoles.</p>
<ul>
<li><strong>ayudawp.com:</strong> declara tres etiquetas con PNG de 32, 192 y 180 píxeles, y sale el logo.</li>
<li><strong>dietpress.dev:</strong> declara un JPG y también sale bien.</li>
<li><strong>mantenimiento.ayudawp.com:</strong> no declara ninguna etiqueta y solo tiene un <code>/favicon.ico</code> que redirige a un PNG de 39 × 39 píxeles. Sale ese icono, que es distinto del de la web principal.</li>
<li><strong>plugins.ayudawp.com:</strong> tampoco declara etiqueta y sale el logo de AyudaWP, aunque como es el mismo de la web principal no sé de dónde lo saca, pero supongo que del dominio principal.</li>
<li><strong>herramientas.ayudawp.com:</strong> declara un ICO y el icono sale casi en blanco.</li>
<li><strong>visibility.quest:</strong> no tiene icono y sale el globo gris.</li>
</ul>
<p>Lo más curioso es lo de mantenimiento.ayudawp.com: enseña su icono sin tener etiqueta, o sea que Google, en la práctica, sí ha encontrado el <code>/favicon.ico</code> aunque no lo documente. Aun así yo seguiría declarándolo en la portada, porque lo que no está en la documentación puede dejar de funcionar sin avisar.</p>
<p>Esa misma web tiene otro detalle, y es que el archivo del icono se llama <code>.png</code>, pero mi servidor entrega un WebP, y Google lo muestra igualmente. No sé si lo rastreó antes de que pasara o si lo acepta aunque no esté en su lista, así que no lo tomo como regla y me quedo con lo que dice la documentación.</p>
<p>Lo que todavía no he probado es qué pasa si subo un icono en WebP a una web que ya tenga uno bueno, y cuando lo haga actualizaré este artículo con los días que tarda y con lo que sale.</p>
<h2>¿Tengo que hacer algo ya mismo?</h2>
<p>Si tu icono sale bien en Google no toques nada, que si no está roto mejor no tocarlo.</p>
<p>Si sale el globo gris, o nunca lo has mirado, haz la comprobación de cinco minutos. Si el icono sale en WebP, AVIF o SVG, <strong>sube un PNG cuadrado de 512 × 512 píxeles</strong>, y si usas Modern Image Formats u otro plugin que convierta imágenes, activa antes la opción del formato original. Luego vacía la caché, pide la indexación de la portada en Search Console y a esperar, que esto va de días o de semanas.</p>
<p>Si te interesa cómo te muestra Google más allá del icono, tienes también cómo conseguir que tus lectores te marquen como <a href="https://ayudawp.com/fuentes-preferidas-google/" target="_blank" rel="ugc noopener">fuente preferida en Google</a>.</p>
<p>Y si te ha salido algo raro con tu icono, o ves en Google algo distinto de lo que te cuento, me tienes ahí abajo, en los comentarios. Es un icono de nada, pero es lo que ve la gente antes de entrar en tu web, así que mejor que salga el tuyo y no un globo gris.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/favicon-seo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Quién fuerza el HTTPS en tu WordPress? ¿el .htaccess, el wp-config, Cloudflare o tu plugin?</title>
		<link>https://ayudawp.com/https-http/</link>
					<comments>https://ayudawp.com/https-http/#comments</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 28 Oct 2026 07:28:17 +0000</pubDate>
				<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[htaccess]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Vigilante]]></category>
		<category><![CDATA[wp-config.php]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160790</guid>

					<description><![CDATA[Entre la CDN, el servidor, el wp-config.php, la base de datos, los plugins y el propio navegador hay seis sitios que pueden decidir si una visita va por http o por https, cada uno actúa en un momento distinto.]]></description>
										<content:encoded><![CDATA[<p>Ponte en situación…</p>
<p>Una visita llega a tu web por <code>http</code>, en la calle, Cloudflare la coge del brazo, muy educado, y la manda a la puerta de <code>https</code>, dentro, tu servidor, que no se ha enterado de nada porque Cloudflare le habla por <code>http</code>, la ve entrar por la puerta vieja y la vuelve a sacar a la calle, Cloudflare la recoge otra vez y otra vez la mete por <code>http</code>.</p>
<p>Mientras tanto, un plugin de esos de optimizar WordPress le cambia la dirección escrita en el sombrero, otro de seguridad le pega en la espalda un cartel de «solo por https durante un año», y WordPress, desde el quinto, jura que todo está en orden porque en el <code>wp-config.php</code> pone <code>https</code>.</p>
<p>La pobre visita acaba dando vueltas en esa especie de puerta giratoria, como Charlot, hasta que el navegador se harta y suelta aquello de que la página te ha redirigido demasiadas veces. Cine mudo del bueno, de bastonazo y tarta en la cara, solo que la tarta te la comes tú.</p>
<p>¿Te has liado alguna vez con esto?, pues bienvenido al club.</p>
<p><strong>Entre la CDN, el servidor, el <code>wp-config.php</code>, la base de datos, los plugins y el propio navegador hay seis sitios que pueden decidir si una visita va por http o por https</strong>, cada uno actúa en un momento distinto, y a nada que tengas el forzado en dos o tres a la vez empieza la película.</p>
<p>Y lo más gracioso (sic) es que <strong>con uno solo tienes de sobra</strong>, siempre que sepas cuál. ¡Que empiece la película!</p>
<h2>Los síntomas del lío http/s ¿te suena alguno?</h2>
<p>Si has llegado hasta aquí buscando algo, seguramente es por uno de estos:</p>
<ul>
<li>Marcas «<strong>forzar HTTPS</strong>» en un plugin y en el <code>.htaccess</code> <strong>no cambia nada</strong>.</li>
<li>El navegador te dice que <strong>la página te ha redirigido demasiadas veces</strong>.</li>
<li>El candado sale con aviso porque hay <strong>contenido mixto</strong> (imágenes o scripts que se siguen pidiendo por <code>http</code>).</li>
<li><strong>La web se queda de repente sin estilos</strong>, como recién salida de 1998.</li>
<li>Desactivas una opción de HTTPS y descubres que <strong>te ha devuelto enlaces a <code>http</code></strong>.</li>
<li>Lo tienes activado en el hosting, en Cloudflare y en dos plugins, y ya <strong>no sabes cuál quitar sin romper nada</strong>.</li>
</ul>
<p>Todos tienen la misma raíz: <strong>hay varias capas que pueden decidir si una visita va por http o por https, y cada una actúa en un momento distinto</strong>. Si no sabes en qué orden, es normal que no entiendas lo que pasa.</p>
<h2>El reparto de la película</h2>
<p>Pongamos orden, piensa en tu web como un edificio ¿vale?, en la calle hay un portero (la CDN, si usas Cloudflare o similar), en el portal está el conserje (el servidor de tu hosting) y tú vives en el quinto (WordPress). Si el portero ya manda a todo el que llega a la puerta buena, que el conserje y tú lo repitáis no molesta, pero tampoco añade nada, porque a vosotros ya os llega todo el mundo por la puerta correcta.</p>
<p>Y al revés también, <strong>lo que hagas en el quinto no lo ve quien se queda en el portal</strong>. Toca desentrañar la trama.</p>
<h3>La CDN o el proxy: el portero de la calle</h3>
<p>Si tu web pasa por Cloudflare (o por cualquier CDN que haga de proxy, un intermediario entre el visitante y tu servidor), lo primero que contesta a una visita es esa CDN, no tu hosting.</p>
<p>Con la opción «<strong>Siempre usar HTTPS</strong>» activada, Cloudflare manda a https cualquier visita que llegue por http, y lo hace antes de que tu servidor se entere. <strong>Esa visita por http no llega nunca a tu hosting</strong>, así que todo lo que tengas configurado más abajo para forzar HTTPS se queda sin trabajo.</p>
<p>Ahora bien, aquí está la trampa más habitual, que es el modo de cifrado. Cloudflare te deja elegir cómo habla con tu servidor:</p>
<ul>
<li><strong>Flexible:</strong> cifra la conexión con el visitante, pero habla con tu servidor por http.</li>
<li><strong>Completo:</strong> cifra las dos conexiones, aunque no comprueba que el certificado de tu servidor sea válido.</li>
<li><strong>Completo (Estricto):</strong> cifra las dos y exige un certificado válido en tu servidor.</li>
</ul>
<p><a href="https://ayudawp.com/?attachment_id=160792" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160792 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/configurar-https-cloudflare-1200x708.jpg" alt="" width="1200" height="708" srcset="https://ayudawp.com/wp-content/uploads/2026/10/configurar-https-cloudflare-1200x708.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/configurar-https-cloudflare-768x453.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/configurar-https-cloudflare-1536x906.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/configurar-https-cloudflare.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Con Flexible pasa exactamente lo de la puerta giratoria del principio. El visitante llega por https a Cloudflare, Cloudflare se lo pasa a tu servidor por http, tu servidor (o WordPress, o un plugin) ve una visita por http y la manda a https, el navegador vuelve a Cloudflare por https, Cloudflare vuelve a pasársela por http… y así hasta que el navegador tira la toalla.</p>
<blockquote><p>Mi consejo: <strong>si tu hosting te da certificado (hoy casi todos lo dan gratis), usa Completo (Estricto) y olvídate del «Flexible»</strong>.</p></blockquote>
<h3>El servidor: el conserje del portal</h3>
<p>La siguiente capa es tu hosting. Aquí el forzado puede estar en el <code>.htaccess</code> (si el servidor es Apache o LiteSpeed), en la configuración de nginx o en una casilla del panel del hosting que lo hace por ti.</p>
<p>La gracia de esta capa es que actúa antes de que se cargue PHP, así que <strong>cubre absolutamente todo</strong>, ya sean páginas, imágenes, hojas de estilo, scripts y las páginas que tu plugin de caché sirve ya hechas. Es rápido y no depende de que WordPress arranque.</p>
<p>La regla típica en el <code>.htaccess</code>, encima del bloque <code># BEGIN WordPress</code>, es algo así:</p>
<pre>RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]</pre>
<p>Fíjate en la tercera línea. <code>X-Forwarded-Proto</code> es la cabecera con la que un proxy como Cloudflare le cuenta a tu servidor cómo llegó la visita en origen. Sin esa línea, detrás de un proxy en <em>Flexible</em>, la regla del servidor se suma a la puerta giratoria.</p>
<p>Y ojo con una cosa, porque <strong>que no veas la regla en el <code>.htaccess</code> no significa que no exista</strong>. Si el forzado está en el panel del hosting o en nginx ahí no lo vas a encontrar.</p>
<h3>El wp-config.php: lo que WordPress cree que es</h3>
<p>En el <code>wp-config.php</code> hay unas cuantas constantes relacionadas con esto, y conviene saber qué hace cada una por si las dudas:</p>
<ul>
<li><strong><code>WP_HOME</code> y <code>WP_SITEURL</code>:</strong> fijan la dirección del sitio y la de WordPress. Mandan sobre lo que haya guardado en la base de datos, y por eso en los ajustes generales esos dos campos salen en gris.</li>
<li><strong><code>FORCE_SSL_ADMIN</code>:</strong> obliga a usar https en el escritorio y en el acceso. WordPress la activa solo cuando la dirección de WordPress empieza por https, así que, si ya la tienes así, ponerla a mano no cambia nada.</li>
<li><strong><code>FORCE_SSL_LOGIN</code>:</strong> está obsoleta desde WordPress 4.0 y hoy hace exactamente lo mismo que la anterior. Si tienes las dos, sobra una.</li>
</ul>
<p>Lo de <code>WP_HOME</code> y <code>WP_SITEURL</code> tiene una cara B que casi nadie cuenta. Como mandan sobre la base de datos, también esconden lo que hay en ella. <strong>Si algo te cambia a http las direcciones guardadas, Ajustes &gt; Generales te seguirá enseñando https</strong> y no te enterarás. Las constantes protegen la dirección del sitio, no los enlaces de tus entradas.</p>
<p>Y luego está el fragmento que se recomienda cuando hay un proxy delante que no le cuenta a PHP que la visita era segura:</p>
<pre>if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) &amp;&amp; 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
	$_SERVER['HTTPS'] = 'on';
}</pre>
<p>Hace que WordPress dé la visita por segura cuando el proxy dice que lo era. Funciona, pero esa cabecera la puede mandar cualquiera que llegue a tu servidor saltándose el proxy, así que úsala para esto y para nada más. Con Cloudflare en «Completo (Estricto)» ni siquiera te hace falta.</p>
<h3>La base de datos: las direcciones que ya tienes escritas</h3>
<p>Una cosa es por dónde llegan las visitas y otra lo que tienes escrito dentro. En la base de datos están las dos direcciones del sitio (las de los ajustes generales de WordPress) y, sobre todo, miles de enlaces dentro de tus contenidos, como imágenes de las entradas, botones, menús, datos de los maquetadores…</p>
<p>Si la web nació en http y la pasaste a https, esos enlaces siguen diciendo <code>http://</code> hasta que alguien los cambie. Para eso está el buscar y reemplazar, con WP-CLI (<code>wp search-replace</code>) o con un plugin que respete los datos serializados (la forma en que WordPress guarda listas y ajustes, que se rompen si les cambias la longitud a lo bruto con una consulta SQL).</p>
<p><strong>Esto se hace una vez, con copia de seguridad antes, y a otra cosa</strong>, no es algo que tenga que estar «activado».</p>
<h3>Los plugins de rendimiento y seguridad: esos vecinos metomentodo</h3>
<p>Aquí es donde más se mezcla todo, porque bajo la misma etiqueta de «forzar HTTPS» los plugins hacen cosas muy distintas. Cuatro, para ser exactos:</p>
<ul>
<li><strong>Redirigir desde PHP.</strong> Cuando WordPress arranca, el plugin mira si la visita es por http y la manda a https. Es lo que hace, por ejemplo, Vigilante, y por eso no toca el <code>.htaccess</code>, no le hace falta.</li>
<li><strong>Reescribir los enlaces al vuelo.</strong> Antes de enviar la página, cambia los <code>http://</code> de tu dominio por <code>https://</code>. Arregla el contenido mixto sin tocar la base de datos, pero lo hace en cada página que sirve.</li>
<li><strong>Enviar cabeceras al navegador.</strong> Sobre todo HSTS y <code>upgrade-insecure-requests</code>, que veremos en el último punto.</li>
<li><strong>Tocar el <code>.htaccess</code> o la base de datos al activar o desactivar una opción.</strong> Ponen la regla del servidor por ti, o cambian las direcciones guardadas.</li>
</ul>
<p>Lo primero tiene sus límites, y conviene saberlos. <strong>Una redirección desde PHP solo cubre lo que llega a WordPress</strong>. Una imagen o una hoja de estilos se sirven sin pasar por PHP, y una página que tu plugin de caché ya tiene guardada, muchas veces también.</p>
<p>Además, para saber si la visita es segura, WordPress mira lo que le cuenta el servidor (la función <code>is_ssl()</code>), no la cabecera de Cloudflare. O sea, que <strong>una redirección en PHP detrás de Cloudflare en <em>Flexible</em> también se mete en la puerta giratoria</strong>, igual que la del servidor sin su tercera línea.</p>
<p>Lo de reescribir al vuelo es un parche, viene de maravilla justo después de migrar, cuando todavía quedan enlaces viejos, pero lo suyo es arreglar la base de datos una vez y quitarlo.</p>
<p>Y lo último, lo de tocar cosas al activar y desactivar, merece apartado propio.</p>
<h3>Forzar no es migrar (y dejar de forzar no debería ser <em>desmigrar</em>)</h3>
<p>Hay plugins de optimización cuyo «forzar HTTPS» hace bastante más que poner una regla. Al activarlo cambian <code>http://</code> por <code>https://</code> en toda la base de datos, y hasta ahí, bien, pero al desactivarlo hacen lo contrario, cambian todos los <code>https://</code> de tu dominio por <code>http://</code>.</p>
<p>Y si una de las dos cosas sale mal, el chiste se completa. Me llegó un caso hace nada: la regla había desaparecido del <code>.htaccess</code>, el cambio de direcciones no había llegado a hacerse y la casilla seguía marcada, así que el plugin volvía a intentarlo cada vez que alguien iniciaba sesión.</p>
<p>Forzar HTTPS es poner un cartel en la puerta vieja que dice «ahora se entra por la de al lado», ,igrar es cambiar la dirección en tus tarjetas, tus facturas y tu buzón. <strong>Un interruptor que, al quitar el cartel, te reimprime todas las tarjetas con la dirección vieja está mezclando dos cosas que no tienen nada que ver</strong>. Y la segunda no tiene vuelta atrás limpia, porque también te pasa a http los enlaces que ya estaban en https antes de que activaras nada.</p>
<p>De aquí salen dos lecciones que valen para cualquier plugin. La primera es que <strong>una casilla marcada te dice lo que hay guardado, no lo que está pasando</strong>, y la segunda que antes de desactivar una opción de HTTPS conviene saber qué hace al desactivarse, no solo al activarse.</p>
<h3>El navegador: lo que se queda en casa del visitante</h3>
<p>La última capa no está en tu servidor sino en el navegador de cada visitante, y tiene dos protagonistas.</p>
<p><strong>HSTS</strong> (HTTP Strict Transport Security) es el cartel de la espalda del principio, una cabecera que le dice al navegador «a esta web, durante tanto tiempo, solo por https». A partir de ahí el navegador ni intenta el http, lo cambia él solo antes de salir de casa.</p>
<p>Es estupendo, pero es un compromiso, porque <strong>si un día tu certificado caduca o deja de funcionar, los navegadores que recibieron esa cabecera no dejarán entrar a tus visitantes hasta que pase el plazo</strong>, que ni siquiera podrán saltarse el aviso, y desde tu web no lo puedes deshacer. Por eso se empieza con un plazo corto (un día, una semana) y se sube cuando todo va bien.</p>
<p>Con una sola capa que la envíe tienes bastante. Y si la pones en Cloudflare, piénsatelo dos veces antes de quitar Cloudflare, porque el compromiso sigue vivo en los navegadores y a partir de ese momento el certificado que cuenta es el de tu servidor.</p>
<p>El otro protagonista es <strong>el contenido mixto</strong>, una página en https que pide algo por <code>http</code>. Los navegadores actuales intentan cargar por https las imágenes, el audio y el vídeo, y si no pueden, no los cargan. Los scripts y los iframes que van por <code>http</code> los bloquean directamente.</p>
<p>Para eso existe la directiva <code>upgrade-insecure-requests</code> (va dentro de la CSP, la cabecera de política de seguridad de contenidos), que le pide al navegador que lo pida todo por https, también lo que está en otros dominios.</p>
<p>Es muy útil cuando todo lo que usas existe en https, y un desastre cuando no, porque lo que no tenga https deja de cargarse, por eso <a href="https://vigilante.works/" target="_blank" rel="noopener">Vigilante</a> no la incluye en su CSP mientras la dirección del sitio empiece por <code>http</code>.</p>
<h2>Cómo saber quién te está redirigiendo</h2>
<p>Vale, pero en tu web, ¿quién está empujando la puerta? Pues no hace falta adivinarlo, te lo dicen las cabeceras de la respuesta. Desde un terminal:</p>
<pre>curl -I http://tudominio.com/</pre>
<p><a href="https://ayudawp.com/?attachment_id=160795" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160795 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/curl-http-https-redirect-1200x404.jpg" alt="" width="1200" height="404" srcset="https://ayudawp.com/wp-content/uploads/2026/10/curl-http-https-redirect-1200x404.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/curl-http-https-redirect-768x258.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/curl-http-https-redirect-1536x517.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/curl-http-https-redirect.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Y te fijas en lo que acompaña al <code>301</code>:</p>
<ul>
<li><strong>Aparecen <code>server: cloudflare</code> y un <code>cf-ray</code>:</strong> te ha redirigido Cloudflare.</li>
<li><strong>Aparece <code>X-Redirect-By</code></strong> (casi siempre con el valor <code>WordPress</code>, a veces con el nombre de un plugin): te ha redirigido WordPress, o un plugin, desde PHP.</li>
<li><strong>Ni lo uno ni lo otro</strong>, y en <code>Server</code> pone Apache, nginx o LiteSpeed: lo ha hecho el servidor (el <code>.htaccess</code>, nginx o el panel del hosting).</li>
</ul>
<p>Si tienes Cloudflare con «Siempre usar HTTPS» siempre verás la primera, y es lo normal, porque el portero no deja pasar a nadie por la puerta vieja.</p>
<p>Si no te apañas con el terminal, el navegador te da lo mismo. Abre las herramientas de desarrollo, ve a la pestaña Red, marca «Conservar registro» (para que no se borre al redirigir), carga la dirección con http y mira las cabeceras de la primera petición.</p>
<p>Y fíjate en que esto mide lo que llega, no lo que tienes marcado. <strong>Lo que cuenta es la respuesta de tu web, no la casilla del plugin</strong>.</p>
<h2>Qué dejar activado según tu caso (con una basta)</h2>
<p>Que sí, que tenerlo en tres sitios a la vez no suele romper nada, siempre que ninguno se meta en la puerta giratoria. Pero tampoco añade seguridad, porque <strong>la primera capa que redirige se lleva la visita y las demás se quedan mirando</strong>. Mi consejo, el mismo que doy cuando me lo preguntan en los foros, es forzarlo cuanto antes y en un solo sitio.</p>
<h3>Si tienes Cloudflare (o una CDN parecida) delante</h3>
<ul>
<li>Modo Completo (Estricto) y «Siempre usar HTTPS» activado.</li>
<li>En el servidor, la regla con su línea de <code>X-Forwarded-Proto</code> solo si quieres un respaldo para quien llegue directo a tu hosting.</li>
<li>En los plugins, nada más. Como mucho, la redirección en PHP como red de seguridad.</li>
</ul>
<h3>Si no tienes CDN pero tu hosting lo ofrece</h3>
<ul>
<li>Actívalo en el panel del hosting o con la regla del <code>.htaccess</code>.</li>
<li>La redirección en PHP de tu plugin sobra, aunque puedes dejarla de respaldo porque no molesta.</li>
</ul>
<h3>Si no tienes ni CDN ni opción en el hosting</h3>
<ul>
<li>Pon tú la regla en el <code>.htaccess</code>, si tu servidor es Apache o LiteSpeed.</li>
<li>Si no puedes tocarlo, la redirección en PHP de un plugin cumple, sabiendo que no cubre ficheros estáticos ni páginas en caché.</li>
</ul>
<h3>En todos los casos</h3>
<ol>
<li>Las dos direcciones de «Ajustes &gt; Generales» (o las constantes del <code>wp-config.php</code>) en https.</li>
<li>Un buscar y reemplazar en la base de datos, una sola vez, con copia antes.</li>
<li>HSTS lo último, cuando todo lo demás funciona, y con un plazo corto al principio.</li>
<li>Un ojo puesto en la renovación del certificado, sobre todo si has activado HSTS.</li>
</ol>
<h2>¿Y Vigilante qué pinta en todo esto?</h2>
<p>Pues sí, también podría estar liándola, así que te cuento <a href="https://wordpress.org/plugins/vigilante/" target="_blank" rel="noopener">cómo lo hace Vigilante</a>. Su sección HTTPS, en la pestaña de cabeceras, empieza diciendo que no te va a imponer HTTPS, <strong>sus cuatro opciones vienen desactivadas por defecto</strong>.</p>
<ul>
<li><strong>Redirigir de HTTP a HTTPS.</strong> Desde PHP, sin tocar el <code>.htaccess</code>. Solo actúa si la dirección del sitio ya empieza por https, así que no te puede dejar fuera de tu propia web. No cubre ficheros estáticos ni páginas en caché, y detrás de Cloudflare necesita el modo Full o Full (strict), como cualquier redirección en PHP.</li>
<li><strong>Corregir contenido mixto.</strong> Reescribe al vuelo los enlaces http de tu propio dominio, y solo cuando la visita ya va por https. No toca recursos de otros dominios, así que no te los puede romper.</li>
<li><strong>Actualizar las solicitudes inseguras.</strong> Es la directiva <code>upgrade-insecure-requests</code>, separada a propósito porque afecta también a recursos de otros sitios. Actívala cuando sepas que todo lo que usas existe en https.</li>
<li><strong>Cambiar dirección del sitio al activarse.</strong> Pasa a https las dos direcciones de Ajustes &gt; Generales al activar el plugin, y solo si el sitio contesta por https. No toca los enlaces de tus contenidos, y desactivar Vigilante no lo deshace, o sea, que al desactivarlo no te devuelve a http.</li>
</ul>
<p>HSTS va aparte, en su propia sección, y no te deja activarlo mientras la dirección del sitio empiece por http.</p>
<p><a href="https://ayudawp.com/?attachment_id=160793" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160793 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/ajustes-https-hsts-plugin-Vigilante-1200x576.jpg" alt="" width="1200" height="576" srcset="https://ayudawp.com/wp-content/uploads/2026/10/ajustes-https-hsts-plugin-Vigilante-1200x576.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/ajustes-https-hsts-plugin-Vigilante-768x368.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/ajustes-https-hsts-plugin-Vigilante-1536x737.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/ajustes-https-hsts-plugin-Vigilante.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Por cierto, Vigilante envía sus cabeceras desde el <code>.htaccess</code>, y no todos los servidores las aplican. Por eso <strong>su análisis de seguridad no puntúa lo que tienes marcado sino lo que de verdad le llega al navegador</strong>, y si una cabecera activada no llega, te lo dice.</p>
<h2>Moraleja</h2>
<p>El HTTPS dejó de ser opcional hace años, y forzarlo es de lo más sencillo que puedes hacer por tu web. Lo complicado no es activarlo, es que <strong>cada capa te ofrece su propia casilla y nadie te explica que solo necesitas una</strong>.</p>
<p>Así que asegúrate de tener solo una puerta, un portero, las direcciones bien escritas en la base de datos y HSTS cuando estés seguro. El resto, como mucho, de respaldo.</p>
<p>Ahora te toca a ti. Si tienes el forzado repartido en tres sitios, ya sabes cómo averiguar cuál trabaja y cuáles sobran. Y si alguna vez ves a una visita dando vueltas en la puerta giratoria, ya sabes por dónde empezar a mirar. Para todo lo demás, me tienes ahí abajo, en la sección de comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/https-http/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>¿Puedes encadenar Black Friday, Navidad y rebajas de enero sin saltarte la ley? ¿qué precio tienes que tachar en cada una?</title>
		<link>https://ayudawp.com/encadenar-rebajas-omnibus/</link>
					<comments>https://ayudawp.com/encadenar-rebajas-omnibus/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 27 Oct 2026 07:28:19 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Ómnibus]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[WooCommerce]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160753</guid>

					<description><![CDATA[Encadenar Black Friday, Navidad y rebajas de enero se puede, pero cada rebaja se anuncia contra el precio más bajo de los 30 días anteriores. Calendario con números, las salidas que tienes y qué revisar antes del 27 de noviembre.]]></description>
										<content:encoded><![CDATA[<p>Sí, por supuesto que puedes encadenar precios diferentes para Black Friday, Navidad y rebajas de enero, pero <strong>cada rebaja se anuncia contra el precio más bajo que tuvo el producto en los 30 días anteriores</strong>, y después de un Black Friday ese precio ya no es tu precio normal.</p>
<p>Así que, por si tenías aún alguna duda, la oferta de Navidad, tal y como la plantean la mayoría de las tiendas, o baja del precio de Black Friday o no se puede anunciar como rebaja.</p>
<p>Y te lo digo con conocimiento de causa, porque en diciembre de 2025 publiqué aquí mismo un ejemplo para <a href="https://ayudawp.com/programar-multiples-ofertas-woocommerce/" target="_blank" rel="noopener">programar cuatro ofertas seguidas en WooCommerce</a> y, tal y como las anunciaba, <strong>tres de las cuatro no cumplían la regla de los 30 días</strong> (sí, lo he dicho yo).</p>
<p>Así que vamos a verlo pasito a pasito, con un calendario de verdad y con números, que el Black Friday es el 27 de noviembre y es ahora cuando estás decidiendo cómo encadenas tus ofertas.</p>
<h2>¿Cómo se tienen que mostrar las ofertas? … legalmente</h2>
<p>La norma viene de la <strong>Directiva (UE) 2019/2161</strong>, la famosa <strong>Ómnibus</strong>, que añadió el artículo 6 bis a la <a href="https://eur-lex.europa.eu/legal-content/ES/TXT/?uri=CELEX:01998L0006-20220528" target="_blank" rel="nofollow noopener">Directiva 98/6/CE</a>, y en España está en el <a href="https://www.boe.es/buscar/act.php?id=BOE-A-1996-1072#a20" target="_blank" rel="nofollow noopener">artículo 20.1 de la Ley de Ordenación del Comercio Minorista</a> desde mayo de 2022. Te lo conté con detalle en <a href="https://ayudawp.com/directiva-omnibus-woocommerce/" target="_blank" rel="noopener">el artículo sobre la directiva Ómnibus en WooCommerce</a>, así que aquí vamos al grano:</p>
<blockquote><p>Cuando anuncias una rebaja tienes que indicar el precio anterior, y el precio anterior es el más bajo que aplicaste a ese producto en los 30 días previos a la rebaja.</p></blockquote>
<p>Fíjate en que no dice «tu precio habitual», dice el más bajo de esos 30 días, sea por el motivo que sea. Y lo que mucha gente no tiene claro es qué cuenta como «anunciar una rebaja», pues casi todo lo que tu tienda pone alrededor del precio:</p>
<ul>
<li><strong>El precio tachado</strong>, que es el anuncio de rebaja por excelencia.</li>
<li><strong>La etiqueta de «¡Oferta!»</strong> que WooCommerce y tu tema ponen sobre la foto.</li>
<li><strong>El porcentaje</strong>, tipo «-30 %», en la etiqueta o en el texto.</li>
<li><strong>Los banners y los textos de campaña</strong>, del estilo de «Black Friday: hasta un 50 % de descuento».</li>
</ul>
<p>Lo del porcentaje no es una interpretación mía. El 26 de septiembre de 2024 el Tribunal de Justicia de la UE resolvió el <a href="https://eur-lex.europa.eu/legal-content/ES/TXT/?uri=CELEX:62023CJ0330">asunto C-330/23</a>, el de Aldi en Alemania, y dejó claro que <strong>un descuento anunciado en porcentaje o con un mensaje promocional se calcula sobre el precio anterior</strong>, no sobre el precio que a ti te parezca más bonito.</p>
<h2>Precios encadenados, la película</h2>
<p>Vamos con un caso sencillito, vender una camiseta a 29,99 € y planificamos tres campañas:</p>
<ul>
<li>Black Friday, del 27 al 30 de noviembre, a 19,99 €.</li>
<li>Navidad, del 18 al 26 de diciembre, con un 30 % de descuento, o sea, a 20,99 €.</li>
<li>Rebajas de enero, del 7 al 20 de enero, con 12 € menos, a 17,99 €.</li>
</ul>
<p>Tiene toda la lógica comercial del mundo, ¿verdad? Pues mira lo que pasa cuando le aplicas la regla de los 30 días a cada una:</p>
<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>Campaña</th>
<th>Precio</th>
<th>Sus 30 días anteriores</th>
<th>Precio anterior</th>
<th>¿Se puede anunciar como rebaja?</th>
</tr>
</thead>
<tbody>
<tr>
<td>Black Friday (27-30 nov)</td>
<td>19,99 €</td>
<td>28 oct – 26 nov</td>
<td>29,99 €</td>
<td><strong><span style="color: #008000;">Sí</span></strong>: «antes 29,99 €», un 33 % menos.</td>
</tr>
<tr>
<td>Navidad (18-26 dic)</td>
<td>20,99 €</td>
<td>18 nov – 17 dic</td>
<td>19,99 €</td>
<td><strong><span style="color: #ff0000;">No</span></strong>: 20,99 € es más caro que el precio de Black Friday.</td>
</tr>
<tr>
<td>Rebajas de enero (7-20 ene)</td>
<td>17,99 €</td>
<td>8 dic – 6 ene</td>
<td>20,99 €</td>
<td><strong><span style="color: #008000;">Sí</span></strong>, pero contra 20,99 €: un 14 % menos, no un 40 %.</td>
</tr>
</tbody>
</table>
</figure>
<p>Ahí lo tienes, <strong>Navidad no se puede anunciar como rebaja</strong>, porque dentro de sus 30 días está el Black Friday a 19,99 €, y tu «30 % de descuento» en realidad es una subida de un euro. Y <strong>las rebajas de enero sí son rebaja, pero de un 14 %</strong>, porque la referencia ya no son los 29,99 € de siempre, es el precio de Navidad.</p>
<p>Ojo, que puedes vender la camiseta a 20,99 € en Navidad, faltaría más, lo que no puedes es tacharle los 29,99 € al lado ni ponerle la etiqueta de «-30 %».</p>
<h2>¿Y mi precio habitual?</h2>
<p>Pues cuando el precio más bajo sale de la franja de ofertas, ni un día antes. El Black Friday termina el 30 de noviembre, así que <strong>hasta el 31 de diciembre los 19,99 € siguen dentro de los 30 días de cualquier oferta nueva</strong>. Una Navidad anunciada contra los 29,99 € de siempre tendría que empezar el 31 de diciembre… y para entonces ya no es Navidad, es Nochevieja.</p>
<p>Con las rebajas de enero pasa lo mismo, pero con el precio de Navidad, si empiezan antes del 26 de enero, la referencia son los 20,99 €.</p>
<h2>Cómo hacer bien una programación de ofertas de precio</h2>
<ol>
<li><strong>Que cada rebaja baje de la anterior:</strong> Si en Navidad la dejas a 17,99 € sí puedes anunciarla, eso sí, «antes 19,99 €» y con un 10 % menos, no un 40 %.</li>
<li><strong>Vender sin anunciar rebaja:</strong> La pones a 20,99 €, sin tachado, sin etiqueta de oferta y sin porcentaje. Es un precio, no una rebaja, y no tienes nada que justificar.</li>
<li><strong>Separar las campañas más de 30 días:</strong> Es la única forma de que tu precio normal vuelva a ser la referencia y normalmente entre noviembre y enero no da.</li>
</ol>
<p>Hay una cuarta que sale mucho en foros, la de las rebajas progresivas (bajar el precio por escalones dentro de una misma campaña sin que suba en ningún momento). La directiva deja que cada país mantenga como referencia el precio de antes de toda la campaña, pero como ya te conté, no he encontrado que España lo haya transpuesto de forma explícita, así que mi consejo sigue siendo el mismo: <strong>aplica siempre la regla de los 30 días y no te fíes del atajo</strong>.</p>
<h2>WooCommerce ni te va a avisar (ni se le espera)</h2>
<p>WooCommerce tacha siempre el precio habitual, el que pones en «Precio normal», sin mirar qué pasó antes. No sabe nada de la directiva Ómnibus, ni de tus campañas anteriores, ni de los 30 días. Si programas la Navidad a 20,99 € con el precio rebajado de toda la vida, te pinta un precioso 29,99 € tachado y tú a pagar multas.</p>
<p><a href="https://ayudawp.com/?attachment_id=160757" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160757 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/precio-rebajado-nativo-woocommerce-1200x716.jpg" alt="Ficha de WooCommerce en Navidad con 29,99 € tachado y 20,99 €, aunque en Black Friday estuvo a 19,99 €" width="1200" height="716" srcset="https://ayudawp.com/wp-content/uploads/2026/10/precio-rebajado-nativo-woocommerce-1200x716.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/precio-rebajado-nativo-woocommerce-768x458.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/precio-rebajado-nativo-woocommerce-1536x917.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/precio-rebajado-nativo-woocommerce.jpg 1612w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Así que tienes dos caminos:</p>
<ul>
<li><strong>A mano</strong>, con una hoja de cálculo con tus campañas, sus fechas y el precio anterior de cada una, revisada antes de programar nada. Funciona, pero con un catálogo grande es una tortura.</li>
<li><strong>Con un plugin que guarde el historial de precios</strong>, como los que te recomendé en el artículo de la directiva Ómnibus, que guardan el precio más bajo y lo muestran en la ficha. Cumplen, pero <strong>solo saben lo que ya ha pasado</strong>, así que te enteras del problema de la Navidad cuando ya está publicada.</li>
</ul>
<p>Y para eso tienes el plugin <a href="https://es.wordpress.org/plugins/multiple-sale-prices-scheduler/" target="_blank" rel="noopener">Ofertas programadas, descuentos e historial de precios Omnibus para WooCommerce</a> (mío, gratis como todos), que programa las ofertas y, como sabe qué precios vienen, <strong>te avisa en el editor del producto de que la Navidad no baja del Black Friday cuando todavía estás a tiempo de cambiarla</strong>.</p>
<p>En la tienda tacha el precio anterior en lugar del normal, y si una oferta no es rebaja la enseña como un precio más, sin tachado ni etiqueta.</p>
<p>Con la camiseta del ejemplo, para que te hagas una idea de lo que ves:</p>
<ul>
<li><strong>En el editor del producto</strong>, debajo de la oferta de Navidad te sale un aviso: 20,99 € no baja de 19,99 €, el precio más bajo de los 30 días anteriores, así que no se puede anunciar como rebaja. Y debajo de la de enero, una línea que te dice que su precio anterior será 20,99 €, no 29,99 €.</li>
<li><strong>Mientras creas una oferta nueva</strong>, según pones la fecha de inicio y el precio te dice cuál será su precio anterior, antes de guardar nada.</li>
</ul>
<p class="captura"><a href="https://ayudawp.com/?attachment_id=160758" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160758 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/aviso-omnibus-oferta-programada-1200x711.jpg" alt="Ofertas programadas en el editor del producto: la de Navidad avisa de que no baja de 19,99 € y la de enero indica que su precio anterior es 20,99 €" width="1200" height="711" srcset="https://ayudawp.com/wp-content/uploads/2026/10/aviso-omnibus-oferta-programada-1200x711.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-omnibus-oferta-programada-768x455.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-omnibus-oferta-programada-1536x910.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-omnibus-oferta-programada.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p class="captura"><a href="https://ayudawp.com/?attachment_id=160759" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160759 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/vista-previa-oferta-nueva-programada-1200x628.jpg" alt="" width="1200" height="628" srcset="https://ayudawp.com/wp-content/uploads/2026/10/vista-previa-oferta-nueva-programada-1200x628.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/vista-previa-oferta-nueva-programada-768x402.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/vista-previa-oferta-nueva-programada-1536x804.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/vista-previa-oferta-nueva-programada.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<ul>
<li><strong>En la tienda durante el Black Friday</strong> ves lo de siempre, 29,99 € tachado y 19,99 €, porque ahí el precio normal sí es la referencia.</li>
<li><strong>En Navidad</strong> la camiseta sale a 20,99 € sin tachar y sin la etiqueta de oferta, porque no es una rebaja.</li>
<li><strong>En enero</strong> sale tachado 20,99 € al lado de los 17,99 €, con una nota debajo que indica el precio anterior.</li>
</ul>

<a href="https://ayudawp.com/encadenar-rebajas-omnibus/oferta-black-friday/" rel="nofollow"><img width="1200" height="709" src="https://ayudawp.com/wp-content/uploads/2026/10/oferta-black-friday-1200x709.jpg" class="attachment-medium size-medium" alt="" srcset="https://ayudawp.com/wp-content/uploads/2026/10/oferta-black-friday-1200x709.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-black-friday-768x454.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-black-friday-1536x907.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-black-friday.jpg 1564w" sizes="(max-width: 1200px) 100vw, 1200px" decoding="async" fetchpriority="high"></a>
<a href="https://ayudawp.com/encadenar-rebajas-omnibus/oferta-navidad/" rel="nofollow"><img width="1200" height="698" src="https://ayudawp.com/wp-content/uploads/2026/10/oferta-navidad-1200x698.jpg" class="attachment-medium size-medium" alt="" srcset="https://ayudawp.com/wp-content/uploads/2026/10/oferta-navidad-1200x698.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-navidad-768x447.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-navidad-1536x893.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-navidad.jpg 1592w" sizes="auto, (max-width: 1200px) 100vw, 1200px" loading="lazy" decoding="async" fetchpriority="low"></a>
<a href="https://ayudawp.com/encadenar-rebajas-omnibus/oferta-enero/" rel="nofollow"><img width="1200" height="787" src="https://ayudawp.com/wp-content/uploads/2026/10/oferta-enero-1200x787.jpg" class="attachment-medium size-medium" alt="" srcset="https://ayudawp.com/wp-content/uploads/2026/10/oferta-enero-1200x787.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-enero-768x504.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-enero-1536x1008.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/oferta-enero.jpg 1576w" sizes="auto, (max-width: 1200px) 100vw, 1200px" loading="lazy" decoding="async" fetchpriority="low"></a>

<p> </p>
<p>Si usas productos variables con el plugin con el que <a href="https://es.wordpress.org/plugins/show-only-lowest-prices-in-woocommerce-variable-products/" target="_blank" rel="noopener">mostrar solo los precios más bajos en productos variables de WooCommerce</a> para mostrar el «<strong>Desde</strong>», ese precio también sigue la misma regla, porque los dos plugins se comunican entre sí, son hermanitos (hijos del mismo padre, un servidor).</p>
<p><a href="https://ayudawp.com/?attachment_id=160763" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160763 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/Precios-mas-bajos-1200x849.jpg" alt="" width="1200" height="849" srcset="https://ayudawp.com/wp-content/uploads/2026/10/Precios-mas-bajos-1200x849.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/Precios-mas-bajos-768x544.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/Precios-mas-bajos-1536x1087.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/Precios-mas-bajos.jpg 1588w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<h2>Lo que tienes que revisar antes del 27 de noviembre (de 2026, o sea ya)</h2>
<p>Si ya te has aclarado, apunta:</p>
<ol>
<li>Apunta tus campañas de aquí a enero, con sus fechas y sus precios.</li>
<li>Para cada una mira el precio más bajo de los 30 días anteriores a su inicio. Ese es su precio anterior.</li>
<li>Si la oferta no baja de ese precio, no la anuncies como rebaja o bájala un poco más.</li>
<li>Calcula los porcentajes contra el precio anterior, no contra el precio normal, y revisa las etiquetas «-X %» de tu tema (si usas Divi, tengo <a href="https://ayudawp.com/porcentaje-descuento-oferta-woocommerce-divi/">un código para mostrar el porcentaje</a> que ya lo calcula bien).</li>
<li>Revisa los banners y los textos de campaña, porque «hasta un 50 %» también es anunciar una rebaja.</li>
<li>Guarda el historial de precios por si alguien te lo pide. No he encontrado un plazo legal para conservarlo, pero las reclamaciones llegan después de la campaña, no durante.</li>
</ol>
<p class="captura"><a href="https://ayudawp.com/?attachment_id=160764" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160764 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/historial-precios-omnibus-1200x555.jpg" alt="" width="1200" height="555" srcset="https://ayudawp.com/wp-content/uploads/2026/10/historial-precios-omnibus-1200x555.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/historial-precios-omnibus-768x355.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/historial-precios-omnibus-1536x710.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/historial-precios-omnibus.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>No te voy a decir que planificar así sea cómodo, porque no lo es, pero <strong>es mucho más barato revisar el calendario ahora que explicar en febrero por qué tu Navidad estaba «rebajada»</strong>. Las multas, como te conté en el <a href="https://ayudawp.com/directiva-omnibus-woocommerce/">artículo de la directiva Ómnibus</a>, no son de broma.</p>
<p>Ahora te toca a ti decidir cómo montas tu temporada. Si tienes dudas con un caso concreto me tienes ahí abajo, en los comentarios. Y ya estás corriendo, que el viernes negro está a la vuelta de la esquina.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/encadenar-rebajas-omnibus/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP2Shell y WordPress ¿me afecta la vulnerabilidad de PHP? ¿puedo protegerme?</title>
		<link>https://ayudawp.com/php2shell/</link>
					<comments>https://ayudawp.com/php2shell/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Mon, 26 Oct 2026 07:28:13 +0000</pubDate>
				<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[PHP]]></category>
		<category><![CDATA[PHP2Shell]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160778</guid>

					<description><![CDATA[PHP2Shell (CVE-2026-109618 y CVE-2026-109619) está en PHP, no en WordPress. Mira tu versión, qué pedir a tu hosting y prueba un plugin gratuito.]]></description>
										<content:encoded><![CDATA[<p>El 21 de octubre de 2026 <strong>PHP publicó parches de emergencia para dos fallos críticos que pueden permitir ejecutar código en tu servidor sin que el atacante inicie sesión</strong>.</p>
<p>A estos parches se les conoce como <code>PHP2Shell</code> (CVE-2026-109618 y CVE-2026-109619, con una puntuación de 9,2 sobre 10 según el <a href="https://www.php.net/archive/2026.php" target="_blank" rel="nofollow noopener">aviso oficial de PHP</a>) y lo que los hace especiales para quienes usamos WordPress es que <strong>el fallo no está en WordPress ni en tus plugins, sino en el propio PHP</strong>.</p>
<p>Y no, no tiene nada que ver con <code>wp2shell</code>, el fallo de julio que sí estaba en el núcleo de WordPress. Te cuento…</p>
<h2>Mira qué versión de PHP tienes</h2>
<p>Entra en «<strong>Herramientas &gt; Salud del sitio</strong>», abre la pestaña «<strong>Información</strong>» y despliega la sección «<strong>Servidor</strong>», ahí aparece la versión de PHP con la que funciona tu web.</p>
<p><a href="https://ayudawp.com/?attachment_id=160780" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160780 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-version-php-insegura-php2shell-1200x1133.jpg" alt="" width="1200" height="1133" srcset="https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-version-php-insegura-php2shell-1200x1133.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-version-php-insegura-php2shell-768x725.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-version-php-insegura-php2shell-1536x1450.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-version-php-insegura-php2shell.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Estas son las versiones que ya llevan la corrección:</p>
<ul>
<li>PHP 8.5: la 8.5.12 o posterior.</li>
<li>PHP 8.4: la 8.4.27 o posterior.</li>
<li>PHP 8.3: la 8.3.36 o posterior.</li>
<li>PHP 8.2: la 8.2.35 o posterior (esta rama deja de recibir soporte el 31 de diciembre de 2026).</li>
</ul>
<p>Si tu número es inferior, no saques conclusiones todavía, porque hay empresas de hosting que corrigen el fallo sin cambiarlo.</p>
<p>Las distribuciones de Linux como Debian o Ubuntu aplican el parche sobre la versión que ya llevaban y solo suben la revisión del paquete, así que <strong>el número que ves en la ventana de salud del sitio no demuestra por sí solo que estés protegido ni que no lo estés</strong>. La única forma segura de saberlo es preguntárselo a tu hosting.</p>
<p>Con PHP 8.1 o anterior la cosa se complica, porque el proyecto PHP no publica una versión oficial con el parche (solo ha dejado parches mínimos de código fuente para 7.4, 8.0 y 8.1, pensados para quien compila a mano). Dependes de que tu hosting aplique los parches retroportados de su proveedor y, si no te lo confirma, lo prudente es cambiar a una rama con soporte.</p>
<p>Si prefieres que lo compare WordPress por ti, he preparado un plugin gratuito y muy pequeño, <a href="https://github.com/fernandotellado/php2shell-wordpress-check" target="_blank" rel="noopener">WordPress PHP2Shell Check</a>. <strong>Añade una prueba a la pantalla de salud del sitio que coteja la versión de PHP con la que está funcionando tu web con las que llevan la corrección</strong>, y solo lee, no envía nada fuera, no guarda nada y no tiene ajustes.</p>
<p><a href="https://ayudawp.com/?attachment_id=160781" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160781 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-info-php2shell-1200x1475.jpg" alt="" width="1200" height="1475" srcset="https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-info-php2shell-1200x1475.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-info-php2shell-768x944.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-info-php2shell-1250x1536.jpg 1250w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-info-php2shell-1666x2048.jpg 1666w, https://ayudawp.com/wp-content/uploads/2026/10/salud-sitio-WordPress-info-php2shell.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Si tu versión es inferior no te dice que estés en peligro, porque ya has visto que no se puede saber desde dentro, sino que te lo explica y te da el mensaje para tu hosting con tu versión ya puesta. Ni detecta ataques ni sustituye a preguntarle a tu hosting.</p>
<h2>Qué puedes hacer tú y qué solo puede hacer tu hosting</h2>
<p>Lo que sí está en tu mano es <a href="https://ayudawp.com/cambiar-version-php-wordpress/" target="_blank" rel="noopener">cambiar la versión de PHP</a> desde el panel de tu hosting, si te deja, y comprobar después en la pantalla de salud del sitio que el cambio se ha aplicado. Y ojo, que elegir una rama en el panel no garantiza que ya lleve el parche, porque eso depende de que tu hosting la haya actualizado.</p>
<p>Lo demás no depende de ti. Las medidas de PHP para quien no puede actualizar se aplican en el <code>php.ini</code> o en la configuración del servidor, y para la del progreso de subida el propio PHP avisa de que ni <code>ini_set()</code> ni un archivo <code>.user.ini</code> sirven porque llegan tarde. <strong>En un hosting compartido eso solo lo puede tocar soporte</strong>, así que escríbeles algo como esto:</p>
<blockquote><p>Hola, ¿habéis aplicado ya en vuestros servidores los parches de PHP para CVE-2026-109618 y CVE-2026-109619 (PHP 8.2.35, 8.3.36, 8.4.27, 8.5.12 o su equivalente retroportado)? ¿Podéis confirmarme qué versión o paquete usa mi sitio y si se han reiniciado los procesos de PHP después de actualizar?</p></blockquote>
<p>Si el servidor es tuyo y no puedes actualizar todavía, contra el segundo fallo PHP recomienda desactivar el seguimiento del progreso de subida de sesiones y reiniciar todos los procesos de PHP:</p>
<pre>; php.ini
session.upload_progress.enabled = 0

; pool de PHP-FPM
php_admin_value[session.upload_progress.enabled] = 0</pre>
<p>Eso reduce la exposición, pero no hace segura la instalación, así que no sustituye a actualizar. En el <a href="https://www.php.net/archive/2026.php" target="_blank" rel="nofollow noopener">aviso oficial</a> tienes también las medidas contra el primer fallo, que tienen que ver con límites de memoria y de tamaño de las peticiones.</p>
<h2>Escáneres de GitHub: no los lances contra tu web</h2>
<p>Si buscas «<strong>php2shell</strong>» en GitHub vas a encontrar una docena de «escáneres», casi todos de los últimos días y con muy pocas estrellas. <strong>No lances ninguno contra tu web</strong>.</p>
<p>Los que miran la versión desde fuera no ven nada si el hosting oculta la cabecera o corrige el fallo sin cambiar el número, y los que sondean de verdad intentan provocar el error de memoria en un servidor que no controlas (los autores de uno de ellos admiten que es arriesgado, y otro escribe datos en las sesiones del servidor que escanea).</p>
<p>A eso súmale que ejecutar código ajeno recién publicado, sin apenas revisión externa y en plena fiebre por un fallo crítico, ya es mala idea por sí solo, ¿o no hemos aprendido nada últimamente?.</p>
<p>Tu comprobación sigue siendo la herramienta de salud del sitio de WordPress, y la pregunta a tu hosting. Y si administras tu propio servidor, mira directamente la versión del paquete instalado y la configuración de PHP, que es más fiable que cualquier sonda desde fuera.</p>
<h2>Por qué ningún plugin te protege de esto</h2>
<p>Un plugin de seguridad es <strong>código PHP que se ejecuta dentro de PHP</strong>, así que pedirle que arregle un fallo del propio PHP es como poco contradictorio, y te lo digo yo, que hago plugins de seguridad.</p>
<p>Además, en Apache con <code>mod_php</code> <strong>el ataque puede dispararse antes de que se ejecute una sola línea de código de WordPress</strong>, según el propio aviso de PHP. Lo que arregla esto es actualizar PHP, no instalar nada.</p>
<h2>Y hay un tercer fallo todavía sin parche</h2>
<p>El 23 de octubre PHP publicó un aviso informativo sobre otro, el CVE-2026-115560, que describe como una posible ejecución remota de código poco probable. Para que se dé, la aplicación tiene que cambiar en tiempo de ejecución el manejador con el que PHP serializa las sesiones y, además, seguir activo el seguimiento del progreso de subida.</p>
<p>A fecha de hoy no hay versión corregida y la medida es la misma de antes, desactivar <code>session.upload_progress.enabled</code> si tu hosting puede. Que dependa del código de cada aplicación lo hace menos probable, no inexistente, así que conviene aplicar la medida si está a tu alcance y estar atento a la próxima versión de PHP que lo corrija.</p>
<h2>Cuánto hay que preocuparse de verdad</h2>
<p>Que nadie lea esto como un «no pasa nada», porque <strong>es un fallo serio</strong>, con ejecución remota de código y sin iniciar sesión. Pero <strong>los parches existen desde el 21 de octubre</strong> y lo razonable es mirar la versión hoy y escribir a tu hosting, no entrar en pánico.</p>
<p>En cuanto a los ataques reales, <a href="https://watchtowr.com/intelligence/php-cve-2026-109618-faq/" target="_blank" rel="nofollow noopener">watchTowr</a> dice haberlos visto en sus sistemas trampa desde el 21 de octubre y Cloudflare asegura, según <a href="https://bleepingcomputer.com/news/security/php-ships-emergency-patches-for-critical-php2shell-flaws" target="_blank" rel="nofollow noopener">BleepingComputer</a>, que ya notaba ataques antes de los parches, pero ninguna de las dos aporta datos que se puedan comprobar y el equipo de PHP no lo confirma.</p>
<p>El <a href="https://cyber.gc.ca/en/alerts-advisories/al26-026-critical-vulnerabilities-impacting-php-cve-2026-109618-cve-2026-109619" target="_blank" rel="nofollow noopener">Centro Canadiense de Ciberseguridad</a> tampoco ha identificado explotación activa por el momento, aunque avisa de que eso puede cambiar rápido. Y sobre todo desconfía de los titulares que cifran en porcentajes enormes los sitios en peligro, porque el que PHP esté en muchísimos sitios no significa que todos estén sin parche.</p>
<h2>Si sospechas que se te han colado</h2>
<p>Actualiza PHP y revisa después lo que recomienda el aviso canadiense, que son los registros del servidor web y cualquier proceso, archivo, cuenta o conexión saliente inusual. En WordPress eso se traduce en buscar usuarios administradores que no reconoces, archivos PHP nuevos en <code>wp-content/uploads</code> y cambios en <code>wp-config.php</code> o en <code>.htaccess</code>.</p>
<p>Para esa búsqueda te puede ayudar <a href="https://es.wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a>, mi plugin de seguridad gratuito, que compara el núcleo, los plugins y los temas con las copias oficiales, busca PHP en la carpeta de subidas, vigila <code>wp-config.php</code> y <code>.htaccess</code> y guarda un registro de actividad con los cambios en cuentas de usuario.</p>
<p>Además, hace nada incluí la comprobación de tu versión de PHP frente a las conocidas como vulnerables, para que te sea más fácil, o por si no quieres instalar el mini plugin que te he comentado antes, lo que prefieras.</p>
<p><a href="https://ayudawp.com/?attachment_id=160787" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160787 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/aviso-php2shell-plugin-Vigilante-WordPress-1200x141.jpg" alt="" width="1200" height="141" srcset="https://ayudawp.com/wp-content/uploads/2026/10/aviso-php2shell-plugin-Vigilante-WordPress-1200x141.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-php2shell-plugin-Vigilante-WordPress-768x90.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-php2shell-plugin-Vigilante-WordPress-1536x180.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-php2shell-plugin-Vigilante-WordPress.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>También revisa el estado de fin de vida útil de tu versión de PHP, aunque que una rama tenga soporte no significa que ya lleve el parche de estos fallos. Eso sí, <strong>sirve para buscar rastros después, no para evitar el fallo</strong>, que como ya sabes se arregla actualizando PHP.</p>
<p>Mira tu versión hoy y escribe a tu hosting, que es lo que de verdad está en tu mano. Si te contesta algo raro (o no te contesta), me tienes ahí abajo, en la sección de comentarios. Y si quieres repasar lo básico de seguridad, tienes montones de <strong><a href="https://ayudawp.com/categoria/seguridad/">artículos y guías sobre seguridad WordPress</a></strong>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/php2shell/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Los plugins experimentales de WordPress.org deberían avisar de lo que son ¿tienes activo Performance Lab, Speculative Loading, Gutenberg o el plugin oficial IA?</title>
		<link>https://ayudawp.com/plugins-beta-wordpress-org/</link>
					<comments>https://ayudawp.com/plugins-beta-wordpress-org/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 06:28:14 +0000</pubDate>
				<category><![CDATA[Opinión]]></category>
		<category><![CDATA[Plugins WordPress]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Canonical]]></category>
		<category><![CDATA[Gutenberg]]></category>
		<category><![CDATA[Principiante]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160664</guid>

					<description><![CDATA[Échale un vistazo a la lista de plugins de tu web, o a la de tus clientes si te dedicas a esto. Si aparece Performance Lab, Speculative Loading, Modern Image Formats, Gutenberg o el plugin AI, lo que tienes ahí no es un plugin como los de toda la vida, es un experimento oficial de WordPress.org, y casi nada en tu escritorio te lo dice.]]></description>
										<content:encoded><![CDATA[<p>Échale un vistazo a la lista de plugins de tu web, o a la de tus clientes si te dedicas a esto. Si aparece Performance Lab, Speculative Loading, Modern Image Formats, Gutenberg o el plugin AI, <strong>lo que tienes ahí no es un plugin como los de toda la vida, es un experimento oficial de WordPress.org</strong>, y nada en tu escritorio te lo dice.</p>
<p>Te reconozco que esto me tiene bastante molesto. Me los encuentro activos en montones de webs de clientes, funcionando como si fueran un plugin más, a veces incluso cuando lo que hacen ya forma parte de WordPress desde hace tiempo.</p>
<p>Lo mío es casi anecdótico al lado de los números, pues el plugin Speculative Loading tiene más de 70.000 instalaciones activas pero resulta que <strong>la carga especulativa está dentro de WordPress desde la versión 6.8, de abril de 2025 ¿ves el problema?</strong>.</p>
<p>Otros plugins experimentales como Performance Lab y Modern Image Formats pasan de las 100.000 cada uno, Gutenberg de las 400.000, y el plugin AI, que no lleva ni un año en el directorio, ya va por las 60.000.</p>
<p>Que conste que no tengo nada contra estos plugins, de ahí han salido algunas de las mejores cosas que ha estrenado WordPress en los últimos años, lo que no me parece ni medio normal es que no avisen de forma clara, y permanente, de lo que son y de lo que no.</p>
<p>Sigo…</p>
<h2>Plugins que no son plugins</h2>
<p>En WordPress.org se los llama <strong>plugins canónicos</strong>, y la idea es ya antigua, y te hablé de ello en <a href="https://ayudawp.com/plugin-canonicos/" target="_blank" rel="ugc noopener">2009, cuando se propuso</a>, así que no me repetiré.</p>
<p>Luego, en 2022 la recuperó Matt Mullenweg en <a href="https://make.wordpress.org/core/2022/09/11/canonical-plugins-revisited/" target="_blank" rel="nofollow noopener">un artículo en Make WordPress</a>, donde los definía como la recomendación oficial para funciones que no tienen por qué estar en el núcleo, con la puerta abierta a entrar en él si triunfan.</p>
<p>Para complicar aún más las cosas, resulta que hay dos familias grandes de estos plugins, que a veces se suelen confundir, pero que en realidad son bastante distintas.</p>
<p>Por un lado están <strong>los plugins experimentales del equipo de rendimiento</strong>, con Performance Lab como lanzadera, desde el que se instalan los demás y una docena de plugins sueltos (Speculative Loading, Modern Image Formats, Optimization Detective, Image Prioritizer, Enhanced Responsive Images y compañía).</p>
<p>Y luego están los que publica la propia cuenta de WordPress.org, a modo de plugins beta, pero que no siempre lo son tanto, como Gutenberg, el plugin AI o el más reciente MCP Adapter.</p>
<p>Todos tienen algo en común, y es que normalmente <strong>no están pensados para ser un producto acabado sino para probar ideas</strong>, que algunas veces acabarán en WordPress y otras no.</p>
<p>Lo dicen ellos mismos, aunque en letra pequeña:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li><strong>Performance Lab:</strong> sus <a href="https://wordpress.org/plugins/performance-lab/" target="_blank" rel="nofollow noopener">preguntas frecuentes</a> reconocen que <em>«it can mostly be considered a beta testing plugin»</em>, o sea, que viene a ser un plugin para probar cosas en beta, y piden prudencia a quien lo use.</li>
<li><strong>El plugin AI:</strong> su <a href="https://wordpress.org/plugins/ai/" target="_blank" rel="nofollow noopener">readme</a> avisa de que sus experimentos <em>«may change significantly or be removed in any release»</em>, o sea, que pueden cambiar mucho o desaparecer en cualquier versión, y recomienda probarlos antes en una web de pruebas.</li>
<li><strong style="font-size: 16px;">Gutenberg:</strong><span style="font-size: 16px;"> su </span><a style="font-size: 16px; background-color: #ffffff;" href="https://wordpress.org/plugins/gutenberg/" target="_blank" rel="nofollow noopener">readme</a><span style="font-size: 16px;"> lo presenta como un </span><em style="font-size: 16px;">«beta plugin»</em><span style="font-size: 16px;"> para quien quiera probar funciones antes de que salgan. Y en 2021 la propia WordPress.org </span><a style="font-size: 16px; background-color: #ffffff;" href="https://wordpress.org/news/2021/04/become-an-early-adopter-with-the-gutenberg-plugin/" target="_blank" rel="nofollow noopener">publicó</a><span style="font-size: 16px;"> que </span><em style="font-size: 16px;">«it is not recommended to use the plugin on a site that has launched and is actively in use»</em><span style="font-size: 16px;">, es decir, que no lo uses en una web ya publicada y en marcha.</span></li>
</ul>
</li>
</ul>
<h3>Ni WordPress.org se aclara con el nombre</h3>
<p>De verdad es que esto es para mear y no echar gota, pues resulta que en julio de 2025 los responsables del núcleo se reunieron para <a href="https://make.wordpress.org/core/2025/07/10/core-committers-check-in-july-2025/" target="_blank" rel="nofollow noopener">poner orden en los tipos de plugins oficiales</a>. Dejaron por escrito que los <strong><em>feature plugins</em></strong> (plugins que prueban funciones candidatas al núcleo) son exploratorios y de corto plazo, y que los canónicos tienen soporte oficial y un responsable directo.</p>
<p>Pero el equipo de IA <a href="https://make.wordpress.org/ai/2026/10/06/whats-new-in-ai-1-4-0/" target="_blank" rel="nofollow noopener">llama canónico a su plugin AI</a>, que según su propio <code>readme</code> es experimental, y en la práctica todo el mundo usa la palabra para lo mismo.</p>
<p>Así que yo, para entendernos, los voy a seguir llamando canónicos, o directamente experimentos. Me refiero a estos, a los de pruebas, no a plugins oficiales como Classic Editor o el importador de WordPress, que son otra cosa y no tienen nada de experimento.</p>
<p>Y si quien los publica no se aclara con el nombre, el que los instala ni te cuento, va listo.</p>
<h3>¿Por qué digo que son peores que un plugin en beta?</h3>
<p>Pues porque <strong>un plugin en beta <em>normal</em> aspira a ser la versión estable de sí mismo</strong>. Lo instalas sabiendo que puede tener fallos, pero el plan es que algún día deje de tenerlos y siga ahí, a tu servicio.</p>
<p>Un experimento no tiene ese plan, <strong>su objetivo es comprobar si una idea funciona, y acaba en el núcleo, con lo que el plugin sobra, o en la papelera</strong>.</p>
<p>Hay casos intermedios, como Modern Image Formats. En 2022 se decidió <a href="https://make.wordpress.org/core/2022/09/11/webp-in-core-for-6-1/" target="_blank" rel="nofollow noopener">no convertir las imágenes a WebP por defecto en el núcleo</a> y dejar esa función en un plugin, y ahí sigue, en tierra de nadie, pero con más de 100 mil webs con el plugin instalado, un plugin que nadie mantiene, ni vigila, ni actualiza.</p>
<p>Encima llevan el sello de WordPress.org, que da una confianza que no te daría la beta de un desarrollador cualquiera. Si lo firma WordPress algo bueno tendrá, ¿no?</p>
<p>Ahora bien, todo hay que decirlo, <strong>sin estos plugins WordPress habría mejorado bastante más despacio</strong>. El atributo <code>fetchpriority</code> (el que le dice al navegador qué imagen cargar primero) llegó al núcleo en la versión 6.3, el <code>sizes="auto"</code> de las imágenes con carga diferida en la 6.7 y la carga especulativa en la 6.8. Todo eso salió de aquí.</p>
<p>Probar en webs reales es como se mejora WordPress, y quien los instala sabiendo lo que hace le está haciendo un favor a todos. El problema no es ese, sino que la gente los instale(mos) sin saberlo, o no todo lo claro que se debería.</p>
<h2>¿Por qué no te enteras de que tienes un experimento instalado?</h2>
<p>Porque<strong> las advertencias están donde no miras.</strong> Fíjate en el camino que hace cualquiera desde que busca el plugin hasta que lo tiene funcionando:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li style="list-style-type: none;">
<ul>
<li><strong>En la página del directorio de plugins:</strong> la de Performance Lab no lleva ninguna etiqueta de beta ni de experimento. Lo único es un «(experimental)» junto a View Transitions dentro de la descripción, y el aviso de verdad está en las preguntas frecuentes, al final de la página, en esa sección que no lee nadie.</li>
<li><strong>En la sección Beta del directorio:</strong> existe una <a href="https://wordpress.org/plugins/browse/beta/" target="_blank" rel="nofollow noopener">sección Beta</a>, pero es un cajón de sastre. Mete plugins cuyo <code>readme</code> parece el de cualquier otro y deja fuera precisamente los plugins de rendimiento con más instalaciones, como Modern Image Formats, Speculative Loading u Optimization Detective. De esa familia solo aparece Performance Lab.</li>
<li><strong>En el instalador de tu escritorio:</strong> en «Plugins &gt; Añadir plugin» existe una pestaña <strong>Pruebas beta</strong>, pero WordPress solo la enseña si tu versión lleva un guion en el número, es decir, en versiones de desarrollo como una beta o una RC. En una web en producción esa pestaña no aparece nunca.</li>
<li><strong>En la lista de plugins instalados:</strong> lo único que ves es la descripción. La de Performance Lab dice <em>«Performance plugin from the WordPress Performance Team»</em> (que suena más a garantía que a aviso), y las de Speculative Loading o Modern Image Formats no dan ninguna pista. Gutenberg se presenta como <em>«development plugin»</em>, Optimization Detective, Image Prioritizer y Embed Optimizer llevan un «-beta» en el número de versión y, desde la versión 1.5.0, el plugin AI avisa en la suya de que sus experimentos pueden cambiar o desaparecer.</li>
<li><strong>Dentro del propio plugin:</strong> en los de rendimiento, quitando el «(experimental)» de View Transitions en la pantalla de Performance Lab, no hay nada que te avise. El plugin AI ha empezado a hacerlo en su versión 1.5.0, y más abajo te cuento cómo.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><a href="https://ayudawp.com/?attachment_id=160671" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160671 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/plugins-canonical-1200x675.jpg" alt="" width="1200" height="675" srcset="https://ayudawp.com/wp-content/uploads/2026/10/plugins-canonical-1200x675.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/plugins-canonical-768x432.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/plugins-canonical-1536x864.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/plugins-canonical.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a><br>
Y lo saben sus equipos, no es algo que se les haya pasado. En abril de 2025, en otra de esas reuniones de los responsables del núcleo, <a href="https://make.wordpress.org/core/2025/04/04/dotorg-core-committers-check-in/" target="_blank" rel="nofollow noopener">quedó escrito</a> que <em>«It’s often not widely known that canonical plugins exist or that they are officially maintained»</em> (poca gente sabe que existen o que son oficiales).</p>
<p>También que <em>«Feedback is mainly received from users when something breaks»</em>, o sea, que las opiniones de los usuarios les llegan sobre todo cuando algo se rompe.</p>
<p>Su conclusión entonces fue que <strong>había que promocionarlos más</strong>, y en julio se pusieron como siguiente paso redactar los criterios para clasificar los plugins oficiales en canónicos, de funciones, experimentales y de soporte. Quince meses después, que yo sepa, esos criterios siguen sin publicarse.</p>
<p>Promocionarlos me parece bien, pero <strong>promocionarlos sin etiquetarlos adecuadamente es justo lo que nos ha traído hasta aquí</strong>.</p>
<h2>Lo que te puede pasar con uno de estos plugins activo</h2>
<p>No quiero meterte miedo, que la mayoría hace lo que promete y hay muchas webs usándolos sin problemas. Pero conviene que sepas qué estás aceptando, porque no es algo trivial, en muchas ocasiones es incluso perjudicial usar estos plugins si no tienes 100% claro lo que supone.</p>
<h3>Te cambian la web nada más activarlos</h3>
<p>Modern Image Formats es el ejemplo más claro. Con la configuración por defecto <strong>cada imagen que subas a partir de ese momento se guarda en WebP o AVIF</strong> (formatos de imagen modernos que pesan menos), en todos sus tamaños, incluida la versión principal que usa WordPress. El JPEG o PNG que subiste se conserva como original, pero WordPress deja de usarlo.</p>
<p>Y ojo, porque <strong>desactivarlo o desinstalarlo no deshace nada</strong>. Las imágenes que subiste con el plugin activo se quedan en WebP o AVIF y WordPress las sigue sirviendo así. No se rompe nada, los navegadores actuales las leen sin problema, pero no es un cambio que quites con un clic.</p>
<p>En la versión 1.5.0 del plugin AI hay un caso curioso. El experimento MCP Access, al activarlo, <strong>te instala y activa otro plugin experimental, MCP Adapter, directamente desde WordPress.org</strong>, y deja que los agentes de IA autorizados usen por defecto las funciones del plugin que tengas activas. Lo dice en su descripción, eso sí, pero es un experimento que te instala otro experimento.</p>
<p>Speculative Loading es otro de los puñeteros, especialmente. La <a href="https://ayudawp.com/carga-especulativa-nativa/" target="_blank" rel="ugc noopener">carga especulativa nativa de WordPress</a> solo hace <em>prefetch</em> (descargar por adelantado el HTML de la página a la que seguramente vas a ir) y de forma prudente, cuando ya estás pulsando el enlace. El plugin, en cambio, hace <em>prerender</em> por defecto, que es cargar la página entera en segundo plano, con sus scripts y todo, en cuanto pasas el ratón por encima.</p>
<p>Es más rápido, pero tiene su precio. En 2024 el plugin hizo que en tiendas WooCommerce <a href="https://github.com/WordPress/performance/issues/1140" target="_blank" rel="nofollow noopener">se añadieran productos al carrito solo con pasar el ratón por encima</a>, sin hacer clic. Lo corrigieron rápido, eso sí, pero sigue abierta otra incidencia en la que <a href="https://github.com/WordPress/performance/issues/1774" target="_blank" rel="nofollow noopener">el carrito y la página de pago, precargados, muestran datos del pedido desfasados</a>.</p>
<h3>Cambian las reglas sin avisar, o desaparecen</h3>
<p>El plugin AI lo deja claro en su <a href="https://github.com/WordPress/ai/blob/develop/docs/FEATURE_EXPERIMENT_LIFECYCLE.md" target="_blank" rel="nofollow noopener">documentación sobre el ciclo de vida de sus experimentos</a>, donde dice que están <em>«subject to breaking changes or removal without notice»</em>, <strong>expuestos a cambios que rompen cosas o a desaparecer sin previo aviso</strong>. Se comprometen a intentar que esos cambios lleguen en versiones mayores, que algo es.</p>
<p>Lo de las versiones mayores, eso sí, es más una intención que una norma. La 1.5.0, que es una versión menor, ha cambiado de forma incompatible tres de las <em>abilities</em> del plugin (las acciones que deja usar a otras herramientas de IA) y ha dejado de servir la dirección <code>/feed/markdown/</code> de cada entrada, que ahora da un error 404. Lo explican en el registro de cambios, y lo justifican porque tenían que igualarse con lo que llega al núcleo, pero el registro de cambios es otra de esas cosas que no lee nadie.</p>
<p>Un ejemplo reciente. En la versión 1.4.0, por un cambio en Gutenberg, <strong>las directrices editoriales que tuvieras guardadas para la IA hay que volver a meterlas a mano</strong>, porque no se migran. Dos experimentos encadenados, y el que paga el pato eres tú.</p>
<p>Luego está lo de desaparecer. Web Worker Offloading, otro plugin del equipo de rendimiento con más de 10.000 instalaciones, avisa en su <a href="https://wordpress.org/plugins/web-worker-offloading/" target="_blank" rel="nofollow noopener">readme</a> de que es experimental y de que está <em>«intended to be sunset»</em>, en vías de retirada. Al menos lo dicen, aunque <strong>solo se entera quien se lee el <code>readme</code></strong>.</p>
<p>Que un plugin normal cambie las reglas o se abandone es un accidente, <strong>en un experimento cambiar o desaparecer entra dentro del plan, es lo esperado, salvo por el detalle de que no siempre te informa como debería.</strong></p>
<h3>Duplican o pisan a tus otros plugins</h3>
<p>El plugin AI, por ejemplo, tiene un experimento que genera con IA la <code>meta description</code> de tus entradas. Si detecta Yoast, Rank Math, All in One SEO o SEOPress, la guarda en el campo de ese plugin y no imprime nada por su cuenta, que está bien.</p>
<p>Pero si usas otro plugin de SEO, como The SEO Framework o Slim SEO, el plugin AI imprime su propia <code>meta description</code> y esa entrada sale con dos. Pasa solo si activas el experimento y aplicas una descripción generada, pero pasa, y <a href="https://ayudawp.com/meta-description-automatica/" target="_blank" rel="ugc noopener">tener dos <code>meta description</code> en la misma página no es nunca buena idea</a>.</p>
<p>Tiene arreglo, eso sí, aunque está en manos del desarrollador de tu plugin de SEO. El plugin AI incluye un filtro, <code>wpai_meta_description_seo_plugins</code>, con el que cualquier plugin de SEO puede apuntarse a esa lista, y a partir de ese momento la descripción generada se guarda en su campo y no se duplica.</p>
<p>Es lo que he hecho yo con <a href="https://visibility.quest/" target="_blank" rel="nofollow noopener">Visibility</a>, y son unas pocas líneas de código, así que si tu plugin de SEO no está entre los cuatro de antes, pídeselo a quien lo desarrolla.</p>
<p>Con los plugins de rendimiento pasa algo parecido. Image Prioritizer decide qué imágenes cargar primero y cuáles retrasar, igual que hacen muchos plugins de optimización, y ya te conté en el artículo sobre <a href="https://ayudawp.com/image-prioritizer/" target="_blank" rel="ugc noopener">por qué WordPress todavía no acierta con el LCP</a> cómo <strong>pueden pisarse entre ellos</strong>.</p>
<h3>Tienen un coste aunque no los uses</h3>
<p>Hasta la versión 1.4.0 del plugin AI, cada función que no habías activado nunca <a href="https://github.com/WordPress/ai/issues/1112" target="_blank" rel="nofollow noopener">costaba una consulta a la base de datos en cada visita</a>, también en la parte pública, en webs sin caché de objetos persistente (tipo Redis o Memcached). Lo he medido en una instalación de pruebas con WordPress 7.1.3, sin caché de objetos y sin ningún experimento activado: <strong>sin el plugin, cada carga hacía 8 consultas; con la 1.4.0, 38</strong>.</p>
<p>En la 1.5.0 lo han arreglado, y bien, porque se quedan en 9. Aun así, es un buen ejemplo de que <strong>tener un experimento activo sin usarlo no sale gratis</strong>, y de paso te deja dos widgets en el escritorio.</p>
<p>Y ojo, porque hasta la 1.4.0 su propia FAQ aseguraba que sus funciones <em>«require manual triggering – nothing happens automatically without your approval»</em>, o sea, que solo se ponían en marcha si tú lo pedías. Activar un experimento ya es aprobarlo, vale, pero <strong>la moderación de comentarios analiza cada comentario nuevo que no esté ya marcado como spam, también los de visitantes sin registrar</strong>, y cada uno viaja a tu proveedor de IA y puede costarte tokens.</p>
<p>Todo hay que decirlo, a raíz de <a href="https://github.com/WordPress/ai/issues/1166" target="_blank" rel="nofollow noopener">la incidencia que abrí</a> lo corrigieron en la 1.5.0, y la FAQ avisa ahora de que esa moderación hace una petición por cada comentario nuevo, incluido el spam que se le escape a tu antispam.</p>
<p>Todo hay que decirlo, a raíz de <a href="https://github.com/WordPress/ai/issues/1166" target="_blank" rel="nofollow noopener">la incidencia que abrí</a> lo han corregido para la versión 1.5.0, que mientras escribo esto todavía no ha salido: la FAQ avisa de que esa moderación hace una petición por cada comentario nuevo, y en los ajustes los experimentos que se ejecutan solos llevan su propia etiqueta.</p>
<p>Optimization Detective funciona con datos de tus visitantes reales. Para eso necesita la API REST de tu web abierta a cualquiera, y los navegadores de tus visitas le envían métricas que se guardan en tu base de datos. Tiene sus límites (una petición por minuto por IP, y borra lo que tiene más de tres meses), pero son escrituras en tu base de datos que antes no tenías.</p>
<p>Como ves, <strong>no son algo que no afecte a tu web, sí pasa algo si los dejas ahí</strong>.</p>
<h3>Gutenberg, el <em>experimento</em> con más instalaciones</h3>
<p>El plugin Gutenberg es el abuelo de todos, con más de 400.000 instalaciones activas. Su propio <code>readme</code> te explica que <strong>no te hace falta para usar el editor de bloques</strong>, porque cada versión de WordPress ya incluye lo que está listo, y que solo lo necesitas si quieres las funciones en beta sin esperar a WordPress, pero <strong>a riesgo de que luego algo no llegue o llegue diferente</strong>.</p>
<p>En noviembre de 2022 pasó lo que tenía que pasar. Las webs con una versión antigua del plugin que se actualizaron solas a WordPress 6.1 <a href="https://core.trac.wordpress.org/ticket/56985" target="_blank" rel="nofollow noopener">se quedaron con un error fatal</a>, sin acceso ni a la portada ni al escritorio. La solución pasó por que WordPress desactive al actualizarse las versiones de Gutenberg que se han quedado demasiado viejas, que algo hemos ganado.</p>
<h2>Cuando su funcionalidad llega a WordPress el plugin sigue ahí</h2>
<p>Esto es lo más delicado, cuando una funcionalidad llega al núcleo de tu WordPress, el plugin que la probaba sigue activo en miles de webs, como un zombi, y como mucho deja una notita en el readme.</p>
<p><strong>Lo más triste es que antes se hacía bien.</strong> WP Auto-Updates y Plugin Dependencies, dos plugins de funciones que acabaron en WordPress 5.6 y 6.5, se desactivaban solos al detectar que su función ya estaba en el núcleo.</p>
<p>Better Code Editing mostraba un aviso en el escritorio diciendo, literal, que su función ya estaba en el núcleo y que se podía desactivar y desinstalar.</p>
<p>Y el propio equipo de rendimiento lo hizo bien con Fetchpriority: en cuanto su función entró en WordPress 6.3, el plugin <a href="https://github.com/WordPress/performance/pull/769" target="_blank" rel="nofollow noopener">mostraba un aviso</a> pidiendo que lo desactivaras, y en junio de 2024 lo cerraron.</p>
<p>Hasta el propio <a href="https://make.wordpress.org/core/handbook/about/release-cycle/features-as-plugins/" target="_blank" rel="nofollow noopener">manual del núcleo sobre plugins de funciones</a> pide que el plugin deje de hacer nada en cuanto su funcionalidad entra en WordPress.</p>
<p>Ahora mira lo que pasa hoy con los del equipo de rendimiento:</p>
<ul>
<li><strong>Speculative Loading:</strong> su readme reconoce que la carga especulativa entró en WordPress 6.8, pero el plugin sigue activo en más de 70.000 instalaciones sin avisar de nada, y encima sustituye la configuración prudente del núcleo por la suya, más agresiva.</li>
<li><strong>Enhanced Responsive Images:</strong> lo de <code>sizes="auto"</code> entró en WordPress 6.7, y lo único que sigue aportando el plugin, según su propio readme, no está disponible para temas clásicos. Tiene más de 50.000 instalaciones, y en cualquier web con tema clásico no hace nada.</li>
<li><strong>Performant Translations:</strong> su readme avisa de que casi todo entró en WordPress 6.5 y de que <em>«You might not need it anymore»</em>. Es verdad que sigue sirviendo para traducciones que no vienen de WordPress.org, pero el aviso está donde no lo lee ni el tato.</li>
</ul>
<p>Yo mismo, con un plugin mío bastante más modesto, saqué una última actualización con un aviso antes de cerrarlo, para que nadie se quedara con un plugin muerto sin enterarse.</p>
<p>Si lo hace un desarrollador cualquiera como yo, el equipo oficial de WordPress también puede. <strong>Dejar zombis repartidos por miles de webs me parece mala política</strong>, y no hay más.</p>
<h2>Si lo que cuenta es la adopción, que al menos sea informada</h2>
<p>Hay un detalle que me parece importante, y es que en la <a href="https://make.wordpress.org/core/2026/09/18/roadmap-to-7-2/" target="_blank" rel="nofollow noopener">hoja de ruta de WordPress 7.2</a> se dice que las funciones de IA tienen que demostrar <em>«clear adoption and practical value»</em> antes de plantearse para el núcleo, y se anima a la gente a usar y probar el plugin AI.</p>
<p>En aquella reunión de abril de 2025 reconocían que las instalaciones activas son <em>«currently the only metric available»</em>, la única métrica que tienen.</p>
<p>No digo que nadie esté inflando nada a propósito, ni mucho menos, pero si las instalaciones cuentan como prueba de que algo funciona, <strong>60.000 instalaciones de un plugin experimental no son 60.000 personas probando algo a sabiendas</strong>.</p>
<blockquote><p>Si las instalaciones activas son la prueba de que un experimento funciona, lo mínimo es que quien lo instala sepa que está participando en una prueba.</p></blockquote>
<h2>Mi propuesta, que no es para volverse loco</h2>
<p>No pido que dejen de hacer estos plugins, ni que dejen de promocionarlos, que son más que útiles, solo <strong>pido que sean explícitos</strong>, y lo concreto en seis cosas:</p>
<ol>
<li><strong>Una etiqueta visible en el directorio:</strong> en la ficha de cada plugin, arriba y a la vista, no escondida en las preguntas frecuentes, y también en los resultados del instalador, no solo en una pestaña que en producción no existe.</li>
<li><strong>Que lo digan el nombre y la descripción del plugin:</strong> «(beta)» en el nombre y, en la descripción de la lista de plugins y en la del directorio, qué añade a lo que ya trae WordPress. Sin avisos en el escritorio, que de esos ya vamos sobrados, y a la vista de todo el mundo, también antes de instalarlo.</li>
<li><strong>Una explicación al activarlo:</strong> qué es, para qué sirve probarlo y qué riesgos tiene usarlo en una web en producción.</li>
<li><strong>Etiquetas distintas para cosas distintas:</strong> no es lo mismo un experimento que una función candidata al núcleo o un plugin oficial estable, y hoy todo cabe en el mismo cajón de «Beta».</li>
<li><strong>Avisar y apartarse cuando su función entra en el núcleo:</strong> como hacían los plugins de funciones antiguos y como pide el propio manual.</li>
<li><strong>Publicar los criterios prometidos en julio de 2025:</strong> los de clasificación de los plugins oficiales, que siguen sin aparecer.</li>
</ol>
<p>Lo bueno es que <strong>los puntos 2, 3 y 5 no necesitan tocar el núcleo de WordPress</strong>, los puede hacer hoy mismo cada equipo en sus propios plugins. De hecho el equipo de rendimiento ya marca como experimentales algunos de sus plugins, pero solo dentro de la pantalla de Performance Lab, donde View Transitions sale con su «(experimental)». Se trata de llevar esa etiqueta al propio plugin.</p>
<p>He abierto <a href="https://github.com/WordPress/performance/issues/2709" target="_blank" rel="nofollow noopener">una incidencia en el GitHub del equipo de rendimiento</a> con esta propuesta, y <a href="https://github.com/WordPress/ai/issues/1166" target="_blank" rel="nofollow noopener">otra en el del plugin AI</a>, donde además pedía que cada experimento dijera si se ejecuta solo, qué envía al proveedor de IA y cuántas peticiones hace.</p>
<p><strong>El equipo del plugin AI se lo tomó en serio y en dos semanas estaba hecho.</strong> En la versión 1.5.0, que salió el 29 de octubre, la descripción de la lista de plugins ya avisa de lo que es, los experimentos que se ejecutan solos llevan una etiqueta en los ajustes y cada uno tiene un icono que te cuenta cuándo se ejecuta, qué envía y cuántas peticiones hace. Y sin meter ni uno de esos avisos que salen arriba en todas las pantallas.</p>
<p>En el equipo de rendimiento la cosa va más despacio. Están abiertos a dejar más claro qué aporta cada plugin además de lo que ya trae WordPress, a uno de sus miembros no le convencen los avisos en el escritorio (y razón no le falta, que hay demasiados) y está sobre la mesa añadir «(beta)» al nombre de los plugins.</p>
<p>Si estás de acuerdo, pásate por la incidencia y deja tu comentario, que un caso real bien explicado vale más que un pulgar hacia arriba.</p>
<h2>Mientras tanto, revisa tu web (o las de tus clientes)</h2>
<p><strong>Hasta que cambie algo te toca a ti.</strong> Para reconocerlos fíjate en estas señales:</p>
<ul>
<li>En el directorio el autor es «WordPress Performance Team» o «WordPress.org».</li>
<li>El número de versión lleva «-beta».</li>
<li>Las preguntas frecuentes o el readme hablan de beta, de experimento o de probarlo antes en una web de pruebas.</li>
<li>Aparece en la sección Beta del directorio, aunque ya has visto que no están todos.</li>
</ul>
<p>Esto es lo que yo haría con los más habituales:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li><strong>Speculative Loading:</strong> si tienes WordPress 6.8 o posterior, tu web ya precarga páginas sin el plugin. Quédatelo solo si quieres su modo más agresivo o poder cambiar la configuración desde <strong>Ajustes &gt; Lectura</strong> (WordPress no trae esos ajustes), y lo has probado bien, sobre todo si tienes tienda. Y si prefieres quitar también la nativa, te lo cuento en <a href="https://ayudawp.com/desactivar-carga-especulativa-wordpress/" target="_blank" rel="ugc noopener">cómo desactivar la carga especulativa de WordPress</a>.</li>
<li><strong>Enhanced Responsive Images:</strong> si tu tema es clásico, desactívalo, porque lo que añade no funciona con temas clásicos. Con un tema de bloques, decide si te compensa.</li>
<li><strong>Performant Translations:</strong> solo tiene sentido si usas plugins o temas con traducciones que no vienen de WordPress.org.</li>
<li><strong>Modern Image Formats:</strong> si lo quieres, que sea sabiendo que convierte tus imágenes a partir de ese momento y que quitarlo no lo deshace.</li>
<li><strong>Optimization Detective, Image Prioritizer y Embed Optimizer:</strong> llevan la beta en el número de versión, así que trátalos como tal.</li>
<li><strong>El plugin AI:</strong> actualízalo a la 1.5.0, que además <a href="https://github.com/WordPress/ai/security/advisories" target="_blank" rel="nofollow noopener">corrige dos vulnerabilidades</a> de gravedad media que solo puede aprovechar alguien con cuenta en tu web y rol de colaborador o superior. Y si lo usas en producción, revisa qué experimentos tienes activos en «<strong>Ajustes &gt; IA</strong>» y fíjate en los que se ejecutan solos.</li>
<li><strong>Gutenberg:</strong> si no desarrollas ni pruebas funciones nuevas, no lo necesitas, que el editor ya viene con WordPress.</li>
</ul>
</li>
</ul>
<p>Si <strong>quieres que tu escritorio te diga lo que WordPress.org no te dice</strong>, aquí tienes un fragmento de código que <strong>añade una nota debajo de cada uno de estos plugins</strong> en la lista de plugins instalados. Si además su función, o parte de ella, ya está en tu versión de WordPress, añade una segunda nota que te lo avisa:</p>
<pre>/**
 * Etiqueta plugins de prueba de WordPress.org (canonical, feature o experimentales) en la pantalla de plugins
 *
 * Añade una etiqueta roja bajo cada plugin de la lista, y cuando su funcionalidad ya es
 * parte del núcleo de WordPress, y una segunda ficha te avisa también de esto
 */

/**
 * Lista de plugins de pruebas de WordPress.org, anotados por su carpeta de plugin
 * Añade más al array si sale alguno nuevo
 *
 * 'core' es una función o clase que solo existe cuando la funcionalidad (o parte
 * de ella) ya está en el core. 'note' es el texto mostrado en su caso
 *
 * @return array
 */
function ayudawp_test_plugins() {
	$plugins = array(
		'gutenberg'               =&gt; array(),
		'performance-lab'         =&gt; array(),
		'webp-uploads'            =&gt; array(),
		'speculation-rules'       =&gt; array(
			'core' =&gt; 'wp_get_speculation_rules_configuration',
			'note' =&gt; 'Ya está en tu WordPress, y este plugin cambia su configuración',
		),
		'optimization-detective'  =&gt; array(),
		'image-prioritizer'       =&gt; array(),
		'embed-optimizer'         =&gt; array(),
		'dominant-color-images'   =&gt; array(),
		'auto-sizes'              =&gt; array(
			'core' =&gt; 'wp_sizes_attribute_includes_valid_auto',
			'note' =&gt; 'Parte ya está en tu WordPress, el resto solo sirve con temas de bloques',
		),
		'view-transitions'        =&gt; array(),
		'web-worker-offloading'   =&gt; array(),
		'nocache-bfcache'         =&gt; array(),
		'performant-translations' =&gt; array(
			'core' =&gt; 'WP_Translation_Controller',
			'note' =&gt; 'Casi todo ya está en tu WordPress',
		),
		'ai'                      =&gt; array(),
		'mcp-adapter'             =&gt; array(),
	);

	return apply_filters( 'ayudawp_test_plugins', $plugins );
}

/**
 * Añade las etiquetas a la fila de datos del plugin
 *
 * @param array  $meta        Datos meta en la ficha de plugins
 * @param string $plugin_file Archivo del plugin relativo al directorio de plugins
 * @return array
 */
function ayudawp_flag_test_plugins( $meta, $plugin_file ) {
	$plugins = ayudawp_test_plugins();
	$folder  = dirname( $plugin_file );

	if ( ! isset( $plugins[ $folder ] ) ) {
		return $meta;
	}

	$meta[] = '&lt;span class="ayudawp-badge ayudawp-badge-test"&gt;' . esc_html( 'Plugin de pruebas de WordPress.org' ) . '&lt;/span&gt;';

	$plugin = $plugins[ $folder ];
	if ( ! empty( $plugin['core'] ) &amp;&amp; ( function_exists( $plugin['core'] ) || class_exists( $plugin['core'], false ) ) ) {
		$meta[] = '&lt;span class="ayudawp-badge ayudawp-badge-core"&gt;' . esc_html( $plugin['note'] ) . '&lt;/span&gt;';
	}

	return $meta;
}
add_filter( 'plugin_row_meta', 'ayudawp_flag_test_plugins', 10, 2 );

/**
 * Estilos de las etiquetas para que se vean bien
 *
 * @param string $hook_suffix Current admin page.
 */
function ayudawp_test_plugins_styles( $hook_suffix ) {
	if ( 'plugins.php' !== $hook_suffix ) {
		return;
	}

	wp_register_style( 'ayudawp-test-plugins', false, array(), '1.0' );
	wp_enqueue_style( 'ayudawp-test-plugins' );
	wp_add_inline_style(
		'ayudawp-test-plugins',
		'.ayudawp-badge{display:inline-block;padding:2px 10px;border-radius:999px;color:#fff;font-size:12px;font-weight:600;line-height:1.6;}
		.ayudawp-badge-test{background:#b32d2e;}
		.ayudawp-badge-core{background:#8a4b00;}'
	);
}
add_action( 'admin_enqueue_scripts', 'ayudawp_test_plugins_styles' );</pre>
<p>Si no sabes muy bien dónde pegarlo, lo tienes explicado en <a href="https://ayudawp.com/functions-plugin-mu-snippets/" target="_blank" rel="ugc noopener">¿Plugin, functions.php, plugin de snippets o mu plugin? ¿dónde meto ese código en WordPress?</a>.</p>
<p><a href="https://ayudawp.com/?attachment_id=160670" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160670 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/aviso-plugins-canonical-1200x675.jpg" alt="" width="1200" height="675" srcset="https://ayudawp.com/wp-content/uploads/2026/10/aviso-plugins-canonical-1200x675.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-plugins-canonical-768x432.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-plugins-canonical-1536x864.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/aviso-plugins-canonical.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>La lista va escrita a mano, así que si sale un plugin nuevo de este tipo puedes añadirlo con el filtro <code>ayudawp_test_plugins</code>, por ejemplo:</p>
<pre>add_filter( 'ayudawp_test_plugins', function ( $plugins ) {
	$plugins['carpeta-del-plugin'] = array();
	return $plugins;
} );</pre>
<p>Por cierto, si lo que te preocupa es que alguno de los plugins que usas se cierre en el directorio y te quedes sin actualizaciones sin enterarte, de eso ya te avisa <a href="https://vigilante.works/es/" target="_blank" rel="nofollow noopener">Vigilante</a>, mi plugin de seguridad, más majo él.</p>
<h2>La decisión, como siempre, es tuya</h2>
<p>Probar está bien, y alguien tiene que hacerlo, pero <strong>lo que no tiene sentido es tener un experimento en producción sin saberlo</strong>, y menos aún cuando ya ni siquiera hace falta.</p>
<p>Revisa lo que tienes, decide con datos y, si estás de acuerdo con la propuesta, échale una mano en la incidencia. Y si no estás de acuerdo, si me he dejado algún plugin en el tintero, me tienes ahí abajo, en la sección de comentarios.</p>
<p>Ojalá dentro de un tiempo este artículo deje de tener sentido. Con el plugin AI ya ha empezado a pasar.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/plugins-beta-wordpress-org/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Error: You do not have permission to manage plugins</title>
		<link>https://ayudawp.com/error-you-do-not-have-permission-to-manage-plugins/</link>
					<comments>https://ayudawp.com/error-you-do-not-have-permission-to-manage-plugins/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 21 Oct 2026 06:28:03 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[wp-config.php]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160652</guid>

					<description><![CDATA[Si cada vez que entras en una pantalla del escritorio de WordPress te salta una ventana del navegador con el mensaje «Error: You do not have permission to manage plugins», bienvenido a este (molesto) club.]]></description>
										<content:encoded><![CDATA[<p>Si <strong>cada vez que entras en una pantalla del escritorio de WordPress</strong> te salta una ventana del navegador con el mensaje «<strong>Error: You do not have permission to manage plugins</strong>», bienvenido a este (molesto) club de sufridores.</p>
<p>Aceptas, pasas a la siguiente pantalla y vuelta a empezar, aunque seas administrador y la web te deje hacer todo lo demás.</p>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160659 size-full" src="https://ayudawp.com/wp-content/uploads/2026/10/you-dont-have-permissions-to-manage-plugins.jpg" alt="" width="1200" height="193" srcset="https://ayudawp.com/wp-content/uploads/2026/10/you-dont-have-permissions-to-manage-plugins.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/you-dont-have-permissions-to-manage-plugins-768x124.jpg 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></p>
<p><strong>La culpa no es tuya ni de WordPress, es casi seguro del tema</strong>, que carga en todo el escritorio <strong>un script que comprueba si puedes instalar plugins</strong> y, si no puedes, te lo suelta en un aviso. Y sí, aun siendo administrador hay situaciones en las que WordPress no te deja instalar plugins.</p>
<p>Me lo encontré hace poco en la web de <a href="https://mantenimiento.ayudawp.com/" target="_blank" rel="noopener">un cliente del servicio de mantenimiento</a>, y te reconozco que al principio no le veía ningún sentido, porque yo tenía permisos completos y podía entrar en todas partes.</p>
<p>Vamos <strong>a ver de dónde sale y cómo quitártelo de encima</strong> sin romper nada.</p>
<h2>De dónde sale el aviso (y por qué no es de WordPress)</h2>
<p>La primera pista está en el propio mensaje, que sale en inglés en un escritorio en español. Los mensajes de permisos del núcleo llegan traducidos («Lo siento, no tienes permisos…» y así), por lo que que <strong>si ves un error de permisos en inglés en un WordPress en español, lo más probable es que venga de un tema o de un plugin</strong>.</p>
<p>En el caso que me tocó era el tema, que hace esto en cada pantalla del escritorio:</p>
<ol>
<li>Carga un archivo JavaScript, <code>plugin-installer.js</code>, en todas las pantallas de administración y no solo en las suyas.</li>
<li>Al cargar la página ese script pregunta por AJAX (una petición en segundo plano a <code>admin-ajax.php</code>) si está instalado el plugin complementario del tema.</li>
<li>Antes de contestar, el código del servidor comprueba si el usuario puede instalar plugins. Si no puede, devuelve el error y el script te lo enseña con un <code>alert()</code>, esa ventana del navegador que no te deja hacer nada hasta que pulsas Aceptar.</li>
</ol>
<p>¿Y por qué te lo pregunta a ti, que solo has entrado a editar una página? Pues porque <strong>el script no mira dónde estás ni qué vas a hacer, salta en todas partes y con todo el mundo</strong>.</p>
<p>Fíjate además en un detalle, porque <strong>el mensaje dice «manage» (gestionar), pero lo que se comprueba es si puedes instalar plugins</strong>, que no es lo mismo, y ahí está la clave de todo esto.</p>
<h2>Si soy administrador, ¿por qué no puedo instalar plugins?</h2>
<p>Esto tiene su gracia, o no, bueno, mola, eso seguro. Gestionar plugins (activarlos y desactivarlos) e instalarlos son permisos distintos, y <strong>hay situaciones en las que WordPress te quita el de instalar aunque tengas el perfil más alto</strong>.</p>
<p>WordPress no decide los permisos solo mirando el perfil. El perfil de administrador incluye la capacidad <code>install_plugins</code>, pero cuando un código pregunta <code>current_user_can( 'install_plugins' )</code> la respuesta pasa antes por la función <code>map_meta_cap()</code>, que tiene en cuenta el contexto.</p>
<p>Y si en el <code>wp-config.php</code> está definida la constante <a href="https://ayudawp.com/no-puedo-instalar-plugins/" target="_blank" rel="noopener"><code>DISALLOW_FILE_MODS</code></a> a <code>true</code>, la respuesta es que no, para todo el mundo, administradores incluidos.</p>
<p>Esa constante <strong>bloquea cualquier cambio de archivos desde el escritorio, o sea, instalar, actualizar o borrar plugins y temas, actualizar el núcleo y usar el editor de archivos</strong>, genial ¿no?. Con ella activa sigues pudiendo activar y desactivar plugins desde el menú de plugins, pero desaparece «Añadir nuevo plugin».</p>
<p>En mi caso la había activado ManageWP, pero puede venir del hosting, de un plugin de seguridad o de alguien que la puso a mano en el <code>wp-config.php</code>.</p>
<p>Y que conste que <strong><code>DISALLOW_FILE_MODS</code> es una buena medida de seguridad</strong>, porque si alguien consigue entrar en tu escritorio no puede instalarte un plugin con una puerta trasera ni meter código en un archivo del tema. El precio es que las actualizaciones tienes que hacerlas por otra vía, y quien la activa suele tenerlo resuelto.</p>
<p>Hay dos casos más en los que vas a ver el aviso sin que haya constante de por medio:</p>
<ul>
<li><strong>Usuarios que no son administradores</strong>: editores, autores o gestores de tienda no pueden instalar plugins, así que les sale en cada pantalla.</li>
<li><strong>Multisitio</strong>: en una red solo el superadmin puede instalar plugins, así que los administradores de cada sitio también lo sufren.</li>
</ul>
<h2>Cómo saber si te pasa</h2>
<p>Antes de tocar nada compruébalo, que es un momento:</p>
<ul>
<li><strong>El menú «Plugins»</strong>: si no te aparece «Añadir nuevo plugin», no tienes permiso para instalar.</li>
<li><strong>La petición que lo dispara</strong>: abre las herramientas para desarrolladores del navegador (F12 en casi todos), ve a la pestaña Red, filtra por <code>admin-ajax</code> y recarga la página. Si ves una petición cuya acción termina en <code>_check_plugin_status</code> (o algo parecido) y su respuesta trae el mensaje, ya tienes al culpable, y en la columna Iniciador verás qué script la ha lanzado.</li>
<li><strong>WP-CLI</strong>: si lo usas (sí, esa herramienta que no usa ni el tato y que en estos casos te ahorra un buen rato, y así de paso me salió un pareado), ejecuta el comando que tienes justo debajo con tu usuario.</li>
</ul>
<pre>wp eval 'var_dump( defined( "DISALLOW_FILE_MODS" ) &amp;&amp; DISALLOW_FILE_MODS, current_user_can( "install_plugins" ) );' --user=tu_usuario</pre>
<p>Si te devuelve <code>bool(true)</code> y <code>bool(false)</code>, la constante está activa y tu usuario no puede instalar plugins. Caso cerrado. Si quieres sacarle más partido a la línea de comandos, tienes <a href="https://ayudawp.com/wp-cli-la-interfaz-de-comandos-de-wordpress-guia-de-uso/" target="_blank" rel="noopener">mi tutorial de WP-CLI</a>.</p>
<h2>Lo que no deberías hacer</h2>
<p>Hay <strong>tres formas rápidas de quitarte el aviso</strong> de encima, pero ninguna es buena idea:</p>
<ul>
<li><strong>Quitar la constante</strong>: el aviso desaparece, sí, pero cambias seguridad por comodidad. Es peor el remedio que la enfermedad.</li>
<li><strong>Dar permiso para instalar plugins a editores y compañía</strong>: con un plugin de gestión de perfiles se puede, y lo he visto recomendar en algún foro de soporte, pero es abrir la puerta de par en par para dejar de oír el timbre.</li>
<li><strong>Editar el <code>functions.php</code> del tema</strong>: funciona hasta la siguiente actualización del tema, que te lo deja como estaba.</li>
</ul>
<blockquote><p>Si la constante está ahí por seguridad, lo que sobra es el aviso, no la constante.</p></blockquote>
<h2>La solución es quitar lo que realmente sobra, esa birria de script</h2>
<p><strong>Lo limpio es que el script del tema no se cargue cuando el usuario no puede instalar plugins</strong>, y no pierdes nada, porque el botón del tema para instalar su plugin tampoco te iba a funcionar.</p>
<p>Lo hago con un mu-plugin (<em>must-use plugin</em>, un plugin que WordPress carga siempre y que no se puede desactivar desde el escritorio, <a href="https://ayudawp.com/que-son-los-mu-plugins-de-wordpress/" target="_blank" rel="noopener">como te explico aquí</a>). Así <strong>no depende del tema, sobrevive a sus actualizaciones y nadie lo desactiva por error</strong>.</p>
<ol>
<li>Entra en la carpeta <code>wp-content</code> por FTP, por SSH o con el administrador de archivos del hosting.</li>
<li>Si no existe la carpeta <code>mu-plugins</code>, créala.</li>
<li>Crea dentro un archivo PHP, por ejemplo <code>silenciar-instalador-tema.php</code>, con el código que tienes a continuación.</li>
</ol>
<pre>&lt;?php
/**
 * Plugin Name: Silenciar instalador de plugins del tema
 * Description: Evita el aviso «You do not have permission to manage plugins» cuando el usuario no puede instalar plugins.
 */

defined( 'ABSPATH' ) || exit;

add_action( 'admin_enqueue_scripts', 'ayudawp_dequeue_theme_plugin_installer', 100 );

function ayudawp_dequeue_theme_plugin_installer() {
	if ( current_user_can( 'install_plugins' ) ) {
		return;
	}

	$scripts   = wp_scripts();
	$theme_uri = get_template_directory_uri();

	foreach ( $scripts-&gt;queue as $handle ) {
		if ( ! isset( $scripts-&gt;registered[ $handle ] ) ) {
			continue;
		}

		$src = (string) $scripts-&gt;registered[ $handle ]-&gt;src;

		if ( str_starts_with( $src, $theme_uri ) &amp;&amp; str_ends_with( $src, 'plugin-installer.js' ) ) {
			wp_dequeue_script( $handle );
		}
	}
}</pre>
<p>Guarda, recarga el escritorio y <strong>el aviso no debería volver a salir</strong>.</p>
<p>Por si quieres entender lo que subes (que deberías, nunca pegues código sin saber qué hace), esto es lo que hace:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li>Si el usuario puede instalar plugins, no hace nada y el tema funciona como siempre.</li>
<li>Si no puede, repasa los scripts que se van a cargar en esa pantalla y quita los que salen de la carpeta del tema y terminan en <code>plugin-installer.js</code>.</li>
</ul>
</li>
</ul>
<ul>
<li>Se engancha con prioridad 100 para ejecutarse después de que el tema haya encolado su script, cosa que hace con la prioridad normal, 10.</li>
<li>Compara con la carpeta del tema padre (<code>get_template_directory_uri()</code>), que es desde donde lo carga el tema, así que funciona igual con un tema hijo activo.</li>
<li><code>str_starts_with()</code> y <code>str_ends_with()</code> son funciones de PHP 8, pero WordPress las incluye por su cuenta desde la versión 5.9, así que no hay problema con PHP 7.</li>
</ul>
<blockquote><p><strong>Nota</strong>: si en tu caso el script se llama de otra forma, lo localizas con la columna Iniciador que te comentaba antes. Cambia <code>plugin-installer.js</code> por el nombre que corresponda y listo. Y si algún día quitas la constante, el script vuelve a cargarse solo, sin tocar nada más.</p></blockquote>
<h2>Un apunte para quien desarrolla temas</h2>
<p>Comprobar los permisos en el servidor antes de instalar nada está bien hecho, eso hay que reconocerlo. Lo que sobra es lo demás, porque <strong>un script que solo sirve en un par de pantallas del tema no tiene por qué cargarse en todo el escritorio</strong>, ni preguntar nada a quien no puede instalar plugins, y mucho menos contestarle con un <code>alert()</code> con el que no puede hacer nada salvo aceptar.</p>
<p>Lo correcto sería comprobar <code>current_user_can( 'install_plugins' )</code> antes de encolar el script y cargarlo solo en las pantallas donde se usa.</p>
<p>Si el tema que usas hace esto, cuéntaselo a su desarrollador, que es un cambio pequeño y le ahorra el mal rato a mucha gente.</p>
<p>Para cualquier duda, o si te ha salido algo parecido con otro tema o con otro mensaje, me tienes ahí abajo, en los comentarios. Un aviso menos, y a otra cosa.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/error-you-do-not-have-permission-to-manage-plugins/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Filtros de WooCommerce y bots: la trampa de rastreo que te puede tumbar la tienda online</title>
		<link>https://ayudawp.com/trampa-rastreo/</link>
					<comments>https://ayudawp.com/trampa-rastreo/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 06:28:37 +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[Cloudflare]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[robots.txt]]></category>
		<category><![CDATA[Search Console]]></category>
		<category><![CDATA[WooCommerce]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160573</guid>

					<description><![CDATA[Si tu tienda WooCommerce se cae sin ataque aparente ni pico de ventas, y el hosting te avisa de que has superado tus recursos, mira qué direcciones están pidiendo los robots…]]></description>
										<content:encoded><![CDATA[<p>Si tu tienda <strong>WooCommerce se cae sin ataque aparente ni pico de ventas</strong>, y el hosting te avisa de que has superado tus recursos, <strong>mira qué direcciones están pidiendo los robots, porque puede que estén recorriendo una por una todas las combinaciones de tu filtro de productos</strong> hasta que el servidor dice basta.</p>
<p>Últimamente me lo estoy encontrando bastante, en varios clientes distintos del <a href="https://mantenimiento.ayudawp.com/" target="_blank" rel="ugc noopener">servicio de mantenimiento</a> y con la misma dinámica, y como ya tengo visto el problema y varias posibles soluciones creo que ya tocaba compartirlo.</p>
<p>Te cuento <strong>qué pasa, cómo comprobar si te afecta y cómo parar esta locura</strong>, que lo es, y que puede tirar abajo prácticamente cualquier tienda online.</p>
<h2>Culpable: un filtro que crea URLs a lo loco</h2>
<p><strong>El filtro por atributos</strong> clásico de WooCommerce, el que te deja elegir talla, color o lo que tengas, funciona con enlaces normales y sin AJAX (la técnica que actualiza una página sin recargarla).</p>
<p>Cada vez que marcas una opción de selección de atributo se carga una dirección nueva con los parámetros del filtro, como esta:</p>
<p><code>/categoria-producto/camisetas/?filter_color=azul,rojo&amp;query_type_color=or&amp;filter_talla=m,l&amp;query_type_talla=or</code></p>
<p><strong>Con 10 tallas hay 1.023 formas de marcar al menos una, con 30 ya son 1.073.741.823, y eso con un solo atributo</strong>, porque al sumar color, material y compañía las combinaciones se multiplican entre sí. Nadie las va a probar todas salvo un robot que no se cansa ni tiene pausas para el almuerzo, y aquí empieza el problema.</p>
<p>Lo que genera el problema es la suma de tres factores:</p>
<ol>
<li><strong>Combinaciones casi infinitas:</strong> el número de URLs posibles es enorme, pero a un robot no le cuesta nada solicitarlas.</li>
<li><strong>Enlaces que cualquiera puede seguir:</strong> el widget clásico de atributos marca los enlaces del filtro con <code>rel="nofollow"</code>, pero <strong>eso es una pista y no una barrera</strong>, porque nada obliga a un robot a hacerle caso. Además, según <a href="https://developers.google.com/crawling/docs/faceted-navigation" target="_blank" rel="nofollow noopener">la documentación de Google sobre navegación por facetas</a> el atributo solo funciona si lo lleva cada enlace que apunta a esa dirección.</li>
<li><strong>Casi ninguna se sirve desde caché:</strong> con tantas direcciones distintas, una caché de página casi nunca tendrá la copia lista cuando llega el robot, y WordPress y WooCommerce montan cada página desde cero. Google lo resume diciendo que rastrear este tipo de direcciones suele costar al sitio muchos recursos de cómputo.</li>
</ol>
<p>Con toda esta tormenta perfecta la cuenta de tu web en el hosting se puede quedar sin cuota de CPU o de procesos y el servidor empieza a rechazar visitas.</p>
<p>El síntoma típico es el <strong>error 508</strong>, <code>Resource Limit Is Reached</code>, que significa que tu cuenta ha superado alguno de sus límites de recursos.</p>
<p>Este problema (gordo) tiene incluso nombre y apellido, <strong>trampa de rastreo</strong> (<em>crawl trap</em>, si buscas en inglés), y consiste básicamente en que <strong>un robot que sigue enlaces puede meterse en un laberinto con casi infinitas salidas</strong>.</p>
<h2>Para tumbar una tienda no hace falta un ataque enorme</h2>
<p>Cuando una tienda se cae así cualquiera pensaría en un ataque DDoS (un ataque de denegación de servicio, con montones de máquinas pidiendo cosas a la vez para colapsar tu web), pero en realidad hace falta mucho menos.</p>
<p>Una página que ya está almacenada en caché la sirve cualquier hosting a un ritmo altísimo, pero <strong>una que WordPress y WooCommerce tienen que montar desde cero, con sus consultas a la base de datos, cuesta muchísimo más</strong>.</p>
<p>Si todas las peticiones son de las segundas, sin caché, un hosting compartido, e incluso muchos Cloud y VPS, con sus cuotas de recursos asignadas, aguanta mucho menos.</p>
<p>Los que recorren esas direcciones son de dos tipos, por un lado están los rastreadores conocidos como <code>Googlebot</code> o el agente de Meta (<code>meta-externalagent</code>), y cada vez más <a href="https://ayudawp.com/bloquear-bots-ia/" target="_blank" rel="ugc noopener">los rastreadores de las IAs</a>, que al menos te dicen quiénes son.</p>
<p>Y luego están los robots que se hacen pasar por un navegador corriente y no se identifican. <strong>Por eso conviene bloquear por el patrón de la dirección y no por quién la pide</strong>, porque a los segundos no hay forma fiable de reconocerlos.</p>
<p>Si te interesa ver cuáles de esos rastreadores de IA te visitan y poder cerrarles el paso, mi plugin <a href="https://wordpress.org/plugins/vigia/" target="_blank" rel="nofollow noopener">VigIA</a> detecta más de 60 por su identificador y permite bloquearlos. Pero lo hace por quién pide y no por la dirección, así que no sustituye a las capas de más abajo, y no ve a los que se hacen pasar por un navegador ni a Googlebot.</p>
<p>Dos pistas que delatan el problema son, por un lado picos de peticiones a <strong>horas en las que no compra nadie</strong>, y por otro <strong>visitas masivas desde países donde no vendes</strong>, si tu hosting o tu CDN te dejan ver de dónde llegan.</p>
<h2>Cómo saber si estás sufriendo una trampa de rastreo debido a los filtros de atributos</h2>
<p>Los registros de acceso (la lista de todo lo que ha pedido cada visitante) lo dirían todo, pero leerlos mediante comandos de consola no es para todo el mundo, y hay alternativas más cómodas, de menos a más esfuerzo. Te las cuento, porque yo suelo también usarlas así, en este orden creciente.</p>
<h3>La prueba de la barra de direcciones</h3>
<p>Entra en una categoría de tu tienda, marca una opción del filtro y mira la barra de direcciones. Si aparece algo como <code>?filter_color=azul</code>, tu filtro escribe la selección en la dirección, la causa del problema del que estamos hablando.</p>
<p><a href="https://ayudawp.com/?attachment_id=160655" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160655 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/producto-woocomerce-filter-1200x716.jpg" alt="" width="1200" height="716" srcset="https://ayudawp.com/wp-content/uploads/2026/10/producto-woocomerce-filter-1200x716.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/producto-woocomerce-filter-768x458.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/producto-woocomerce-filter-1536x917.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/producto-woocomerce-filter.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Para saber si los robots pueden llegar hasta ahí, pulsa <code>Ctrl+U</code> en Chrome o Firefox (en Mac, <code>Cmd+Option+U</code> en Chrome y <code>Cmd+U</code> en Firefox) para ver el código fuente de la página, busca <code>filter_</code> y fíjate en si lo que encuentras son enlaces (<code>&lt;a href="…filter_…"</code>).</p>
<p>Si tus enlaces son de ese tipo un robot puede seguirlos y deberías seguir leyendo esta guía. Si no hay ninguno el riesgo es menor, pero no des el caso por cerrado sin mirar los registros o el contador del que te hablo más abajo.</p>
<h3>Los registros de tu hosting</h3>
<p>Si en el panel de tu hosting puedes descargar o ver los registros de acceso, ábrelos con un editor de texto y busca <code>filter_</code>. Si lo llevan la mayoría de las líneas, ya sabes cuál es tu problema.</p>
<h3>Mini plugin para tener un contador con el que diagnosticar el problema</h3>
<p>Si no tienes acceso a los registros, o prefieres una cifra clara, puedes poner a contar a la propia web con un pequeño plugin de un solo archivo.</p>
<p>Crea en tu ordenador un archivo de texto llamado <code>ayudawp-filter-detector.php</code> con este contenido, súbelo a la carpeta <code>wp-content/plugins</code> con el gestor de archivos de tu hosting o por FTP, o si lo prefieres lo comprimes en un zip y lo instalas como como siempre, y actívalo en la pantalla de plugins.</p>
<pre>&lt;?php
/**
 * Plugin Name: AyudaWP Detector de filtros
 * Plugin URI:  https://plugins.ayudawp.com
 * Description: Diagnóstico temporal. Cuenta las peticiones públicas con parámetros de filtro de WooCommerce y muestra el total en el escritorio.
 * Version:     1.0.0
 * Author:      Fernando Tellado
 * Author URI:  https://ayudawp.com
 * License:     GPL-2.0-or-later
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Indica si los parámetros incluyen algún nombre filter_*.
 *
 * Lee los parámetros ya interpretados por PHP, igual que WooCommerce.
 *
 * @param array $params Parámetros de la petición ($_GET).
 * @return bool
 */
function ayudawp_fd_has_filter( array $params ): bool {
	foreach ( array_keys( $params ) as $name ) {
		if ( 0 === strpos( (string) $name, 'filter_' ) ) {
			return true;
		}
	}
	return false;
}

/**
 * Cuenta la petición y guarda las últimas direcciones. No guarda IP ni navegador.
 *
 * El recuento es aproximado: dos peticiones simultáneas pueden pisarse.
 */
function ayudawp_fd_record(): void {
	if ( is_admin() || wp_doing_ajax() || wp_doing_cron() ) {
		return;
	}

	// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Solo se leen nombres de parámetros, no se guarda ni se muestra nada.
	if ( ! ayudawp_fd_has_filter( $_GET ) ) {
		return;
	}

	$uri = ( isset( $_SERVER['REQUEST_URI'] ) &amp;&amp; is_string( $_SERVER['REQUEST_URI'] ) )
		? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) )
		: '';

	$stats = get_transient( 'ayudawp_fd_stats' );
	if ( ! is_array( $stats ) ) {
		$stats = array(
			'since' =&gt; time(),
			'count' =&gt; 0,
			'last'  =&gt; array(),
		);
	}

	++$stats['count'];
	array_unshift( $stats['last'], substr( $uri, 0, 150 ) );
	$stats['last'] = array_slice( $stats['last'], 0, 10 );

	set_transient( 'ayudawp_fd_stats', $stats, WEEK_IN_SECONDS );
}
add_action( 'init', 'ayudawp_fd_record' );

/**
 * Muestra las cifras en el escritorio, solo a administradores.
 */
function ayudawp_fd_notice(): void {
	global $pagenow;

	if ( 'index.php' !== $pagenow || ! current_user_can( 'manage_options' ) ) {
		return;
	}

	$stats = get_transient( 'ayudawp_fd_stats' );
	if ( ! is_array( $stats ) || empty( $stats['count'] ) ) {
		echo '&lt;div class="notice notice-info"&gt;&lt;p&gt;&lt;strong&gt;AyudaWP.com - Detector de filtros&lt;/strong&gt;&lt;/p&gt;';
		echo '&lt;p&gt;Activo, pero todavía no ha contado ninguna petición con parámetros de filtro. Un cero no descarta el problema: si hay una caché, Cloudflare, el .htaccess o el plugin de bloqueo por delante, esas peticiones no llegan hasta aquí.&lt;/p&gt;&lt;/div&gt;';
		return;
	}

	echo '&lt;div class="notice notice-warning"&gt;&lt;p&gt;&lt;strong&gt;AyudaWP.com - Detector de filtros&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;';
	printf(
		'Peticiones con parámetros de filtro: %1$s (desde el %2$s).',
		esc_html( number_format_i18n( (int) $stats['count'] ) ),
		esc_html( wp_date( 'j/n/Y H:i', (int) $stats['since'] ) )
	);
	echo '&lt;/p&gt;&lt;p&gt;Últimas direcciones pedidas:&lt;/p&gt;&lt;ul&gt;';
	foreach ( (array) $stats['last'] as $address ) {
		echo '&lt;li&gt;&lt;code&gt;' . esc_html( (string) $address ) . '&lt;/code&gt;&lt;/li&gt;';
	}
	echo '&lt;/ul&gt;&lt;/div&gt;';
}
add_action( 'admin_notices', 'ayudawp_fd_notice' );

// Al desactivar el plugin se borran los datos del contador.
register_deactivation_hook(
	__FILE__,
	static function () {
		delete_transient( 'ayudawp_fd_stats' );
	}
);</pre>
<p>Este pequeño plugin cuenta las peticiones de la parte pública de la web que llevan parámetros <code>filter_</code> y, cuando entras a «Escritorio &gt; Inicio» como administrador, te muestra el total, desde cuándo está contando y las últimas direcciones pedidas. Mientras no haya contado ninguna, el aviso te dice que está activo y que todavía no ha visto nada.</p>
<p><a href="https://ayudawp.com/?attachment_id=160656" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160656 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/detector-filtros-plugin-woocommerce-1200x678.jpg" alt="" width="1200" height="678" srcset="https://ayudawp.com/wp-content/uploads/2026/10/detector-filtros-plugin-woocommerce-1200x678.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/detector-filtros-plugin-woocommerce-768x434.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/detector-filtros-plugin-woocommerce-1536x867.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/detector-filtros-plugin-woocommerce.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Para comprobar que funciona, añade <code>?filter_prueba=1</code> al final de la dirección de tu tienda desde una ventana de incógnito y vuelve a «Escritorio &gt; Inicio» y el contador debería marcar 1. Si no sube, algo atiende esa petición antes de que llegue a PHP, como una caché o una regla de bloqueo.</p>
<p>El código no guarda direcciones IP ni identificadores de navegador. Las cifras son aproximadas, porque si dos peticiones coinciden en el mismo instante una puede pisar a la otra, y los datos caducan solos tras siete días sin peticiones con filtro.</p>
<p>También ten en cuenta que solo ve las peticiones que llegan hasta PHP, y las que sirve una caché o corta Cloudflare, el <code>.htaccess</code> o el plugin de bloqueo (si ya lo tienes activo) no pasan por aquí, de modo que la cifra real será igual o mayor.</p>
<p><strong>Úsalo unas horas y quítalo.</strong> Cada petición que cuenta hace unas cinco consultas a la base de datos (en una instalación sin caché de objetos persistente son tres lecturas y dos escrituras), y si tu servidor ya va justo se notan. Cuando tengas la cifra, desactívalo y bórralo desde Plugins.</p>
<h2>Cómo parar una trampa de rastreo en 3 capas</h2>
<p>Mi criterio es cortar lo más lejos posible de WordPress, porque cuanto antes pares una petición, menos trabajo le llega a tu servidor. Las capas van en este orden y puedes montar una, dos o las tres.</p>
<table border="1" cellspacing="0" cellpadding="8">
<thead>
<tr>
<th>Capa</th>
<th>Dónde corta</th>
<th>Qué necesitas</th>
<th>¿Sigue funcionando el filtro?</th>
</tr>
</thead>
<tbody>
<tr>
<td>1. Cloudflare</td>
<td>Antes de llegar a tu hosting</td>
<td>Web detrás de Cloudflare, vale el plan gratuito</td>
<td>No, para nadie</td>
</tr>
<tr>
<td>2. .htaccess</td>
<td>En el servidor, antes de WordPress</td>
<td>Apache o LiteSpeed y acceso al archivo</td>
<td>No, para nadie</td>
</tr>
<tr>
<td>3. Plugin de bloqueo</td>
<td>Dentro de WordPress, antes de que cargue WooCommerce</td>
<td>Poder subir un archivo a <code>wp-content/plugins</code></td>
<td>Lo decides tú: con <code>0</code> se bloquea cualquier filtro y con un número se pone un límite</td>
</tr>
</tbody>
</table>
<p>Las tres capas <strong>bloquean por el nombre del parámetro y no distinguen quién lo envía</strong>. Si usas otro plugin que ponga parámetros que empiecen por <code>filter_</code> en la parte pública de tu web, comprueba que sigue funcionando después.</p>
<p>Lo mismo vale para los bloques de filtro de producto que trae el propio WooCommerce, que usan esos mismos parámetros y también se ven afectados por el bloqueo total.</p>
<p>Cloudflare y el <code>.htaccess</code> buscan el texto <code>filter_</code> tal como llega en la dirección, mientras que la tercera capa lee los parámetros que PHP entrega a WooCommerce. Para los robots que siguen los enlaces del filtro da igual, porque piden justo las direcciones que el filtro genera.</p>
<p>Pero no para quien escriba a mano una variante como <code>filter.color=azul</code> (PHP convierte el punto en un guion bajo y WooCommerce la entiende igual), pues se salta las dos primeras capas, y solo el plugin la para.</p>
<p>Además, las reglas solo cubren los parámetros <code>filter_</code>: el widget clásico de filtrar por valoración usa enlaces con <code>rating_filter</code>, que también se pueden rastrear y que estas reglas no tocan.</p>
<h3>Primera capa: Cloudflare, antes de que llegue a tu hosting</h3>
<p>Cloudflare con su plan gratuito permite <a href="https://developers.cloudflare.com/waf/custom-rules/" target="_blank" rel="nofollow noopener">hasta 5 reglas personalizadas</a>, con la acción de bloquear incluida. Con una sola puedes parar estas peticiones sin que tu servidor se entere. Para crearla:</p>
<ol>
<li>En el panel de Cloudflare entra en la página «Security rules» (si tienes el panel en español, puede aparecer traducida) y pulsa «Create rule» y después «Custom rules».</li>
<li>Ponle un nombre que te acuerdes de qué hace, por ejemplo «Bloquear filtros de WooCommerce».</li>
<li>Pulsa el enlace «Edit expression», junto a la vista previa de la expresión, para <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/" target="_blank" rel="nofollow noopener">editarla a mano</a>, y pega esto:
<pre>(starts_with(http.request.uri.query, "filter_") or http.request.uri.query contains "&amp;filter_") and not starts_with(http.request.uri.path, "/wp-admin/")</pre>
</li>
<li>En la acción elige «Block» y pulsa «Deploy».</li>
</ol>
<p>La primera parte busca parámetros que empiecen por <code>filter_</code>, ya sea al principio de la dirección o detrás de un <code>&amp;</code>, y la segunda deja fuera el escritorio de WordPress, porque el botón «Filtrar» de las listas de entradas, páginas y productos envía un parámetro llamado <code>filter_action</code> y sin esa excepción te quedarías sin él.</p>
<ul>
<li><strong>Tu web tiene que estar detrás de Cloudflare con el proxy activado</strong> (la nube naranja de «Proxied»): Con la nube gris, Cloudflare solo hace de DNS y <a href="https://developers.cloudflare.com/dns/proxy-status/" target="_blank" rel="nofollow noopener">no aplica ninguna regla</a>.</li>
<li><strong>Pruébala:</strong> añade <code>?filter_color=azul</code> al final de la dirección de tu tienda y, si funciona, verás una página de bloqueo en lugar de tu tienda. Para ver cuántas peticiones ha parado, mira en Analytics la <a href="https://developers.cloudflare.com/waf/analytics/security-events/" target="_blank" rel="nofollow noopener">pestaña Events</a>, donde en el plan gratuito sale una muestra de los eventos y no todos, y se guardan hasta 31 días.</li>
<li><strong>Mientras la regla esté activa, el filtro deja de funcionar para tus clientes:</strong> El resto de la tienda va con normalidad, que es mejor que una web caída. Si de verdad lo usan, la tercera capa te deja un punto medio.</li>
<li><strong>El límite de velocidad del plan gratuito se queda corto para esto:</strong> <a href="https://developers.cloudflare.com/waf/rate-limiting-rules/" target="_blank" rel="nofollow noopener">solo admite una regla</a>, con ventanas de 10 segundos y por IP, y un límite por IP sirve de poco contra robots que llegan desde muchas direcciones distintas.</li>
</ul>
<p>Si todavía no tienes tu web en Cloudflare, ponerla lleva su proceso (lo habitual es cambiar los servidores de nombres de tu dominio, o sea, los DNS) y no es lo que quieres hacer con la tienda caída. Pasa a la capa siguiente y deja Cloudflare para cuando respires.</p>
<h3>Segunda capa: el servidor, con una regla en el .htaccess</h3>
<p>Si no usas Cloudflare, o quieres una segunda barrera por si alguien llega a tu servidor sin pasar por él, la regla va en el <code>.htaccess</code>. Haz antes una copia del archivo y pega esto <strong>al principio, antes de la línea <code># BEGIN WordPress</code></strong>, para que WordPress no la toque.</p>
<pre>&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/wp-admin/ [NC]
RewriteCond %{QUERY_STRING} (^|&amp;)filter_ [NC]
RewriteRule .* - [F,L]
&lt;/IfModule&gt;</pre>
<p>La regla <strong>devuelve un 403</strong> a cualquier petición con un parámetro que empiece por <code>filter_</code>, y deja fuera <code>/wp-admin/</code> por el mismo motivo que en Cloudflare. Si en tu filtro solo usas un atributo puedes afinar más y poner su nombre, por ejemplo <code>(^|&amp;)filter_talla=</code>.</p>
<p>Vale para Apache y LiteSpeed, que leen el <code>.htaccess</code>, pero no para nginx. Y como en la capa anterior, <strong>mientras esté activa, el filtro deja de funcionar para tus clientes</strong>.</p>
<h3>Tercera capa: un plugin que cierra la puerta desde WordPress</h3>
<p>Si no puedes tocar ni Cloudflare ni el <code>.htaccess</code>, o <strong>quieres que tus clientes puedan seguir filtrando con un límite razonable</strong>, esta es tu capa.</p>
<p>Se ejecuta dentro de WordPress, así que el servidor ya ha hecho parte del trabajo, pero corta la petición antes de que cargue WooCommerce y el tema, y por tanto antes de que hagan sus consultas.</p>
<p>Se instala igual que el contador que hemos visto antes, en este caso el nombre del archivo recomendado sería <code>ayudawp-filter-trap-guard.php</code>:</p>
<pre>&lt;?php
/**
 * Plugin Name: AyudaWP Bloqueo de filtros
 * Plugin URI:  https://plugins.ayudawp.com
 * Description: Rechaza las direcciones con filtros de WooCommerce (filter_*) antes de que carguen WooCommerce y el tema.
 * Version:     1.0.0
 * Author:      Fernando Tellado
 * Author URI:  https://ayudawp.com
 * License:     GPL-2.0-or-later
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// Opciones de filtro que se permiten en una petición. Con 0 se bloquea cualquier filtro,
// y con 2 tus clientes pueden combinar hasta dos opciones y se rechaza lo que pase de ahí.
if ( ! defined( 'AYUDAWP_FTG_MAX_OPTIONS' ) ) {
	define( 'AYUDAWP_FTG_MAX_OPTIONS', 0 );
}

/**
 * Indica si los parámetros traen más opciones de filtro de las permitidas.
 *
 * Lee los parámetros ya interpretados por PHP, igual que WooCommerce, así que también
 * pilla nombres escritos de forma rara. Cada valor de cada filter_* cuenta como una opción.
 *
 * @param array $params Parámetros de la petición ($_GET).
 * @param int   $max    Opciones permitidas. Con 0 se rechaza cualquier filtro.
 * @return bool
 */
function ayudawp_ftg_should_block( array $params, int $max ): bool {
	$found   = false;
	$options = 0;

	foreach ( $params as $name =&gt; $value ) {
		if ( 0 !== strpos( (string) $name, 'filter_' ) ) {
			continue;
		}

		// WooCommerce espera un texto separado por comas, nunca una lista.
		if ( is_array( $value ) ) {
			return true;
		}

		$found    = true;
		$options += max( 1, count( array_filter( explode( ',', (string) $value ), 'strlen' ) ) );
	}

	return $found &amp;&amp; ( 0 === $max || $options &gt; $max );
}

/**
 * Responde 403 y corta si la petición es un filtro rechazado.
 */
function ayudawp_ftg_maybe_block(): void {
	// El escritorio, AJAX y cron usan nombres filter_* para sus cosas.
	if ( is_admin() || wp_doing_ajax() || wp_doing_cron() ) {
		return;
	}

	// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Solo se leen nombres y recuentos de parámetros, no se guarda ni se muestra nada.
	if ( ! ayudawp_ftg_should_block( $_GET, (int) AYUDAWP_FTG_MAX_OPTIONS ) ) {
		return;
	}

	status_header( 403 );
	header( 'Cache-Control: no-store, max-age=0' );
	header( 'Content-Type: text/plain; charset=utf-8' );
	exit( 'Forbidden' );
}

ayudawp_ftg_maybe_block();</pre>
<p>El número que manda está al principio, en <code>AYUDAWP_FTG_MAX_OPTIONS</code>, y lo cambias editándolo en el propio archivo (o definiéndolo en el <code>wp-config.php</code>, si prefieres no tocar el plugin).</p>
<ul>
<li>Con <code>0</code>, cualquier dirección con <code>filter_</code> recibe un 403, igual que en las capas anteriores.</li>
<li>Con <code>2</code>, tus clientes pueden combinar hasta dos opciones (un color y una talla, por ejemplo) y todo lo que pase de ahí se rechaza. En el ejemplo de las 10 tallas, <strong>pasas de 1.023 combinaciones posibles a 55</strong>.</li>
</ul>
<p>Los robots seguirán pidiendo las combinaciones que sí se permiten, y el widget seguirá ofreciendo la tercera opción a tus clientes: quien la marque verá un <code>Forbidden</code> en texto plano en lugar de su tienda.</p>
<p>Es un parche <strong>poco elegante, pero muuucho mejor que una tienda caída</strong>. Si tu hosting está en las últimas empieza con <code>0</code> y sube el número cuando pase el apretón.</p>
<p>Para probarlo, con el valor <code>0</code>, abre tu tienda con <code>?filter_color=azul</code> al final. Si ves un texto que dice <code>Forbidden</code>, funciona.</p>
<p>WordPress carga los plugins activos por orden alfabético y este empieza por «ayudawp», así que corta antes de que cargue WooCommerce. Solo se te adelantaría uno cuyo nombre empiece antes, como Akismet.</p>
<p>Si prefieres que el plugin se cargue siempre el primero, el mismo archivo funciona sin cambios en <code>wp-content/mu-plugins/</code>, donde WordPress carga los <a href="https://ayudawp.com/que-son-los-mu-plugins-de-wordpress/" target="_blank" rel="ugc noopener">mu-plugins</a> antes que cualquier plugin normal y sin activarlos.</p>
<h2>¿Sirven de algo el robots.txt, el canonical y los errores 4xx?</h2>
<p>Sobre esto circula mucho consejo por ahí, y prefiero quedarme con lo que dice la documentación de Google ¿y tú?:</p>
<ul>
<li><strong>robots.txt:</strong> una regla como <code>Disallow: /*?*filter_</code> hace que <code>Googlebot</code> deje de pedir esas direcciones, y <a href="https://developers.google.com/crawling/docs/faceted-navigation" target="_blank" rel="nofollow noopener">Google la recomienda en primer lugar</a> para la navegación facetada. Tiene dos límites, uno es que según <a href="https://developers.google.com/search/docs/crawling-indexing/robots/intro" target="_blank" rel="nofollow noopener">su documentación sobre robots.txt</a> una página bloqueada puede indexarse igualmente si otros sitios enlazan a ella, y el otro que solo lo cumplen los robots que quieren cumplirlo, es declarativo, como todo en el fichero robots.txt, no obligatorio.</li>
<li><strong>Canonical:</strong> apuntar las páginas filtradas a la categoría sin filtrar le dice a Google cuál es la versión buena, pero según esa misma <a href="https://developers.google.com/crawling/docs/faceted-navigation" target="_blank" rel="nofollow noopener">documentación sobre navegación por facetas</a> solo puede reducir el volumen de rastreo con el tiempo y a largo plazo es menos eficaz que el robots.txt.</li>
<li><strong>Errores 4xx:</strong> según <a href="https://developers.google.com/search/docs/crawling-indexing/http-network-errors" target="_blank" rel="nofollow noopener">la documentación de Google sobre códigos de estado</a>, todos los 4xx se tratan igual salvo el 429, y no distingue entre un 404 y un 410. Devolver un 403 o un 410 da lo mismo, y las direcciones que ya estuvieran indexadas y pasen a devolver cualquiera de ellos acaban saliendo del índice. Eso sí, esa misma página desaconseja usar el 401 y el 403 para limitar el ritmo de rastreo, y los que hacen que <code>Googlebot</code> afloje son los errores 5xx y el 429. El 403 de tus capas no sirve para que venga menos, y lo que consigues es que cada visita cueste muy poco.</li>
</ul>
<p><strong>Si bloqueas las direcciones en el robots.txt, Googlebot no las pide y por tanto nunca ve ese 403.</strong> Si en Search Console ves direcciones con filtro indexadas y quieres que desaparezcan quita el <code>Disallow</code> una temporada (tus reglas las responden sin esfuerzo) y deja que Google compruebe que ya no existen. Si no hay ninguna indexada déjalo como está.</p>
<h2>Quitar la causa y no solo tapar el agujero</h2>
<p>Las capas frenan el golpe pero el filtro sigue roto para tus clientes, salvo que hayas puesto un límite en la tercera. Hay dos salidas habituales, con lo que te llevas y lo que te cuesta cada una.</p>
<h3>Lo bueno y lo malo de quitar los filtros con muchos valores</h3>
<p><strong>A favor</strong></p>
<ul>
<li>Cuesta cero y no hay nada que mantener.</li>
<li>Desaparecen los enlaces del laberinto en su origen. Como las combinaciones crecen de forma exponencial, quitar el atributo con 30 valores elimina de golpe los más de mil millones de direcciones que generaba.</li>
<li>Un filtro menos que probar cada vez que actualizas WooCommerce o el tema.</li>
</ul>
<p><strong>En contra</strong></p>
<ul>
<li>Pierdes una función que quizá usan tus clientes. Mira tu analítica antes de quitar nada.</li>
<li>Reduce el problema, pero no lo cierra. Tres atributos de cuatro valores cada uno ya dan 4.095 direcciones, más que de sobra para un robot que no se cansa, así que las capas se quedan igual.</li>
<li>Si en tu sector el filtro es parte de cómo se compra, quitarlo puede costar ventas, y solo lo sabrás midiendo.</li>
</ul>
<h3>Lo bueno y lo malo del filtro AJAX</h3>
<p>Un filtro AJAX actualiza los productos sin recargar la página y puede funcionar sin enlaces con parámetros que los robots sigan, aunque eso depende de cómo esté hecho cada plugin.</p>
<p>Entre los plugins de este tipo están <a href="https://facetwp.com/pricing/" target="_blank" rel="nofollow noopener">FacetWP</a>, de pago, y <a href="https://es.wordpress.org/plugins/annasta-woocommerce-product-filters/" target="_blank" rel="nofollow noopener">annasta Filters for WooCommerce</a>, disponible en el directorio de WordPress.org, en parte gratis y en parte de pago.</p>
<p><strong>A favor</strong></p>
<ul>
<li>Mantienes el filtro para la gente que sí lo usa.</li>
<li>Si las opciones no son enlaces, los robots se quedan sin laberinto. <a href="https://facetwp.com/help-center/developers/the-facetwp-url/" target="_blank" rel="nofollow noopener">FacetWP</a> dice en su documentación que las facetas son invisibles para los buscadores, y los bloques de filtro de WooCommerce pintan las opciones con JavaScript.</li>
<li>Algunos plugins traen controles de SEO. La ficha de <a href="https://es.wordpress.org/plugins/annasta-woocommerce-product-filters/" target="_blank" rel="nofollow noopener">annasta</a> anuncia canonical automático en las páginas filtradas y opciones de noindex y nofollow.</li>
</ul>
<p><strong>En contra</strong></p>
<ul>
<li><strong>Cuesta dinero o tiempo</strong>: FacetWP Basic son 99 dólares al año para entre 1 y 3 sitios, annasta es gratuito pero con funciones de pago, y en los dos casos hay que configurarlo y probarlo con tu tema y tu maquetador.</li>
<li>Es JavaScript y <strong>una dependencia más que mantener y actualizar</strong>.</li>
<li><strong>Las direcciones filtradas siguen existiendo</strong>: FacetWP escribe la selección en la dirección (con parámetros que empiezan por <code>_</code>), esa dirección se puede abrir directamente y, según su propia documentación, <strong>si alguien la enlaza puede acabar indexada</strong>. Si no quieres eso, hay que añadir noindex. Y la descripción de annasta anuncia que puede actualizar la URL del navegador y convertir los parámetros en enlaces permanentes, así que esas opciones conviene mirarlas con la prueba en la mano.</li>
<li><strong>El trabajo pasa de los robots a las personas</strong>: cada cambio en el filtro es una petición al servidor. Con mucho tráfico, conviene medirlo.</li>
</ul>
<p>Sea cual sea el plugin que elijas repite la prueba de la barra de direcciones y del código fuente. Lo que abre la trampa son los enlaces con parámetros que un robot puede seguir, y si el filtro nuevo los deja en el código volverías a tener el problema, aunque los parámetros se llamen de otra forma y tus reglas, que buscan <code>filter_</code>, no los pararían.</p>
<p>Si el plugin nuevo trabaja con los mismos parámetros <code>filter_</code>, tus propias reglas bloquearán a tus clientes, y conviene probarlo con ellas activas antes de dar el trabajo por terminado.</p>
<p><strong>Cuando lo tengas funcionando retira el filtro nativo</strong> (el widget o el bloque) para que desaparezcan los enlaces. <strong>Las reglas se quedan</strong>, porque los robots ya conocen esas direcciones y es probable que sigan pidiéndolas durante un tiempo.</p>
<h3>Cómo decidir entre una salida y otra</h3>
<p>Para decidir te traslado tres preguntas.</p>
<ol>
<li><strong>¿Alguien usa el filtro?</strong>: si casi nadie lo toca quítalo del todo y te ahorras todo el problema.</li>
<li><strong>¿Cuántos valores tienen tus atributos?</strong>: con decenas el problema se dispara, y con tres o cuatro es manejable.</li>
<li><strong>¿Quién va a cuidar el plugin?</strong>: un filtro de pago pide actualizaciones y pruebas, y si no tienes quien las haga, quitar es más sensato que instalar.</li>
</ol>
<p>Cuando me he encontrado esto en un cliente, lo primero que hago es analizar el tráfico y los registros, y con esos datos diagnostico el problema con la ayuda de mi equipo y el refuerzo de la IA, en mi caso con Claude Code, y siempre doy con una solución, pero cambia según el sitio.</p>
<p>La decisión depende de lo que digan los datos y el resultado del análisis del problema, pues cada tienda es un mundo.</p>
<h2>¿Por dónde empezar?</h2>
<ol>
<li>Marca una opción de tu filtro, mira la barra de direcciones y el código fuente de la página. Si ves enlaces con <code>filter_</code>, esto va contigo.</li>
<li>Si no tienes claro cuánto te está pasando, deja el contador unas horas y apunta la cifra.</li>
<li>Si tu web está en Cloudflare, crea la regla de bloqueo. Es una regla corta y tu hosting ni se entera.</li>
<li>Añade la regla del <code>.htaccess</code> (con copia previa) o, si no puedes tocar ese archivo, instala el plugin de bloqueo, que además para las variantes retorcidas.</li>
<li>Mira en Google Search Console si hay direcciones con filtro indexadas y decide qué haces con el <code>Disallow</code> del <code>robots.txt</code>.</li>
<li>Con los datos delante, decide qué haces con el filtro: quitarlo, pasar a uno AJAX o dejarlo con el límite de la tercera capa. Si cambias, repite con el nuevo la prueba del código fuente y comprueba que no choca con tus reglas.</li>
</ol>
<p>Para seguir con la defensa de tu web, tienes mi guía sobre <a href="https://ayudawp.com/ataques-ddos-wordpress/" target="_blank" rel="ugc noopener">ataques DDoS en WordPress</a> y, si te interesa un problema parecido, el artículo sobre <a href="https://ayudawp.com/evitar-rastreo-anadir-al-carrito-woocommerce/" target="_blank" rel="ugc noopener">evitar el rastreo de «Añadir al carrito»</a>, en cierto modo relacionado.</p>
<p>Si tienes dudas con alguna de las capas, o quieres contarme qué ves tú en tu tienda, me tienes ahí abajo, en la sección de comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/trampa-rastreo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Así es cómo reviso la seguridad de mis plugins, por qué cambié el proceso, y de regalo unas skills para tu IA favorita con el procedimiento</title>
		<link>https://ayudawp.com/skill-revisar-seguridad-plugins/</link>
					<comments>https://ayudawp.com/skill-revisar-seguridad-plugins/#comments</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Mon, 19 Oct 2026 06:28:56 +0000</pubDate>
				<category><![CDATA[IA + WordPress]]></category>
		<category><![CDATA[Programación + WordPress]]></category>
		<category><![CDATA[Seguridad WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Claude]]></category>
		<category><![CDATA[CVE]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[skill]]></category>
		<category><![CDATA[Vigilante]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160535</guid>

					<description><![CDATA[Me avisaron de una vulnerabilidad publicada con CVE de uno de mis plugins, y aquí te cuento qué pasó, cómo cambió mi forma de revisar el código antes de cada versión y cómo puedes usar ese procedimiento, hecho skill, aunque no seas experto en seguridad.]]></description>
										<content:encoded><![CDATA[<p>Hace ya tiempo se detectó una vulnerabilidad en Vigilante, mi plugin de seguridad, ahí es nada, y desde entonces <strong>he cambiado por completo la forma en que reviso cualquier plugin antes de publicar una actualización</strong>.</p>
<p>He convertido en skills públicas el procedimiento que surgió de ahí, y antes de enseñártelas quiero contarte de dónde vienen.</p>
<p>Porque una skill no enseña nada por sí sola, eso para empezar,  es simplemente el formato que he elegido para pasarte lo que aprendí a las malas, de manera que puedas aprovecharlo, incluso aunque no sepas demasiado de seguridad, con una IA que te haga de ayudante.</p>
<p><strong>Lo que vale es lo aprendido, creo, y de eso va este artículo</strong>.</p>
<h2>Qué pasó con el plugin … de seguridad</h2>
<p>El 11 de septiembre de 2026 se publicó el <a href="https://patchstack.com/database/wordpress/plugin/vigilante/vulnerability/wordpress-vigilant-plugin-2-10-2-cross-site-scripting-xss-vulnerability" target="_blank" rel="noopener nofollow">CVE-2026-81754</a>, una vulnerabilidad de tipo XSS almacenado (un código sospechoso que podía quedarse guardado en tu web y ejecutarse cuando alguien abre la página donde se muestra) que afectaba a <a href="https://wordpress.org/plugins/vigilante/" target="_blank" rel="nofollow noopener">Vigilante</a> hasta la versión 2.10.2, y qué corregí en la 2.10.3 (en menos de una hora, eso sí).</p>
<p>Te cuento qué pasaba procurando usar los mínimos tecnicismos posibles…</p>
<p>El registro de actividad de Vigilante guarda el <code>User-Agent</code> de cada visita, que es el texto con el que un navegador o un robot se presenta al entrar en tu web. Lo escribe quien visita, así que puede poner lo que quiera, y cuando el administrador abría el registro, una función de JavaScript preparaba ese texto para mostrarlo y lo hacía a medias, porque codificaba los símbolos <code>&lt;</code> y <code>&gt;</code> pero dejaba pasar las comillas.</p>
<p>Con un <code>User-Agent</code> bien elegido cualquiera sin cuenta en la web podía salirse del atributo HTML donde se pintaba el texto y ejecutar código en el navegador del administrador.</p>
<p>Hay matices, y conviene decirlos, porque <strong>la puntuación CVSS es de 7.2, hace falta que un administrador abra el registro para que ocurra algo</strong>, y cuando se publicó la ficha la valoración de CISA indicaba que <strong>no se conocía ninguna explotación</strong>. Nada de eso le quita importancia, pero contarlo sin esos datos sería contarlo mal, e incluso injusto.</p>
<p>Lo encontró y me lo comunicó Sebastian Albrecht, y se lo agradezco. Que le pase esto a un plugin de seguridad escuece el doble, pero prefiero contarlo yo con todos los datos antes de que lo cuente otro con la mitad.</p>
<h2>Lo que de verdad me dio que pensar</h2>
<p>Lo que más me inquietó no fue el fallo en sí. La función que escapaba mal venía de las primeras versiones del plugin, de esas que nadie toca porque funcionan, y todas las versiones posteriores habían pasado por mi revisión.</p>
<p>Mi revisión de entonces se fijaba sobre todo en lo que cambiaba de una versión a otra. Si tocaba algo, lo repasaba, y lo que quedaba sin tocar lo daba por bueno, y además, el fallo era en el JavaScript, donde mis comprobaciones miraban poco, y mal, porque <strong>una revisión que solo mira lo que cambia no ve lo que ya estaba mal, y este fue mi mayor aprendizaje</strong>.</p>
<h2>Revisarlo todo y cerrar cada puerta</h2>
<p>Con la versión 2.10.3 quedó cerrado el CVE, como te he comentado, pero me quedé con una idea ahí clavada a fuego, y es que <strong>si había una puerta abierta que nadie había mirado, podía haber más</strong>.</p>
<p>Así que me puse a <strong>revisar el plugin entero, sin fijarme en qué había cambiado, y a cerrar cada posible puerta</strong> que encontraba, hasta la última versión antes de la 3.0.0. Fueron muchas versiones y no te las voy a contar una a una, pero algunos hallazgos te enseñan lo que pasa cuando por fin miras todo:</p>
<ul>
<li><strong>La identificación en dos pasos, el 2FA</strong>, tenía un camino para saltárselo, que cerré en la 2.10.3 junto al CVE. Más tarde, una revisión cruzada encontró otro, porque el código se pedía en el formulario de acceso de WordPress pero no en otros formularios de inicio de sesión, como los de WooCommerce, y lo cerré en la 2.11.0. En ambos casos hacía falta conocer la contraseña de la cuenta, pero una doble verificación que se puede esquivar, por raro que sea el caso, no cumple su función, no al menos en mis estándares.</li>
<li><strong>El bloqueo de intentos de accesos</strong> falló en sitios que no usaban la hora UTC durante 73 versiones, de la 1.0.0 a la 2.10.5, porque la tabla de intentos mezclaba la hora del sitio con la UTC. Se corrigió en la 2.11.0.</li>
<li><strong>Al guardar copias de <code>wp-config.php</code> y <code>.htaccess</code> en la base de datos para comparar cambios</strong>, acababa ahí información sensible como la contraseña de la base de datos y las claves de seguridad (desde la 2.7.0). Lo fui limpiando entre la 2.11.2 y la 2.11.9, y en las preguntas frecuentes del plugin explico que, si alguien pudo leer tu base de datos o sus copias, conviene regenerar esas claves y cambiar la contraseña.</li>
<li><strong>La IP del visitante</strong> se leía de la cabecera <code>X-Forwarded-For</code> por el lado equivocado, también desde la 2.7.0. Cada proxy va añadiendo su dato a esa cabecera, pero el visitante puede escribir la suya al principio de la lista, de modo que leerla por ese extremo es creerse lo que diga el visitante. Solo afectaba a sitios con esa opción activada y quedó corregido en la 2.11.8.</li>
</ul>
<p>Todo consta con su versión en el <a href="https://wordpress.org/plugins/vigilante/#developers" target="_blank" rel="nofollow noopener">registro de cambios público</a> del plugin, que es lo que más me importa, porque sin ese rastro lo que cuento sería solo mi palabra, y la transparencia es vital. Si tienes un problema y lo solucionas demuestras responsabilidad, si lo ocultas no esperes que nadie se fíe de ti y tus productos.</p>
<p>No todo lo encontré yo. Albert Calzada, un usuario muy activo del plugin, se dedicó a revisar las diferencias entre versiones, artprojectgroup leyó el código de la 2.11.11 y dio con problemas en el 2FA que corregí en la 2.11.12, y Antonio Cambronero, freelancesgroup y pepelopex me avisaron de fallos de funcionamiento por el camino. Todos lo hicieron como se debe hacer, directamente y con educación, sin montar un escándalo y dándome tiempo para arreglarlo. Gracias a todos, de verdad, sois parte de la grandeza del código abierto.</p>
<h2>Lo que aprendí por el camino</h2>
<p>De esa revisión salió un <strong>procedimiento que ahora aplico antes de publicar cualquier versión</strong>. Los pasos concretos están en la skill, aquí te cuento los aprendizajes o ideas sobre los que está basada:</p>
<ul>
<li><strong>Se revisa todo lo que el plugin expone, haya cambiado o no:</strong> Cada punto por donde entran datos de fuera (formularios, cabeceras, campos que viajan por la API REST) se mira en cada versión, aunque nadie haya tocado ese código en años.</li>
<li><strong>No todas las versiones merecen el mismo esfuerzo:</strong> El proceso completo me llevó unas diez horas en una versión corriente, y lo que no se aguanta acaba saltándose. Por eso hay tres niveles de profundidad, según sea un cambio ordinario, uno sensible o un plugin de seguridad con una vulnerabilidad publicada.</li>
<li><strong>Quien revisa no puede ser quien escribió el cambio:</strong> Una revisión cruzada y a ciegas, hecha por otra persona o por otra IA que no haya visto cómo se hizo, encuentra lo que el autor ya no ve. Para la 3.0.0 hice diez rondas solo sobre la autoprotección del plugin, y dos más sobre la parte visible, que conté en el artículo sobre <a href="https://ayudawp.com/vigilante-3/" target="_blank" rel="ugc noopener">Vigilante 3</a>.</li>
<li><strong>Una comprobación nunca debe decir «no hay nada» cuando la verdad es «no he podido mirar»:</strong> Por eso cada herramienta y cada nota de versión lleva escrito, además de lo que encontró, lo que no ha visto, y la nota incluye cifras de cuántas comprobaciones se hicieron. En mi opinión es la regla más valiosa de todas.</li>
<li><strong>Se mide el efecto, no que el código esté escrito:</strong> Haber añadido una corrección no prueba nada. Hay que reproducir el fallo contra la versión anterior y comprobar que con la nueva ya no ocurre, y así reproduje el segundo atajo del 2FA contra la 2.10.5 antes de darlo por cerrado.</li>
</ul>
<p>La parte mecánica de las comprobaciones la he dejado en tres scripts. Uno busca funciones de JavaScript que escapan texto sin codificar las comillas, o sea, justo el fallo del CVE. Otro lista los avisos de seguridad del analizador de código que alguien ha silenciado sin explicar por qué, y el tercero detecta llamadas a métodos que no existen cuando copias código de un plugin a otro. Llevan un <em>autotest</em> de siete casos y cada uno tiene escrita la lista de lo que no ve.</p>
<p>Todo esto cobra más sentido con la <a href="https://developer.wordpress.org/plugins/wordpress-org/automated-security-review/" target="_blank" rel="nofollow noopener">revisión automática de seguridad</a> que WordPress.org aplica desde junio de 2026, donde cada versión pasa por un periodo de espera mientras la analizan varios modelos de IA junto con Jetpack Scan, y si la puntuación de riesgo sale alta, la versión se bloquea y los sitios siguen recibiendo la anterior.</p>
<p>Que una revisión con Plugin Check te salga sin errores ni avisos tristemente actualmente sirve de bien poco, te cuenta cosas, te informa de límites de procedimiento y cosa básicas de seguridad, pero no es un pentest ni de lejos.</p>
<h2>El proceso completo, de un vistazo</h2>
<p>Todo lo anterior cabe en un mapa. Es el recorrido de una versión de mi plugin, desde que decido cuánta revisión le toca hasta que llega a los sitios, con las tres puertas que pueden pararla por el camino.</p>
<p><a href="https://ayudawp.com/?attachment_id=160566" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160566 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/10/mapa-proceso-revision-plugin-wordpress-1200x1122.jpg" alt="" width="1200" height="1122" srcset="https://ayudawp.com/wp-content/uploads/2026/10/mapa-proceso-revision-plugin-wordpress-1200x1122.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/10/mapa-proceso-revision-plugin-wordpress-768x718.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/10/mapa-proceso-revision-plugin-wordpress-1536x1436.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/10/mapa-proceso-revision-plugin-wordpress.jpg 1604w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>En el mapa salen unas palabras que no he usado hasta ahora y que resumen bien cómo pienso la revisión:</p>
<ul>
<li><strong>Puerta:</strong> Es un punto del recorrido donde, si algo falla, la versión no sigue, y hay tres:
<ol>
<li>Una comprobación mecánica que da error o una cifra que no cuadra.</li>
<li>Un hallazgo de gravedad media o superior en el análisis o en la revisión cruzada.</li>
<li>Un riesgo alto en la revisión automática de WordPress.org. No hay posibilidad de «ya lo arreglo luego».</li>
</ol>
</li>
<li><strong>Canario:</strong> Es un caso de prueba cuyo resultado conoces de antemano. Cuando un comando que busca algo en el código te dice «cero coincidencias», no sabes si no hay nada o si el comando no ve nada. Por eso lo ejecuto antes sobre un archivo hecho a propósito, con líneas que sí deben saltar, y solo me fío del cero si ahí encuentra lo que debe. Lo llamo canario porque es lo primero que avisa de que algo va mal, por lo de los pajaritos que se llevaban a la mina, por si no conocías la referencia.</li>
</ul>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160568 size-full" src="https://ayudawp.com/wp-content/uploads/2026/10/canario-cero-comprobacion-plugin-wordpress.jpg" alt="" width="1056" height="656" srcset="https://ayudawp.com/wp-content/uploads/2026/10/canario-cero-comprobacion-plugin-wordpress.jpg 1056w, https://ayudawp.com/wp-content/uploads/2026/10/canario-cero-comprobacion-plugin-wordpress-768x477.jpg 768w" sizes="auto, (max-width: 1056px) 100vw, 1056px"></p>
<p>También te cuento acerca de otra terminología que uso para el procedimiento, para que comprendas mejor como funciona mi cabeza (spoiler: raro):</p>
<ul>
<li><strong>Arnés:</strong> Es el conjunto de pruebas permanentes del plugin, y <strong>a cada prueba suelta la llamo celda</strong>. Crece con cada hallazgo, se ejecuta entero en cada versión y no lleva número de versión, porque no es de ninguna en concreto. Cuando se publica una vulnerabilidad, su prueba de concepto, que es el código que reproduce el fallo, entra en el arnés ese mismo día: falla contra la versión vulnerable y pasa contra la actual. No va dentro del zip del plugin, es mi herramienta de trabajo y no algo que instales en tu web.</li>
<li><strong>Mutante:</strong> Cada vez que arreglo un hallazgo grave añado una celda para que no vuelva. Y para saber si esa celda sirve de algo vuelvo a meter el fallo a propósito, eso es el mutante, y compruebo que la celda falla. Si con el fallo puesto sigue pasando, no protege nada. Para la 3.0.0 de Vigilante inyecté 71 mutantes y las pruebas cazaron todos menos uno, que no cambiaba el comportamiento del plugin y dejé anotado como tal.</li>
</ul>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160567 size-full" src="https://ayudawp.com/wp-content/uploads/2026/10/celda-mutante-arnes-pruebas-plugin-wordpress.jpg" alt="" width="1096" height="936" srcset="https://ayudawp.com/wp-content/uploads/2026/10/celda-mutante-arnes-pruebas-plugin-wordpress.jpg 1096w, https://ayudawp.com/wp-content/uploads/2026/10/celda-mutante-arnes-pruebas-plugin-wordpress-768x656.jpg 768w" sizes="auto, (max-width: 1096px) 100vw, 1096px"></p>
<p>Lo que ves en el mapa es el procedimiento que viene en la skill de seguridad. No hace falta pasar por todo en cada versión, para eso están los tres niveles, pero así sabes qué hay detrás de cada paso cuando se lo pidas a tu asistente.</p>
<h2>Qué es una skill y por qué las comparto</h2>
<p>Si no te suena el término, <strong>una skill es una carpeta con instrucciones, y a veces con documentos de referencia y scripts, que le das a tu asistente de IA para que trabaje con un método</strong> concreto en lugar de tirar solo de lo que recuerda. Piensa en la nota que dejas en la nevera para quien se queda en tu casa, no le enseña a sobrevivir, solo le dice cómo haces tú las cosas.</p>
<p>Todo este tipo de procesos los expliqué con más calma, y cómo cargarlas en cada IA, en el artículo sobre <a href="https://ayudawp.com/vibe-coding-plugin-wordpress/" target="_blank" rel="ugc noopener">vibe coding de plugins para WordPress</a>.</p>
<p>Esto eran procedimientos internos, notas mías para no volver a chocar con la misma piedra, y lo normal habría sido quedármelos para mis plugins, pero llevo más de veinte años haciendo webs, buena parte de lo que sé lo aprendí de gente que compartió lo suyo, y la filosofía Open Source va de eso, así que <strong>he empaquetado mi procedimiento actual como skills para que lo aproveche quien quiera</strong>.</p>
<h2>Dónde están las skills, qué incluyen y qué no</h2>
<p>Las dos que salen de esta historia las tienes disponibles en el <a href="https://github.com/fernandotellado/ai-skills" target="_blank" rel="nofollow noopener"><strong>repositorio de skills para IA que tengo en GitHub</strong></a>, junto a otras que ya tenía, como la de rendimiento o las de humanizar textos.</p>
<ul>
<li><code>wp-plugin-security</code>, en su versión 1.3, trae la skill principal, cuatro documentos de referencia, los tres scripts y la puerta de seguridad previa a cada versión, con sus tres niveles, los comandos que hay que ejecutar y la plantilla de la nota de versión. Recoge también cosas como usar los datos que elige quien hace la petición (el User-Agent, las cabeceras de proxy, la IP) solo para registrar y nunca para decidir, o lo que borra en silencio <code>sanitize_text_field()</code> de una URL con caracteres codificados, algo que dejó al cortafuegos de Vigilante analizando una copia distinta de la petición hasta la 2.9.9.</li>
<li><code>wp-plugin-development</code> unifica lo que la documentación no cuenta sobre desarrollar y publicar plugins, como la receta para que los textos por defecto traducibles no se guarden en la base de datos y se queden congelados en un idioma.</li>
</ul>
<p>De todos modos, a riesgo de ser pesado, insisto en que <strong>una skill no garantiza un plugin seguro ni sustituye a una auditoría.</strong> Las puertas de revisión cazan regresiones, es decir, que rompas lo que ya funcionaba, pero no te dicen si el diseño original era bueno. Los scripts no lo detectan todo, y el ejemplo de la doble verificación de la skill de seguridad es un boceto con la lista de lo que le falta, no una implementación completa.</p>
<p>Si descargaste la skill de seguridad antes de esta actualización bájala de nuevo, pues corregí en esta versión (1.3) un ejemplo con lo del 2FA que daba por bueno un atajo que se saltaba el código en los formularios de acceso distintos de <code>wp-login.php</code>.</p>
<h2>Cómo obtener las skills y usarlas</h2>
<p>El <code>README</code> del repositorio está en inglés, así que te resumo lo que necesitas.</p>
<ol>
<li>Entra en el repositorio, pulsa el botón «<strong>Code</strong>», elige «<strong>Download ZIP</strong>» y descomprímelo. Cada skill es una carpeta (<code>wp-plugin-security</code>, <code>wp-plugin-development</code> y así), y te quedas con las que quieras.</li>
<li><strong>Carga la skill en tu asistente de IA</strong>: En Claude con proyectos, añade los archivos de la skill al conocimiento del proyecto. En Claude Code copia la carpeta entera a <code>~/.claude/skills/</code>. En ChatGPT, crea un GPT personalizado y sube los archivos a su base de conocimiento. En cualquier otro asistente, usa su apartado de archivos o conocimiento, o las instrucciones personalizadas.</li>
<li><strong>Sube siempre la carpeta completa</strong>, no solo <code>SKILL.md</code>, porque ese archivo remite a los de <code>references</code> y <code>scripts</code>, y sin ellos la skill queda coja.</li>
<li>Los scripts necesitan Node.js, PHP en línea de comandos con la extensión mbstring y Python 3. Los ejecutas tú, o tu asistente si trabaja con acceso a una terminal.</li>
<li>Para actualizarlas, dale al icono del ojo (watch) para que te avise cuando suba cambios, vuelve a descargar el repositorio y sustituye los archivos.</li>
</ol>
<p>Con la skill ya cargada, pídele a tu asistente de IA que aplique la puerta de seguridad antes de publicar una versión, dile qué nivel crees que toca y que te entregue la nota de versión con lo que ha comprobado y lo que no ha podido mirar. Si es la primera vez que lo haces empieza por el nivel más bajo en tu próxima versión y sube solo si el cambio lo pide. Y lee esa nota con ojo crítico, porque <strong>la IA también se equivoca y ninguna skill cambia eso</strong>.</p>
<h2>Para terminar</h2>
<p>Si tienes Vigilante instalado, comprueba que estás en una versión actual, sino valiente apaño he hecho ¿no?</p>
<p>Y luego, bueno, si quieres me cuentas en los comentarios si has vivido algo parecido con tus propios plugins o temas, o si ves algún hueco en este procedimiento. Estaré encantado de comentarlo contigo, que de eso también se aprende.</p>
<p>A mí me tocó aprenderlo a las malas, y lo mínimo es que a ti te salga más barato, y para ello espero que las skills te ayuden.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/skill-revisar-seguridad-plugins/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>