TimThumb ha muerto: cómo gestionar imágenes EN WordPress (guía 2026)

TimThumb ha muerto: cómo gestionar imágenes EN WordPress (guía 2026)

Última verificación: 12 de octubre de 2026
17 min de lectura
Guía
Desarrollador full-stack
Auditor de seguridad

Si eres un veterano de WordPress, seguramente recuerdas TimThumb. Era un pequeño script PHP que se encontraba en casi todos los “temas premium” alrededor de 2010. Permitía recortar y redimensionar imágenes de forma fácil y al vuelo.

En agosto de 2011 se descubrió una vulnerabilidad crítica Zero-Day que permitía a los atacantes subir y ejecutar código PHP en los servidores que tenían el script. Ese fue el fin de la era del “script sencillo”.

Hoy, en 2026, WordPress cuenta con un poderoso motor de gestión de medios. Si todavía encuentras timthumb.php en tu tema, elimínalo inmediatamente. Esta guía muestra cómo hacerlo de forma profesional.

#Por qué TimThumb era inseguro

TimThumb funcionaba “al vuelo”: tomaba una imagen de una URL, la procesaba y la guardaba en caché. Los problemas eran múltiples y graves:

  1. Seguridad: Permitía la ejecución remota de código (RCE). La vulnerabilidad la hizo pública Mark Maunder el 1 de agosto de 2011, después de que atacaran su propio blog. El script solo comprobaba parcialmente el nombre de host frente a su lista blanca de dominios, así que un atacante podía hacer que descargara un archivo PHP a su directorio de caché y después ejecutarlo con una petición directa. Eso daba acceso completo al sitio web y potencialmente al servidor entero. Maunder recomendaba además buscar en el directorio de WordPress la función base64_decode y cadenas codificadas largas, la huella típica del código inyectado.

  2. Rendimiento: Sobrecargaba el servidor PHP con cada nueva solicitud de imagen. Cada vez que un visitante accedía a una página con imágenes procesadas por TimThumb, el servidor tenía que ejecutar PHP para verificar la caché, procesar la imagen si no existía, y servirla. En sitios con mucho tráfico, eso significaba muchas ejecuciones PHP adicionales que consumían CPU y memoria. El procesamiento de imágenes es una tarea intensiva en recursos, y hacerlo en tiempo real a través de PHP era muy ineficiente comparado con servir archivos estáticos pregenerados.

  3. Sin integración: No reconocía la Biblioteca de Medios de WordPress. TimThumb operaba completamente fuera del ecosistema de WordPress. No utilizaba los hooks ni las funciones del core, no registraba las imágenes procesadas en la base de datos, y no se beneficiaba de las mejoras que WordPress iba implementando en su sistema de medios. Las imágenes procesadas por TimThumb no aparecían en la Biblioteca de Medios, no se podían gestionar desde el panel de administración, y no se beneficiaban de funcionalidades como el texto alternativo, las descripciones o los créditos de imagen.


#Cronología de las vulnerabilidades de TimThumb

La historia del script cabe en cuatro fechas, y todas están documentadas en fuentes primarias:

FechaQué pasóFuente
agosto de 2011Fallo en la lista blanca de dominios de las versiones anteriores a la 2.0, explotado activamenteNVD, CVE-2011-4106
agosto de 2011Maunder reescribe el script como WordThumb, que se fusiona en TimThumb 2.0blog de Mark Maunder
junio de 2014Ejecución remota de comandos en TimThumb 2.8.13 y WordThumb 1.07 cuando la función WebShot está activadaNVD, CVE-2014-4663
27 de septiembre de 2014Su autor, Ben Gillbanks, anuncia que deja de mantenerloBinaryMoon

El identificador CVE-2011-4106 se publicó en la NVD más tarde, en octubre de 2013, pero la descripción oficial dice que el fallo se explotó en agosto de 2011. Maunder calculó entonces la escala de forma indirecta: Google devolvía más de 39 millones de resultados para el nombre del script. Su diagnóstico de fondo sigue siendo válido para cualquier redimensionador escrito dentro de un tema:

