Saltar al contenido
gioser
EN

tawasuyu · Hacer

Tu WordPress, sin WordPress: el mismo sitio al píxel, sin una sola línea de PHP

Un sitio hecho con WordPress es un programa que corre cada vez que alguien lo visita, con su base de datos, sus plugins y sus puertas de administración abiertas a internet. qhatu se lo lleva entero, igual al píxel, y lo deja sin nada que ejecutar: el mismo sitio, más rápido, y sin una sola línea de PHP.

8 min de lecturaPor Redacción Gioser

Cada vez que alguien abre una página de un sitio WordPress, en el servidor arranca un programa: lee la base de datos, carga el tema, despierta cada plugin, arma el HTML y lo manda. Lo mismo, una y otra vez, para un texto que cambia una vez por mes. Y mientras tanto, ese programa deja abiertas a todo internet las puertas por donde se administra. Este artículo cuenta cómo qhatu —el gestor de contenidos de tawasuyu— se lleva un sitio WordPress real entero, lo deja igual al píxel, y le quita todo lo que se podía atacar.

Gráfico: a la izquierda, WordPress con 9 de 9 programas que contestan a cualquiera, con la lista de sus direcciones —wp-login.php, wp-admin, xmlrpc.php, wp-json, el listado de usuarios, author=1, readme.html, install.php, wp-cron.php—; a la derecha, qhatu y saywa con 0 de 9, 0 píxeles distintos de 3.278.400, 825 a 135 milisegundos y cero PHP
Medido el 24 de octubre de 2026 sobre el sitio real de un cliente y su copia.

El sitio que se arma en cada visita

WordPress es la forma más común de tener un sitio, y hay buenas razones: se instala en una tarde, hay un tema para todo, y un constructor como Elementor deja diseñar sin escribir código. El precio se paga después, y en cuotas. Cada plugin es código ajeno que corre con todos los permisos del sitio; cada actualización que se posterga es una puerta; y la base de datos, el login y la API quedan escuchando las veinticuatro horas, aunque el sitio lo edite una persona dos veces por mes.

El sitio con el que se probó todo esto es el de un cliente real: un centro de retiros hecho con WordPress, el tema WoodMart y Elementor Pro, con 64 páginas, una galería, un blog y dos formularios de contacto. Un sitio común, del tipo que hay a millones. El pedido fue simple: que quede igualito, y que se pueda seguir editando fácil.

Un comando

Lo que el primer día se hizo a mano —bajar el sitio renderizado, limpiar lo que WordPress agrega a cada nombre de archivo, reapuntar los formularios— hoy es un verbo:

qhatu absorb-wordpress https://el-sitio.com/ carpeta

Lee los mapas del sitio que publica WordPress, baja cada página y todo lo que necesita —hojas de estilo, scripts, imágenes en todos sus tamaños, fuentes, íconos—, y deja cada referencia apuntando a la copia local. No baja lo que no es contenido: el carrito, el panel de administración, los feeds, las búsquedas. Si una dirección vieja redirige a otra, no la duplica: la anota como redirección para el servidor, así un enlace que alguien compartió hace años sigue llegando. Sobre el sitio del cliente:

quémedido
páginas64
recursos (hojas, scripts, imágenes, fuentes)448, 45 MB
tiempo, con una pausa de cortesía entre pedido y pedido6 minutos
referencias rotas en la copia0

Igual al píxel, y con brazo de control

«Igualito» se puede medir. Se abrió la misma página del original y de la copia en Chrome, a 1366 por 2400 píxeles, y se compararon las dos capturas punto por punto. En la portada y en una entrada del blog, 0 píxeles distintos de 3.278.400. Para que ese cero signifique algo, la prueba lleva brazo de control: cada captura tiene 216.987 colores distintos, así que no se están comparando dos páginas en blanco.

Y la honestidad incluye lo que no dio cero. En una tercera página aparecieron 1.785 píxeles distintos en la franja del menú. Antes de culpar a la copia se comparó el original consigo mismo, dos veces: dio 1.642 y 0. Es la propia página, que no se pinta igual dos veces seguidas.

Nada que hackear