“timthumb.php es inseguro por naturaleza, porque depende de poder escribir archivos en un directorio al que tienen acceso los visitantes de tu sitio web.”

Mark Maunder, 1 de agosto de 2011, traducción propia

El parche de 2011 cerró aquel agujero concreto, pero no el diseño. Tres años después llegó el fallo de WebShot, que pasaba metacaracteres de shell del parámetro src a un comando del sistema. Gillbanks escribió en su anuncio de 2014 que llevaba años sin apenas tocar el código y que quien siguiera usando TimThumb lo hacía bajo su propia responsabilidad. Un tema que todavía incluye el archivo depende por tanto de código sin mantenimiento desde hace más de una década.


#Cómo registrar tamaños nativos con add_image_size

WordPress tiene la función add_image_size() desde hace años. Te permite definir formatos que el sistema generará automáticamente durante la subida del archivo. Esta es la forma más eficiente y segura de gestionar los diferentes tamaños de imagen que tu tema necesita.

#Registrar tamaños en functions.php

function wppoland_setup_theme() {
    // Habilitar soporte para imágenes destacadas
    add_theme_support( 'post-thumbnails' );

    // Tamaños estándar (recorte suave: mantiene la proporción de aspecto)
    add_image_size( 'blog-list', 800, 400 );

    // Recorte duro (corta el exceso)
    // WordPress recortará exactamente el centro de la imagen
    add_image_size( 'team-member', 300, 300, true );

    // Recorte con posicionamiento (ej., desde arriba, desde la izquierda)
    add_image_size( 'hero-banner', 1920, 600, ['center', 'top'] );
}
add_action( 'after_setup_theme', 'wppoland_setup_theme' );

Cuando defines tamaños personalizados con add_image_size(), WordPress genera automáticamente todas las variantes en el momento de la subida. El procesamiento pesado se realiza una sola vez, durante la carga del archivo, y no cada vez que un visitante solicita la página. Por eso este enfoque rinde mucho mejor que cualquier solución de procesamiento al vuelo.

Conviene entender los tres modos de recorte disponibles. El recorte suave (soft crop) es el comportamiento predeterminado cuando no se especifica el parámetro de recorte. WordPress redimensionará la imagen para que quepa dentro de las dimensiones especificadas, manteniendo la proporción de aspecto original. Esto significa que una de las dimensiones puede ser menor que la especificada. El recorte duro (hard crop), activado pasando true como tercer parámetro, fuerza exactamente las dimensiones especificadas, recortando los bordes que sobren. El recorte posicionado permite especificar desde qué punto de la imagen se realizará el recorte, lo cual es especialmente útil para banners donde el sujeto principal suele estar en la parte superior de la imagen.

#Mostrar el tamaño en la plantilla (single.php)

if ( has_post_thumbnail() ) {
    the_post_thumbnail( 'hero-banner', ['class' => 'img-fluid'] );
}

Si ya tienes el ID del adjunto, wp_get_attachment_image() hace lo mismo fuera del bucle:

echo wp_get_attachment_image( $attachment_id, 'blog-list' );

Ventaja: Las imágenes se generan una vez (durante la subida). Se sirven como archivos estáticos ya preparados. Cero carga PHP al mostrarlas. Esto también facilita el almacenamiento en caché, ya que los archivos estáticos son fácilmente cacheables tanto a nivel de servidor como de CDN.

#Cómo regenerar miniaturas con WP-CLI

Cuando añades nuevos tamaños de imagen a un tema existente, las imágenes ya subidas no tendrán las nuevas variantes generadas. Necesitas regenerar las miniaturas para las imágenes existentes. La forma más eficiente de hacerlo es a través de WP-CLI:

wp media regenerate --yes

Para bibliotecas grandes, la documentación de wp media regenerate ofrece opciones para limitar el trabajo: --only-missing genera solo los tamaños que faltan, --image_size=<nombre> regenera un único tamaño y --skip-delete conserva las miniaturas antiguas si alguien las enlaza desde fuera:

wp media regenerate --only-missing --yes
wp media regenerate --image_size=hero-banner --yes

#Qué tamaños de imagen genera WordPress por defecto

Antes de registrar tamaños propios conviene saber cuántos archivos crea ya el core por cada subida. Los valores por defecto de las opciones del esquema de WordPress son:

NombreDimensiones por defectoDesde
thumbnail150 × 150, recorte duroajustes de Medios
medium300 × 300 como máximoajustes de Medios
medium_large768 de ancho, sin límite de altoWordPress 4.4
large1024 × 1024 como máximoajustes de Medios
1536x15361536 × 1536 como máximoWordPress 5.3
2048x20482048 × 2048 como máximoWordPress 5.3

Los dos últimos los añade la función interna _wp_add_additional_image_sizes(), y el propio código del core desaconseja cambiarlos porque el nombre refleja las dimensiones. Cada add_image_size() de tu tema se suma a esta lista, así que una subida puede producir fácilmente diez archivos o más.

WordPress 5.3 también introdujo el umbral para imágenes grandes. Si el original supera 2560 píxeles de ancho o de alto, el core crea una copia reducida con el sufijo -scaled y la usa como tamaño “full”; el original se conserva y su nombre queda en los metadatos del adjunto (original_image). El valor se cambia o se desactiva con el filtro big_image_size_threshold:

// Subir el umbral a 4000 px
add_filter( 'big_image_size_threshold', fn() => 4000 );

// Desactivarlo por completo
add_filter( 'big_image_size_threshold', '__return_false' );

Para srcset existe un límite paralelo: el filtro max_srcset_image_width excluye del conjunto los candidatos más anchos de 2048 píxeles en el código actual del core. Si un tema necesita candidatos mayores para pantallas de alta densidad, ese es el filtro que hay que tocar, no un script de redimensionado.


#Cómo redimensionar imágenes WordPress con un CDN

Los tamaños nativos tienen un inconveniente: si cambias de tema, tienes que regenerar las miniaturas (por ejemplo, con el plugin Regenerate Thumbnails), lo que lleva mucho tiempo en una biblioteca de 100 GB.

En 2026, los servidores son rápidos y los CDNs son económicos. A menudo usamos un enfoque híbrido o servicios externos que procesan las imágenes en el edge, cerca del usuario final.

#Redimensionar con parámetros de URL en el CDN

En lugar de sobrecargar tu servidor PHP, usa parámetros de URL para que el CDN se encargue del procesamiento. La sintaxis exacta depende del proveedor; esquemáticamente:

<img src="https://tusitio.com/wp-content/uploads/imagen.jpg?width=400&height=300&format=avif">

La imagen original se almacena en tu servidor, pero el CDN se encarga de redimensionar, convertir el formato y servir la versión optimizada al usuario. Esto elimina la carga de procesamiento de imágenes de tu servidor PHP.

Las ventajas de este enfoque son claras. Primero, no necesitas regenerar miniaturas para tamaños nuevos, ya que el CDN genera cualquier tamaño bajo demanda. Segundo, la conversión de formato es automática: el CDN puede servir AVIF a navegadores que lo soportan y WebP como fallback. Tercero, cada transformación queda en la caché del edge, así que el coste de procesarla se paga una sola vez.

#Cloudflare Image Resizing

En Cloudflare la transformación se pide directamente en la URL, con el formato https://<zona>/cdn-cgi/image/<opciones>/<imagen-original>, por ejemplo /cdn-cgi/image/width=400,format=auto/wp-content/uploads/2026/10/foto.jpg. Según la documentación de Cloudflare, funciona en las zonas que tienen las transformaciones activadas, y format=auto sirve el formato más eficiente que admite el navegador que hace la petición. No hace falta un Worker para este caso; los Workers sirven cuando quieres reglas propias, por ejemplo reescribir automáticamente las URL de /wp-content/uploads/.