Un escáner de WordPress empieza siempre igual: pregunta por las direcciones que todo WordPress tiene. Se hizo esa misma pregunta a los dos sitios, en modo pasivo —sólo pedidos de lectura a direcciones públicas, sin probar una sola contraseña—:

direcciónqué esWordPresscopia
/wp-login.phpla puerta del logincontesta404
/wp-admin/el panelcontesta404
/xmlrpc.phpla puerta clásica de la fuerza bruta en lotecontesta404
/wp-json/la APIcontesta404
/wp-json/wp/v2/usersla lista de quienes pueden entrarcontesta, con 3 nombres404
/?author=1el nombre de usuario del primer autorlo diceno
/readme.htmlla versión exactacontesta404
/wp-admin/install.phpel instaladorcontesta404
/wp-cron.phptareas que dispara cualquieracontesta404

Nueve de nueve contra cero de nueve. Además, el original anunciaba en su propio código la versión exacta de WordPress y de dos de sus plugins: exactamente lo que un atacante busca para cruzar con una lista de fallas conocidas. No es que la copia tenga esas puertas mejor cerradas: no las tiene. No hay PHP que ejecutar, ni base de datos que consultar, ni usuarios que adivinar.

Midiendo esto apareció un detalle que vale contar. La copia todavía decía «WordPress» en una etiqueta invisible del HTML, heredada del original: un escáner la leía y anunciaba un WordPress que ya no existía. El absorbedor ahora la saca.

¿Y los formularios de contacto, que en WordPress son un plugin más? En la copia los atiende una función WebAssembly de 205 KB que corre en el servidor con capacidades declaradas: puede guardar lo que llega y leer el reloj, y nada más. No puede leer el disco ni salir a la red; lo que no pidió no existe para ella. Los mensajes se leen en el panel, y bajan como planilla.

Más rápido, y medido sin trampa

Cinco páginas, cinco cargas en frío de cada lado —un navegador nuevo por carga, sin caché—, alternando original y copia para que una mala racha de la red no caiga entera de un lado. Las medianas:

páginaprimer bytelo más grande pintadocarga completa
portada2,5 s → 0,9 s6,1 s → 4,9 s9,9 s → 5,9 s
página de servicio1,9 s → 0,8 s6,5 s → 3,8 s14,9 s → 5,4 s
página larga con galería2,3 s → 0,9 s11,7 s → 6,3 s22,3 s → 7,9 s
listado del blog2,4 s → 0,7 s4,5 s → 4,1 s5,1 s → 5,3 s
una entrada2,3 s → 0,8 s5,9 s → 2,5 s7,0 s → 5,2 s

Los bytes que viajan son prácticamente los mismos: es la misma página. Lo que cambia es el servidor. Y hay una salvedad que un artículo honesto tiene que hacer: los dos sitios están en servidores distintos, en lugares distintos, y la copia quedaba más cerca de donde se midió. Así que se separó la red del software. Abrir la conexión cuesta 392 milisegundos hasta el original y 179 hasta la copia; eso es distancia, no código. Descontando una ida y vuelta de cada lado, lo que queda es el trabajo de armar la página:

WordPress: ~825 ms por página saywa: ~135 ms por página
El trabajo del servidor, con la distancia de red descontada. Medido con curl, cinco pedidos de cada lado.

Y se sigue editando, en el lugar

Una copia estática que no se puede tocar sería un museo. La de qhatu se edita desde un panel que vive en su propia dirección —nada del sitio público lo enlaza—, sobre la página misma, tal como se ve:

Todo eso corre en saywa, el servidor web de tawasuyu. En la máquina donde vive este sitio, saywa y la forja propia del proyecto ya reemplazaron a cuatro programas: el servidor web, la forja de git, el proxy y el intérprete de PHP. Alguien escribió las dos piezas desde cero, en Rust, con una regla que se repite en todo el proyecto: lo que no se midió no se afirma.

Lo que todavía no

Cómo verlo

qhatu vive en el repositorio de tawasuyu —git.tawasuyu.net, en un servidor propio— bajo 02_ruway/qhatu, y saywa bajo 03_ukupacha/saywa. Los dos instrumentos de este artículo, el de exposición y el de velocidad, están en scripts/qhatu-careo/: cualquiera puede correrlos contra su propio WordPress y contra su copia, y comparar.

Fondo