#Cómo usar srcset y sizes en imágenes WordPress

WordPress genera automáticamente el atributo srcset para tus imágenes, permitiendo al navegador elegir el tamaño apropiado para el dispositivo (teléfono vs escritorio 4K). Esta funcionalidad fue introducida en WordPress 4.4 y ha sido mejorada continuamente desde entonces.

<!-- WordPress genera esto automáticamente: -->
<img src="imagen-800x400.jpg"
     srcset="imagen-300x150.jpg 300w,
             imagen-800x400.jpg 800w,
             imagen-1024x512.jpg 1024w"
     sizes="(max-width: 600px) 100vw, 800px">

El atributo srcset lista todas las variantes disponibles de la imagen junto con sus anchuras en píxeles. El navegador utiliza esta información junto con el atributo sizes para determinar cuál es la imagen más adecuada para descargar, teniendo en cuenta el tamaño de la pantalla, la densidad de píxeles y el ancho del viewport.

Según la nota de desarrollo de WordPress 4.4, el valor sizes por defecto equivale a (max-width: {ancho}px) 100vw, {ancho}px, y si el HTML del contenido ya trae srcset o sizes, WordPress no los toca. Tu trabajo como desarrollador es definir correctamente sizes usando el filtro wp_calculate_image_sizes. Este filtro te permite especificar cómo se renderizará la imagen en diferentes breakpoints de tu diseño, para que el navegador pueda tomar la decisión óptima:

add_filter( 'wp_calculate_image_sizes', function( $sizes, $size, $image_src, $image_meta ) {
    // Para imágenes dentro de artículos
    if ( is_singular() ) {
        return '(max-width: 768px) 100vw, (max-width: 1200px) 75vw, 800px';
    }
    return $sizes;
}, 10, 4 );

#Qué atributos de carga añade WordPress a las imágenes

Desde WordPress 5.5, el atributo loading="lazy" se añade automáticamente a las imágenes. Las imágenes que no son visibles en el viewport inicial no se descargan hasta que el usuario se desplaza hacia ellas, lo que acelera la carga inicial de la página.

WordPress 6.1 añadió a wp_get_attachment_image() el atributo decoding="async", que permite al navegador decodificar las imágenes sin bloquear el renderizado de la página. Desde WordPress 6.3 los tres atributos los decide una sola función, wp_get_loading_optimization_attributes(). Marca con fetchpriority="high" la primera imagen suficientemente grande (el umbral por defecto es 50 000 píxeles de superficie, filtro wp_min_priority_img_pixels) y no le añade loading="lazy", porque un mismo elemento nunca debería llevar las dos cosas. Si tu imagen LCP sale de un bloque o de un fondo CSS que esa función no ve, márcala tú.


#Cómo optimizar imágenes WordPress con WebP y AVIF

En 2026, JPG y PNG son reliquias para fotografías. WordPress soporta nativamente WebP (desde la versión 5.8) y AVIF (desde la versión 6.5), siempre que la biblioteca de imágenes del servidor (Imagick o GD) admita el formato. La pantalla Herramientas > Salud del sitio, pestaña Información, sección Gestión de medios, muestra qué formatos admite tu servidor.

No necesitas plugins adicionales. Simplemente sube un archivo AVIF y WordPress lo gestiona. O usa el plugin Modern Image Formats del equipo de rendimiento de WordPress, que genera los subtamaños de los JPEG subidos en AVIF (o en WebP si el servidor no admite AVIF) y conserva el original.

#Cuánto pesan WebP y AVIF frente a JPG

Las cifras oficiales del core son estas:

AVIF suele comprimir mejor que WebP, especialmente en fotografías con degradados suaves. WebP sigue teniendo un soporte algo más amplio en navegadores antiguos, por lo que una estrategia habitual es servir AVIF como primera opción y WebP como fallback.

#Cómo usar el elemento picture con AVIF y WebP

Para un control máximo sobre los formatos servidos, puedes usar el elemento HTML <picture>:

<picture>
    <source srcset="imagen.avif" type="image/avif">
    <source srcset="imagen.webp" type="image/webp">
    <img src="imagen.jpg" alt="Descripción de la imagen">
</picture>

Sin embargo, en la mayoría de los casos, dejar que WordPress y el CDN gestionen la negociación de formato es la solución más práctica y mantenible.


#Cómo cambiar la calidad y el formato de salida en WordPress

Cada subtamaño que genera WordPress pasa por la clase WP_Image_Editor, y dos filtros controlan su resultado.

El primero es la calidad. En el código fuente actual de la clase, la calidad por defecto es 82 para JPEG y 86 para WebP; los demás formatos usan el 82. El filtro wp_editor_set_quality recibe la calidad y el tipo MIME, así que puedes ajustar cada formato por separado. En los JPEG se aplica después el filtro antiguo jpeg_quality, que tiene la última palabra si algún plugin lo usa:

add_filter( 'wp_editor_set_quality', function( $quality, $mime_type ) {
    if ( 'image/avif' === $mime_type ) {
        return 70;
    }
    return $quality;
}, 10, 2 );

El segundo es el formato de salida. El filtro image_editor_output_format asigna a cada tipo MIME de entrada el formato en el que se guardan los subtamaños. La nota de WordPress 6.5 usa exactamente este ejemplo para que los JPEG subidos produzcan subtamaños AVIF:

add_filter( 'image_editor_output_format', function( $formats ) {
    $formats['image/jpeg'] = 'image/avif';
    return $formats;
} );

Desde WordPress 6.7 el core usa ese mismo mecanismo por defecto para las fotos HEIC de los iPhone: si el servidor puede leerlas, las convierte a JPEG al subirlas. El cambio de formato solo afecta a imágenes nuevas o regeneradas, así que después de activar el filtro toca ejecutar wp media regenerate.


#Cómo eliminar TimThumb de un sitio WordPress

Descubre más sobre los servicios de seguridad WordPress en WPPoland.

Si has heredado un proyecto antiguo, sigue estos pasos para eliminar TimThumb de forma segura y completa:

  1. Escanea: Busca en el directorio wp-content los archivos timthumb.php o thumb.php. Busca también directorios de caché asociados.
  2. Elimina: Borra el archivo y cualquier directorio de caché asociado (normalmente una carpeta cache dentro del directorio del tema).
  3. Corrige: Encuentra dónde se llamaba en el código y reemplázalo:
    // CÓDIGO ANTIGUO (MALO)
    <img src="<?php echo get_template_directory_uri(); ?>/timthumb.php?src=..." />
    
    // REEMPLAZAR CON (BUENO)
    <?php the_post_thumbnail( 'mi-tamaño' ); ?>
  4. Regenera: Instala WP-CLI y ejecuta wp media regenerate.
  5. Verifica: Después de la migración, recorre todas las páginas principales del sitio para asegurarte de que las imágenes se muestran correctamente. Presta especial atención a las páginas de archivo, los widgets de la barra lateral y las áreas del pie de página donde TimThumb podría haber sido utilizado.

#Cómo buscar referencias a TimThumb con grep

No basta con eliminar el archivo. Debes buscar todas las referencias en el código:

# Buscar en todos los archivos PHP del tema
grep -r "timthumb" wp-content/themes/tu-tema/
grep -r "thumb.php" wp-content/themes/tu-tema/

# Buscar también en plugins personalizados
grep -r "timthumb" wp-content/plugins/

# Huella de código inyectado que recomendaba revisar Maunder
grep -rl "base64_decode" wp-content/

Cada referencia encontrada debe ser reemplazada por la función nativa equivalente de WordPress. En la mayoría de los casos, esto significa usar the_post_thumbnail() o wp_get_attachment_image() con el tamaño adecuado. Un resultado de base64_decode no prueba una infección, porque algunos plugins legítimos usan la función, pero cada aparición en un tema merece una lectura.


#Cómo medir el rendimiento de imágenes en WordPress

Una vez que has migrado de TimThumb a los métodos nativos, verifica que el rendimiento ha mejorado. Utiliza herramientas como Google PageSpeed Insights, Lighthouse y WebPageTest para medir los tiempos de carga antes y después de la migración.

#Qué métricas de imagen medir: LCP, CLS y TTFB

  • Largest Contentful Paint (LCP): La imagen principal suele ser el elemento LCP. Con tamaños nativos pregenerados, fetchpriority="high" y un CDN, el LCP debería mejorar.
  • Cumulative Layout Shift (CLS): Asegúrate de que todas las imágenes tienen dimensiones width y height definidas para evitar saltos de diseño durante la carga. Las funciones de adjuntos de WordPress las añaden solas.
  • Time to First Byte (TTFB) de las imágenes: Sin procesamiento PHP al vuelo, la respuesta de cada imagen ya no espera a PHP ni a GD.

#Configuración del servidor para imágenes WordPress

Para un rendimiento óptimo de imágenes en WordPress 2026, la configuración recomendada incluye:

  • Caché de navegador con headers Cache-Control largos para archivos de imagen (al menos 1 año)
  • CDN configurado con transformaciones de imagen para conversión de formato automática
  • Preload de la imagen LCP usando <link rel="preload"> cuando la imagen no aparece pronto en el HTML

#Qué método de imágenes WordPress elegir en 2026

La historia de TimThumb es una lección de humildad. La conveniencia (escalado al vuelo) no puede estar por encima de la seguridad. En 2026, tenemos add_image_size() nativo, srcset responsivo y CDNs procesando imágenes en la nube. No hay razón para volver a soluciones de hace 15 años.

La gestión moderna de imágenes en WordPress se basa en tres pilares: generación de tamaños durante la subida con add_image_size(), entrega responsiva con srcset y sizes, y optimización de formato con WebP/AVIF. Combinados con un CDN para la entrega, estos tres elementos proporcionan una experiencia de imagen rápida, segura y mantenible para cualquier sitio WordPress.

Siguiente paso

Transforma el artículo en una implementación real

Este bloque refuerza el enlazado interno y lleva al lector al siguiente paso más útil dentro de la arquitectura del sitio.

Cluster relacionado

Explora otros servicios WordPress y base de conocimiento

Refuerza tu negocio con soporte técnico profesional en áreas clave del ecosistema WordPress.

Preguntas frecuentes

Respuestas prácticas para aplicar el tema en la ejecución real.

¿Por qué TimThumb era peligroso para los sitios WordPress?#
Las versiones anteriores a la 2.0 solo comprobaban parcialmente el dominio de la lista blanca, de modo que un atacante podía hacer que el script descargara un archivo PHP a su directorio de caché y luego ejecutarlo con una petición directa (CVE-2011-4106, explotada en agosto de 2011). El script escribía archivos en un directorio accesible desde la web, y ese diseño era el problema de fondo.
¿Cómo reemplazo TimThumb en mi tema WordPress?#
Reemplaza TimThumb con la función nativa add_image_size() en functions.php para definir tamaños de imagen personalizados. WordPress generará automáticamente las miniaturas durante la subida de archivos, eliminando la necesidad de procesamiento en tiempo real y mejorando la seguridad.
¿Qué formatos de imagen debería usar en WordPress en 2026?#
WordPress acepta WebP desde la versión 5.8 y AVIF desde la versión 6.5, siempre que la biblioteca de imágenes del servidor (Imagick o GD) los soporte. Según las notas de desarrollo del core, WebP pesa de media alrededor de un 30% menos que JPEG o PNG y AVIF puede ser hasta un 50% más ligero que JPEG con la misma calidad.

¿Necesitas un FAQ adaptado a tu sector y mercado? Preparamos una versión alineada con tus objetivos de negocio.

Hablemos

Artículos Relacionados