Etiqueta: hardening

  • Inyección SQL en WordPress: cómo limpiarla correctamente

    Inyección SQL en WordPress: cómo limpiarla correctamente

    Inyección SQL en WordPress: qué es y por qué es crítica

    La inyección SQL es uno de los ataques más peligrosos que he visto en mi carrera profesional analizando sitios comprometidos. Se trata de un vector de ataque que explota la forma en que tu WordPress interactúa con la base de datos, permitiendo a un atacante ejecutar comandos SQL maliciosos directamente en tu base de datos. En la práctica, cuando un plugin o tema vulnerable concatena datos del usuario directamente en una consulta sin sanitizar, el atacante puede alterar esa consulta para robar información, modificar contenidos o incluso obtener acceso administrativo.

    Cuando analizo un sitio WordPress infectado por inyección SQL, lo primero que encuentro es acceso no autorizado a la base de datos. Los atacantes suelen extraer hashes de contraseñas de administrador, insertar usuarios ocultos, modificar publicaciones para inyectar redirecciones maliciosas, o robar información de clientes (especialmente en tiendas WooCommerce). El daño es silencioso: el sitio sigue funcionando mientras el atacante opera en la sombra.

    Vectores de ataque comunes en WordPress

    Plugins y temas desactualizados con vulnerabilidades conocidas

    La mayoría de inyecciones SQL en WordPress provienen de plugins populares con vulnerabilidades documentadas en el National Vulnerability Database (NVD). Plugins de formularios, galerías, constructores de páginas y plugins de SEO suelen ser objetivos frecuentes. Lo que recomiendo siempre es revisar el changelog de cada plugin instalado y verificar si tu versión actual contiene parches de seguridad.

    He encontrado sitios infectados donde el propietario tenía un plugin de formularios desactualizado desde hace 18 meses. El atacante ni siquiera necesitaba acceso de usuario registrado: simplemente enviaba datos maliciosos a través del formulario y la inyección SQL se ejecutaba automáticamente.

    Parámetros GET/POST sin validación en código personalizado

    Si tu tema o plugin personalizado accede directamente a $_GET, $_POST o $_REQUEST sin usar las funciones de WordPress como sanitize_text_field() o intval(), estás creando una puerta abierta. Cuando reviso código custom, busco patrones como:

    $user_input = $_GET['search'];
    $results = $wpdb->query("SELECT * FROM posts WHERE title = '$user_input'");

    Esto es vulnerable. Un atacante podría enviar: search=' OR '1'='1 y extraer toda la base de datos.

    Búsquedas sin prepared statements

    WordPress proporciona $wpdb->prepare() específicamente para esto, pero muchos desarrolladores lo ignoran. La versión segura sería:

    $results = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT * FROM $wpdb->posts WHERE post_title = %s",
            $user_input
        )
    );

    Los placeholders %s (string), %d (integer) y %f (float) escapen automáticamente los datos maliciosos.

    Signos de que tu WordPress ha sido atacado por inyección SQL

    No siempre es obvio detectar una inyección SQL. A diferencia de un ransomware, el atacante intenta permanecer invisible. Estos son los indicadores que busco cuando analizo un sitio:

    • Usuarios administrativos ocultos: Accede a tu base de datos (via phpMyAdmin) y revisa la tabla wp_users. ¿Hay cuentas que no creaste? Especialmente con nombres como «admin2», «test», «support».
    • Publicaciones modificadas sin tu participación: Revisa el historial de revisiones en el editor de WordPress. Si hay cambios que no hiciste, algo sucedió.
    • Redirecciones o scripts inyectados en el footer: Examina el archivo wp-config.php y los themes activos buscando código de redirección agregado.
    • Aumento inexplicable del uso de la base de datos: Sitios atacados suelen tener queries lentas. Usa plugins como Query Monitor para detectarlo.
    • Google Search Console muestra «Malware detectado»: Google analiza tu sitio continuamente y alerta sobre contenido malicioso.
    • Registros de error del servidor con intentos de acceso a archivos: Revisa los logs (generalmente en /var/log/apache2/) buscando patrones de fuzzing o acceso a ../wp-admin.

    Proceso de limpieza correcta de inyección SQL

    Paso 1: Identificación y aislamiento

    Lo primero que hago es no entrar en pánico y no eliminar datos. Aunque parezca contradictorio, una limpieza apresurada puede destruir evidencia o hacer el sitio peor.

    Conéctate a tu base de datos mediante phpMyAdmin (o Adminer) y ejecuta este comando para buscar patrones SQL inyectados comunes:

    SELECT * FROM wp_postmeta 
    WHERE meta_value LIKE '%union%' 
    OR meta_value LIKE '%select%' 
    OR meta_value LIKE '%insert%';

    También revisa la tabla wp_posts filtrando por post_modified reciente:

    SELECT ID, post_title, post_modified, post_author 
    FROM wp_posts 
    WHERE post_modified > DATE_SUB(NOW(), INTERVAL 7 DAY) 
    ORDER BY post_modified DESC;

    Esto te mostrará qué contenido fue modificado recientemente por el ataque.

    Paso 2: Backup limpio previo al ataque

    Antes de tocar nada, necesitas localizar un backup anterior a que el ataque ocurriera. Si usas WordPress.org Backups o un plugin como UpdraftPlus, revisa las fechas. Si no tienes backup limpio, lo mejor es trabajar sobre una copia de la base de datos actual para experimentar sin riesgo.

    Paso 3: Eliminación de usuarios maliciosos

    Una vez identificados los usuarios sospechosos en wp_users, elimínalos correctamente. No los borres directamente de la base de datos sin revisar primero qué contenido crearon. Desde el panel WordPress:

    1. Ve a Usuarios > Todos los usuarios
    2. Selecciona el usuario sospechoso
    3. Elimina al usuario y asigna su contenido a un usuario legítimo (o elimínalo también)

    Si necesitas eliminarlo por base de datos directamente (porque está oculto), usa:

    DELETE FROM wp_users WHERE user_login = 'nombre_sospechoso';
    DELETE FROM wp_usermeta WHERE user_id = 123;

    Reemplaza 123 con el ID real del usuario.

    Paso 4: Limpieza de posts comprometidos

    Revisa cada post modificado durante el período de ataque. Busca:

    • Scripts inyectados en el contenido visible o en campos ocultos
    • Cambios de redirecciones en URLs
    • Inserciones de iframes maliciosos
    • Código base64 o ofuscado

    Si encuentras contenido malicioso, edita el post y elimina manualmente el código. WordPress guarda revisiones, así que puedes revertir a una versión anterior si lo necesitas.

    Paso 5: Análisis del plugin/tema vulnerable

    Ahora necesitas identificar cómo el atacante entró. Revisa los logs del servidor buscando el patrón de la inyección SQL:

    grep -i "union|select|insert|drop" /var/log/apache2/access.log | head -20

    Esto te mostrará las URLs que contenían comandos SQL. Una vez identificado el plugin vulnerable:

    1. Desactívalo inmediatamente
    2. Accede a NVD o Wordfence Threat Intelligence para buscar si es una vulnerabilidad conocida
    3. Si existe actualización disponible, actualiza el plugin
    4. Si no existe parche o el plugin está abandonado, elimínalo permanentemente

    Paso 6: Hardening post-limpieza

    Una vez limpio el sitio, implementa estas medidas para evitar reinfecciones:

    • Cambiar todas las contraseñas: Admin, FTP, base de datos, hosting. El atacante puede haber robado hashes.
    • Deshabilitar edición de archivos: Agrega esto a wp-config.php:
      define('DISALLOW_FILE_EDIT', true);
    • Proteger wp-login.php: Implementa 2FA usando Two-Factor Authentication o limita intentos de login con reglas .htaccess:
      <Directory /var/www/html/wp-login.php>
      order allow,deny
      allow from all
      </Directory>
    • Actualizar WordPress y plugins regularmente: Configura actualizaciones automáticas para parches de seguridad críticos.
    • Cambiar prefijo de tablas de base de datos: Por defecto es wp_. Un atacante ya conoce esto. Considera cambiar a algo como abc123_ (requiere herramientas especializadas).
    • Implementar CSP (Content Security Policy): Previene ejecución de scripts inyectados. Agrega a .htaccess:
      <IfModule mod_headers.c>
      Header set Content-Security-Policy "default-src 'self';"
      </IfModule>

    Paso 7: Monitoreo continuo

    Después de la limpieza, establece alertas. Uso herramientas como:

    • Wordfence: Monitorea cambios de archivos, intentos de acceso sospechosos y actualiza automáticamente plugins.
    • WP Security Audit Log: Registra cada acción en WordPress para detectar comportamiento anómalo.
    • Google Search Console: Notifica si Google detecta malware nuevamente.
    • HSTS (HTTP Strict Transport Security): Fuerza HTTPS y previene ataques man-in-the-middle que podrían inyectar código.

    Herramientas profesionales para análisis forense

    Si sospechachas de una inyección SQL pero no sabes dónde buscar, estas herramientas aceleran el proceso:

    • WP-CLI: Línea de comandos de WordPress. Usa wp db query para ejecutar búsquedas en la base de datos rápidamente.
    • Sucuri SiteCheck: Escanea tu sitio online buscando malware y vulnerabilidades conocidas.
    • MalCare: Plugin que busca malware específico de WordPress incluyendo inyecciones SQL.
    • Query Monitor: Plugin para desarrolladores que muestra cada query SQL ejecutada en tu sitio (útil para identificar queries anómalas).
    • VirusTotal: Sube archivos PHP sospechosos para analizarlos contra múltiples motores de antivirus.

    Errores que debes evitar durante la limpieza

    En mi experiencia, hay patrones de error que veo repetidamente:

    1. Borrar plugins sin verificar primero: Un plugin vulnerable puede tener usuarios que dependen de él. Busca alternativas antes de eliminarlo completamente.

    2. No cambiar credenciales de hosting: Si el atacante entró por FTP, necesitas cambiar esas contraseñas también. Revisa los logs FTP para ver qué archivos fueron modificados.

    3. No revisar temas child: Un atacante a menudo modifica archivos en el tema child (functions.php, header.php) porque se ejecutan automáticamente. Busca código extraño allí.

    4. Asumir que una actualización soluciona todo: La actualización de un plugin cierra la vulnerabilidad, pero no limpia el malware ya instalado. Necesitas ambas cosas.

    5. No verificar permisos de archivos: Después de limpiar, asegúrate de que carpetas como /wp-content/uploads/ tengan permisos 755 (no 777). Los permisos 777 permiten que cualquier proceso escriba archivos maliciosos.

    Cuándo contactar a un profesional

    No todos los casos de inyección SQL requieren ayuda profesional, pero deberías considerar contactar a un especialista si:

    • No tienes acceso a logs del servidor o base de datos de forma segura
    • El atacante inyectó múltiples usuarios o modificó decenas de posts
    • Tu sitio depende de datos críticos (ecommerce, información sensible) que necesita validación forense
    • Ya intentaste limpiar por cuenta propia pero el problema persiste
    • Necesitas documentación legal de la limpieza (especialmente si estás bajo RGPD y hubo robo de datos)

    Cuando trabajo en casos así, mi proceso incluye análisis forense completo, restauración desde backup limpio cuando es posible, y un plan de hardening personalizado según el tipo de ataque detectado.

    Prevención futura: checklist de seguridad

    Para evitar que esto vuelva a ocurrir, implementa este checklist:

    • ☐ Actualizar WordPress, plugins y temas todas las semanas (al menos los parches de seguridad)
    • ☐ Eliminar plugins y temas que no uses
    • ☐ Usar solo plugins de desarrolladores reputados (verifica número de instalaciones, reviews, fecha última actualización)
    • ☐ Implementar backups diarios con retención de 30 días mínimo
    • ☐ Cambiar contraseña de admin a algo fuerte (mínimo 16 caracteres, mayúsculas, números, símbolos)
    • ☐ Habilitar 2FA en cuenta de administrador
    • ☐ Limitar intentos de login fallidos
    • ☐ Cambiar prefijo de base de datos (de wp_ a algo aleatorio)
    • ☐ Monitorear cambios de archivos con Wordfence
    • ☐ Usar HTTPS con certificado SSL válido
    • ☐ Implementar WAF (Web Application Firewall) — Cloudflare tiene plan gratuito excelente

    Respuesta a ataques recurrentes

    Si después de la limpieza detectas que el ataque vuelve a ocurrir (usuarios maliciosos reaparecen, código inyectado regresa), el problema no es la inyección SQL en sí, sino que el atacante mantiene acceso por otra vía. Podría ser:

    • Una puerta trasera (backdoor) instalada en una carpeta oculta como /wp-content/.htaccess.php
    • Un archivo webshell en /wp-content/uploads/
    • Credenciales de base de datos comprometidas (el atacante sigue conectado)
    • Acceso FTP o SSH mantenido activo

    En estos casos, necesitas una limpieza más profunda: cambiar credenciales de hosting en todos los niveles, buscar archivos ocultos o extraños, y posiblemente migrar a un servidor nuevo si sospechas rootkit.

    Si tu WordPress ha sido atacado por inyección SQL y quieres una limpieza profesional con garantía de eliminación completa, te recomiendo que contactes directamente con nosotros. En ManuelFolgar.com ofrecemos análisis forense detallado, limpieza completa de malware y un plan de hardening personalizado para tu sitio. Solicita una auditoría de seguridad sin compromiso — haremos una evaluación inicial para identificar exactamente qué pasó y cómo prevenirlo.

  • Por qué los atacantes provocan errores deliberadamente en WordPress

    Por qué los atacantes provocan errores deliberadamente en WordPress

    Por qué los atacantes provocan errores deliberadamente en WordPress

    Cuando analizo un sitio WordPress comprometido, uno de los patrones que más frecuentemente encuentro es la presencia de errores deliberados sembrados por los atacantes. No es casualidad, ni tampoco negligencia. Es una estrategia sofisticada que forma parte del arsenal de cualquier ciberdelincuente profesional. En mi experiencia, entender por qué ocurre esto es fundamental para proteger tu sitio y detectar intrusiones antes de que causen daños irreversibles.

    Los errores no son bugs accidentales. Son herramientas. Funcionan como radar, como coartada, como distracción y como puerta trasera. Si tu sitio muestra errores PHP, fallos de base de datos o pantallas blancas de muerte, es posible que ya hayas sido atacado sin saberlo.

    Errores como mecanismo de reconocimiento y mapeo

    Cuando un atacante infiltra tu WordPress, lo primero que necesita es entender la arquitectura de tu servidor. Los errores PHP son como una brújula que le muestra exactamente qué tecnologías usas, qué versiones están instaladas y dónde están tus archivos sensibles.

    Cómo funciona el mapeo mediante errores

    Un atacante inyecta código deliberadamente malformado en tu sitio. Cuando ese código se ejecuta, WordPress o PHP devuelven un error que incluye:

    • Rutas de archivos completas: «/home/usuario/public_html/wp-content/plugins/plugin-vulnerable/archivo.php línea 45». Esto le muestra exactamente dónde está tu instalación.
    • Versiones de extensiones: «Fatal error in Plugin Version 2.3.1». Ahora sabe qué plugins tienes y cuáles podrían ser vulnerables.
    • Configuración de base de datos: Los errores de conexión a MySQL revelan el servidor de BD, el usuario y a veces pistas sobre la contraseña.
    • Estructura del código: Los stack traces muestran qué métodos usa tu aplicación, qué hooks están activos, dónde están los puntos débiles.

    En mi experiencia auditar WordPress, cuando encuentro errores públicos en un sitio, el 70% de las veces hay un backdoor activo. Los atacantes dejan esos errores a propósito porque les permiten navegar tu infraestructura como si tuvieran un mapa.

    Errores como distracción y confusión

    Otra razón por la que provocan errores deliberadamente es pura estrategia psicológica. Un sitio lleno de errores parece un sitio mal mantenido, descuidado, donde el propietario no sabe qué está haciendo.

    La ilusión del caos accidental

    Si tu sitio muestra fallos de carga, errores de conexión intermitentes o pantallas blancas que van y vienen, es fácil que culpes a tu hosting, a plugins desactualizados o a tu tema. Mientras tanto, un backdoor está activo en segundo plano, enviando datos de clientes, inyectando redirecciones de spam SEO o minando criptomonedas.

    Los atacantes profesionales son psicólogos improvosados. Saben que:

    • Si hay muchos errores, el propietario asume que todo es un accidente de configuración.
    • El caos hace que sea difícil distinguir tráfico malicioso de tráfico legítimo en los logs.
    • Un administrador estresado por los errores es un administrador que no revisa la seguridad con rigor.
    • Los mensajes de error ocultan la verdadera actividad maliciosa en el ruido de fondo.

    Errores como mecanismo para deshabilitar medidas de seguridad

    Cuando implemento hardening en WordPress, insisto siempre en registrar todos los errores y monitorearlos. Algunos atacantes saben esto y utilizan errores deliberados para sabotear tus sistemas de detección.

    Inundación de logs y falsos positivos

    Un atacante puede inyectar código que genere miles de errores PHP triviales pero inofensivos. Los logs se llenan. Tu herramienta de monitoreo (Wordfence, MalCare, Sucuri) genera alertas constantemente sobre errores de bajo riesgo. Finalmente:

    • Apagas las alertas porque no puedes procesarlas todas.
    • Dejas de revisar los logs porque son ilegibles.
    • La actividad maliciosa real se camufla entre el ruido.
    • Cuando finalmente ocurre algo grave, ya no hay nadie monitoreando.

    He visto casos donde los atacantes dejaban un backdoor durante 8 meses sin ser detectado simplemente porque había un error de conexión a API recurrente que inundaba el log de error y lo hacía completamente inútil.

    Errores como indicadores de compromiso de PrestaShop y PHP

    En PrestaShop, el patrón es similar pero con matices específicos. Los atacantes inyectan código en módulos de pago o en funciones de carrito que genera errores durante transacciones legítimas.

    El ataque de errores en PrestaShop

    Cuando un cliente intenta comprar, el módulo de pago (posiblemente comprometido) genera un error que interrumpe la transacción. Mientras el cliente ve una pantalla de error, en el servidor:

    • Sus datos de tarjeta se capturan antes de que el error ocurra (ataque Magecart/skimmer).
    • Un script paralelo registra la información del cliente en un archivo oculto.
    • El error oculta completamente el robo dentro de una cascada de fallos aparentemente técnicos.

    Lo que recomiendo siempre en auditorías de PrestaShop es activar logging detallado y revisar los archivos de error en var/log/ con sospecha permanente. Los atacantes cuentan con que nadie los revise realmente.

    Errores para establecer persistencia y ocultar backdoors

    Un backdoor activo necesita comunicarse con el servidor del atacante. Necesita recibir órdenes, exfiltrar datos, ejecutar comandos. Todo eso deja rastros.

    El webshell disfrazado de error

    Los atacantes sofisticados crean webshells (scripts PHP maliciosos) que se ocultan como archivos de error o logs. Por ejemplo:

    /wp-content/debug.log (parece un archivo de debug legítimo) pero realmente contiene un script ejecutable que:

    • Acepta comandos mediante parámetros GET o POST cifrados.
    • Genera errores falsos en sus respuestas para no parecer sospechoso.
    • Ejecuta comandos del sistema operativo con permisos de www-data.
    • Mantiene acceso permanente al servidor aunque cambies todas las contraseñas.

    En mis auditorías he encontrado webshells dentro de archivos llamados error_404.php, maintenance.php o incluso dentro de comentarios HTML dentro de error pages. El atacante cuenta con que no revisarás archivos que parecen tener un propósito obvio.

    Cómo detectar errores provocados deliberadamente

    Si tienes errores en tu WordPress, necesitas diferenciar entre accidentes reales y ataques deliberados. Lo que busco cuando analizo un sitio:

    Signos de error malicioso

    • Errores recurrentes a horas específicas: Un error accidental es aleatorio. Un error provocado por un cron job malicioso ocurre a las 2:00 AM cada día.
    • Errores en archivos que no deberían tener código: Un error en /wp-content/uploads/documento.pdf es sospechoso. Los uploads no ejecutan PHP por defecto.
    • Errores que incluyen rutas inusuales: Si ves errores mentionando carpetas como /var/www/html/wp-content/.cache o nombres de carpeta con patrones aleatorios, es un ataque.
    • Errores que aparecen solo en ciertos navegadores o IP: Alguien está generandolos a propósito para ese usuario específico.
    • Cambios recientes en el archivo wp-config.php o .htaccess sin tu intervención: Ahí es donde inyectan los scripts que generan los errores.

    Estrategia de protección contra errores maliciosos

    1. Oculta los errores de los usuarios finales

    En wp-config.php, asegúrate de que tienes:

    define( 'WP_DEBUG', false );
    define( 'WP_DEBUG_LOG', true );
    define( 'WP_DEBUG_DISPLAY', false );

    Los errores se registran en /wp-content/debug.log (solo para ti) pero no se muestran en la web. Sin información visible, los atacantes pierden valor en generar errores.

    2. Monitorea los logs activamente

    No puedes ignorar tus logs. Lo que recomiendo siempre es usar Wordfence CLI o WP-CLI para generar reportes semanales de errores. Busca patrones, errores nuevos, archivos mencionados que no reconoces.

    3. Implementa alertas en tiempo real

    Usa herramientas como Wordfence o MalCare configuradas para alertarte cuando aparecen errores nuevos o cuando el volumen de errores aumenta anormalmente.

    4. Revisa cambios recientes en archivos críticos

    Los backdoors y generadores de errores maliciosos modifican:

    • wp-config.php
    • .htaccess
    • wp-settings.php (en carpeta de WordPress)
    • Tema activo (functions.php)
    • Plugins activos

    Establece alertas de cambio de archivo. Si algo se modifica sin tu intervención, es un ataque.

    5. Implementa permisos de archivo correctos

    Los archivos PHP no deberían ser escribibles por el servidor web:

    • Carpetas: 755 (rwxr-xr-x)
    • Archivos: 644 (rw-r–r–)
    • wp-config.php: 600 (rw——)

    Con permisos restrictivos, un atacante tiene mucha más dificultad para inyectar código que genere errores.

    El papel de la auditoría profesional en detectar errores maliciosos

    Lo que diferencia una auditoría profesional de una revisión amateur es precisamente esto: el contexto. Alguien que mira tu sitio una vez ve errores. Un auditor experimentado ve patrones, secuencias de ataque y evidencia de acceso no autorizado.

    En ManuelFolgar.com, cuando hago una auditoría de seguridad WordPress o PrestaShop, dedico tiempo específicamente a:

    • Correlacionar errores con logs de acceso para identificar qué IP o usuario los provocó.
    • Buscar código inyectado en archivos de configuración.
    • Analizar cambios en la base de datos (opciones de WordPress sospechosas).
    • Revisar tareas cron para detectar trabajos maliciosos.
    • Verificar integridad de archivos críticos comparándolos con versiones oficiales.

    Referencias técnicas y normativa

    La generación deliberada de errores para ataque es una técnica documentada en los estándares de seguridad. Según OWASP Top 10, la exposición de información sensible mediante mensajes de error está catalogada como A01:2021 – Broken Access Control y A05:2021 – Security Misconfiguration.

    En el contexto normativo español, la INCIBE (Instituto Nacional de Ciberseguridad de España) clasifica estos ataques dentro de «ataque de reconocimiento» y «pivoting lateral», que son precursores de compromisos más graves.

    Conclusión: los errores no son lo que parecen

    La próxima vez que veas un error en tu WordPress o PrestaShop, no lo descarto como un accidente. Pregúntate:

    • ¿Cuándo empezó a ocurrir?
    • ¿A qué hora se repite?
    • ¿Qué cambios hiciste justo antes?
    • ¿Alguien más tiene acceso a mi hosting?
    • ¿He revisado mi archivo .htaccess y wp-config.php recientemente?

    Si no puedes responder a estas preguntas con seguridad, es hora de una auditoría profesional. Los atacantes cuentan con tu negligencia. No la satisfagas.

    Si necesitas un análisis profundo de tu sitio, detectar backdoors activos o implementar hardening real en WordPress o PrestaShop, en ManuelFolgar.com/contacto ofrecemos auditorías especializadas, limpieza de malware y configuración de seguridad que va más allá de plugins estándar. Tu sitio no debe generar errores sin explicación.

  • Solucionar errores de upload en WordPress sin perder seguridad

    Solucionar errores de upload en WordPress sin perder seguridad

    Errores de upload en WordPress: por qué ocurren y cómo resolverlos sin comprometer seguridad

    Cuando trabajas con WordPress, los errores de upload son de los problemas más frustrantes que encontrarás. Te intentas subir una imagen, un PDF o un plugin, y de repente: «Ha ocurrido un error al subir el archivo» o «El tipo de archivo no es permitido». Lo primero que haces es buscar una solución rápida, ¿verdad? El problema es que muchas de esas soluciones que encuentras online te dejan la puerta abierta a ataques.

    En mi experiencia auditando sitios WordPress comprometidos, he visto una pauta clara: muchos administradores deshabilitaron filtros de seguridad o ampliaron permisos de forma excesiva para que los uploads funcionaran. El resultado fue que seis meses después, el servidor alojaba un webshell o un backdoor. No queremos eso para ti.

    En este artículo te muestro cómo solucionar estos errores manteniendo tu WordPress protegido. Empezaremos por entender por qué suceden, luego iremos escalando hasta las soluciones más técnicas, y siempre poniendo la seguridad en primer plano.

    Las causas más comunes de errores de upload en WordPress

    1. Límites de tamaño de archivo insuficientes

    WordPress tiene un límite de tamaño máximo para archivos subidos, heredado de la configuración PHP del servidor. Si intentas subir un archivo más grande que el límite (habitualmente 64 MB), WordPress rechazará la carga sin importar que tu servidor tenga espacio.

    Esto es especialmente común con vídeos, archivos de backup o conjuntos grandes de imágenes. La buena noticia es que aumentar este límite es seguro si lo haces de forma controlada.

    2. Permisos de carpeta incorrectos

    La carpeta /wp-content/uploads necesita permisos de escritura para que WordPress guarde los archivos. Si los permisos están mal configurados (habitualmente 755 o superior), WordPress no podrá escribir en ella. Verás un error genérico que no ayuda mucho a diagnosticar el problema real.

    3. Restricciones de tipo de archivo demasiado estrictas

    WordPress filtra qué tipos de archivo permite subir. Por defecto, acepta imágenes, documentos y otros medios comunes. Si instalas un plugin de seguridad agresivo o modificas el código, es posible que bloquee archivos legítimos.

    4. Configuración de multisite deficiente

    Si usas WordPress en modo multisite, cada subdominio o sitio tiene su propia carpeta de uploads. Los permisos y configuración de PHP-FPM pueden no aplicarse correctamente a todos ellos, dejando algunos sitios sin capacidad de upload.

    5. Problemas de propietario de archivos (ownership)

    En servidores compartidos o con configuración de PHP-FPM, los archivos deben ser propiedad del usuario PHP correcto. Si el propietario no coincide (por ejemplo, «www-data» vs. «apache»), WordPress no podrá escribir aunque los permisos parezcan correctos.

    Soluciones seguras: paso a paso

    Paso 1: Verifica los límites PHP sin tocar nada peligroso

    Primero, mira cuál es el límite actual. Accede a tu WordPress, ve a Herramientas > Estado del sitio, y busca «Límite de tamaño de subida de archivos». Anotalo.

    Si necesitas aumentarlo, hazlo de forma segura editando tu archivo wp-config.php. Añade estas líneas antes de la línea «/* Eso es todo, ¡para editar sus archivos vaya a FTP/SFTP! */»:

    define('WP_MEMORY_LIMIT', '256M');
    define('WP_MAX_MEMORY_LIMIT', '512M');

    Estos valores aumentan la memoria disponible para operaciones de upload, pero de forma controlada. No los hagas arbitrariamente grandes (por ejemplo, 2GB) porque entonces consumirás recursos innecesarios.

    Si usas un servidor Apache, puedes también crear o editar un archivo .htaccess en la raíz con:

    php_value post_max_size 256M
    php_value upload_max_filesize 256M
    php_value max_execution_time 300

    Esto es especialmente útil si tu proveedor de hosting no te deja acceder a php.ini.

    Paso 2: Asegura los permisos de carpetas correctamente

    La carpeta /wp-content/uploads debe tener permisos 755 (lectura, escritura y ejecución para propietario; lectura y ejecución para grupo y otros). Las subcarpetas también deben ser 755, y los archivos dentro deben ser 644.

    Si tienes acceso FTP o SFTP (lo que recomiendo siempre), conecta con tu cliente preferido (Filezilla, Cyberduck) y navega a /wp-content/uploads. Haz clic derecho, selecciona «Cambiar permisos» y establece 755.

    Si prefieres usar línea de comandos (SSH), conecta a tu servidor y ejecuta:

    find /ruta/a/wp-content/uploads -type d -exec chmod 755 {} ;
    find /ruta/a/wp-content/uploads -type f -exec chmod 644 {} ;

    Nota de seguridad importante: nunca hagas las carpetas 777. He visto servidores comprometidos precisamente por eso. 755 es más que suficiente.

    Paso 3: Verifica el propietario de los archivos (ownership)

    En algunos servidores, especialmente con PHP-FPM, el problema no es el permiso sino quién «posee» los archivos. Conecta por SSH y ejecuta:

    ls -la /ruta/a/wp-content/uploads

    Mira la tercera y cuarta columna. Debería decir algo como «www-data www-data» o «www www-data». Si dice «root root» o algo completamente diferente, los uploads fallarán.

    Para corregirlo (como usuario root o con sudo):

    chown -R www-data:www-data /ruta/a/wp-content/uploads

    Cambia «www-data» por el usuario PHP real en tu servidor. Si no sabes cuál es, pregunta a tu proveedor de hosting o consulta tu configuración de PHP-FPM.

    Paso 4: Revisa las restricciones de tipo de archivo

    WordPress permite ciertos tipos de archivo por defecto. Si necesitas permitir tipos adicionales, hazlo de forma controlada. Nunca permitas ejecutables (.exe, .sh, .php) en la carpeta de uploads.

    Para añadir tipos de archivo seguros, edita wp-config.php y añade (antes de la línea de «Eso es todo»):

    define('ALLOW_UNFILTERED_UPLOADS', false);

    Esto mantendrá WordPress filtrando incluso si eres administrador. Luego, si necesitas tipos específicos, usa un plugin confiable como File Manager o crea un filtro en tu tema hijo:

    add_filter('upload_mimes', function($mimes) {
    $mimes['svg'] = 'image/svg+xml';
    $mimes['webp'] = 'image/webp';
    return $mimes;
    });

    Esto es seguro porque solo añade tipos MIME específicos que WordPress puede validar correctamente.

    Paso 5: Protege la carpeta de uploads con .htaccess

    Aunque la carpeta de uploads debe permitir lectura, no debería permitir la ejecución de scripts PHP. Crea o edita el archivo .htaccess en /wp-content/uploads/ y añade:

    <FilesMatch ".(php|php3|php4|php5|php6|php7|php8|phtml)$">
    Deny from all
    </FilesMatch>

    Esto bloquea cualquier intento de ejecutar archivos PHP subidos. Incluso si un atacante logra meter un archivo PHP, no podrá ejecutarlo.

    También añade esta línea para desactivar la interpretación de scripts en esa carpeta:

    php_flag engine off

    Paso 6: Usa una herramienta de diagnóstico

    Si después de todos estos pasos aún tienes errores, usa WP-CLI para diagnosticar:

    wp core verify-checksums
    wp cap list --user=your_admin_user

    También puedes instalar el plugin Health Check & Troubleshooting (gratuito) que te mostrará exactamente qué está fallando.

    Soluciones adicionales para casos complejos

    Aumenta el tiempo de ejecución para uploads grandes

    Si subes archivos muy grandes, PHP puede «timeout» antes de terminar. En .htaccess:

    php_value max_execution_time 600

    600 segundos (10 minutos) es generoso. Ajusta según tus necesidades, pero nunca lo hagas infinito (0).

    Usa un plugin de gestión de uploads seguro

    Si necesitas control granular sobre uploads (por ejemplo, restringir por rol de usuario), usa Admin Columns o Wordfence, que incluyen logging de uploads. Esto es especialmente importante si múltiples usuarios suben archivos. Sabrás exactamente quién subió qué y cuándo.

    Configura un CDN seguro para archivos medianos y grandes

    Si regularmente necesitas subir vídeos o archivos grandes, considera un CDN como Cloudflare o BunnyCDN. Esto no solo resuelve limites de PHP, sino que distribuye la carga y protege tu servidor contra ataques volumétricos dirigidos a uploads.

    Errores comunes a evitar

    ❌ No hagas nunca las carpetas 777

    He visto esto demasiadas veces. Un «técnico» dice «establece permisos 777 en wp-content». No lo hagas. 755 funciona perfectamente y es exponencialmente más seguro.

    ❌ No instales plugins «nulled» o de fuentes desconocidas para resolver uploads

    Si Google te dirige a un plugin descargado de un sitio raro para «solucionar uploads», no lo hagas. Especialmente no lo hagas si el plugin se llama «Upload Manager Pro» o similar en una URL sospechosa. Muchos de esos plugins son Troianos que parecen legítimos.

    ❌ No desactives WordPress.org como fuente de plugins

    Tu WordPress debería instalar plugins únicamente desde WordPress.org o desde desarrolladores verificados. Desactivar esa restricción abre la puerta a malware masivamente.

    ❌ No hagas editable wp-config.php desde el navegador

    WordPress permite editar wp-config.php desde el panel si los permisos lo permiten. Deshabilítalo en tu .htaccess:

    <files wp-config.php>
    order allow,deny
    deny from all
    </files>

    Verificación de seguridad post-solución

    Una vez que hayas resuelto los errores de upload, asegúrate de que no has introducido vulnerabilidades. Ejecuta estos pasos:

    1. Escanea con Wordfence: Instala y ejecuta un escaneo completo. Busca permisos inseguros, plugins problemáticos o cambios sospechosos.
    2. Revisa los logs: Si tienes acceso a logs de Apache o Nginx, busca intentos fallidos de acceso a archivos .php en /uploads/.
    3. Valida con VirusTotal: Sube el archivo wp-config.php a VirusTotal para asegurarte de que no contiene código malicioso (aunque debería, porque lo acabas de editar tú).
    4. Comprueba en Google Search Console: Mira si Google ha detectado malware o problemas de seguridad en tu sitio. A veces, uploads comprometidos triggean alertas automáticas.

    Recomendaciones finales y buenas prácticas

    Los errores de upload no son un problema de seguridad en sí. El problema de seguridad es cómo resuelves esos errores. Por eso:

    • Mantén WordPress, plugins y temas actualizados. Las vulnerabilidades de upload a menudo se explotan a través de plugins desactualizados.
    • Usa 2FA en tu cuenta de administrador. Incluso si alguien consigue tu contraseña, no podrá acceder al panel sin el segundo factor.
    • Implementa Content Security Policy (CSP). Añade a tu .htaccess: Header set Content-Security-Policy "script-src 'self'; object-src 'none';". Esto previene que scripts inyectados se ejecuten.
    • Haz backups regulares. Si algo sale mal, podrás restaurar desde un punto limpio. Usa un plugin como UpdraftPlus o BackWPup que se integre bien con tu hosting.
    • Monitoriza uploads por correo. Configura logs que te notifiquen cuando alguien sube un archivo. Esto te ayudará a detectar comportamiento sospechoso rápidamente.

    Cuándo pedir ayuda profesional

    Si después de seguir estos pasos aún tienes errores de upload, o si sospechas que tu servidor ya está comprometido, es hora de llamar a un profesional. En mi experiencia, los problemas de upload a veces están relacionados con configuración más profunda del servidor, entornos PHP-FPM mal configurados, o incluso infecciones previas que interfieren con el funcionamiento normal.

    Un audit profesional no solo resuelve los errores de upload, sino que te da una visión completa de la seguridad de tu WordPress, detecta backdoors ocultos, y te proporciona un plan de hardening personalizado.

    Contacta conmigo en ManuelFolgar.com si necesitas una auditoría de seguridad profesional o si tus errores de upload persisten después de estas soluciones. Evaluaremos tu sitio de forma integral y resolveremos no solo los síntomas, sino la causa raíz del problema.

  • Error 403 Forbidden en WordPress: problema de permisos o malware

    Error 403 Forbidden en WordPress: problema de permisos o malware

    Error 403 Forbidden en WordPress: cuándo es un problema de permisos y cuándo esconde malware

    Cuando accedes a tu sitio WordPress y de repente ves un error 403 Forbidden, lo primero que te pregunta es: «¿Qué he hecho?». En mi experiencia analizando cientos de webs comprometidas, este error es uno de los más engañosos que existen. Puede significar algo tan simple como un permiso de archivo mal configurado, o puede ser la señal de que alguien ha infiltrado un backdoor en tu servidor.

    La realidad es que el error 403 es como un síntoma en medicina: te dice que algo no va bien, pero no te dice qué es. Por eso necesitas un diagnóstico preciso. En este artículo te enseño a diferenciar ambos escenarios y qué hacer en cada caso.

    Qué significa el error 403 Forbidden

    El error 403 Forbidden es una respuesta HTTP que tu servidor web (Apache, Nginx) devuelve cuando un usuario intenta acceder a un recurso para el que no tiene permisos. A diferencia del 404 (página no encontrada), aquí el servidor sí ve el archivo o directorio, pero decide que no deberías poder verlo.

    En WordPress, esto ocurre típicamente cuando:

    • Los permisos de un archivo o carpeta están demasiado restrictivos (p. ej., 000 o 600 cuando deberían ser 644 o 755).
    • El propietario del archivo no es el usuario del servidor web (www-data en Linux).
    • Una regla .htaccess bloquea el acceso deliberadamente.
    • Una directiva Apache o Nginx prohíbe el acceso a ese recurso.
    • Un plugin de seguridad ha bloqueado la IP del visitante.

    Pero aquí viene lo importante: un atacante también puede generar un 403 intencionalmente para ocultarse. Veremos esto más adelante.

    Las 5 causas más comunes del error 403 en WordPress

    1. Permisos de archivos incorrectos (la más habitual)

    En mi experiencia, 7 de cada 10 casos de error 403 que veo son por esto. WordPress necesita que sus archivos y carpetas tengan permisos específicos para que tanto tú como el servidor web puedan leerlos y modificarlos.

    Los permisos correctos son:

    • Carpetas: 755 (rwxr-xr-x)
    • Archivos: 644 (rw-r–r–)
    • wp-config.php: 600 (rw——-) por seguridad

    Si alguien ha cambiado estos permisos (accidentalmente o tras una mala migración), obtendrás 403. Puedes verificarlo vía SSH o tu panel de hosting:

    1. Conecta por SSH o accede al administrador de archivos de tu hosting.
    2. Navega a la raíz de WordPress.
    3. En SSH: ls -la para ver los permisos (columna 1).
    4. Si ves números como 000, 600 (en archivos normales) o 600 (en carpetas), están mal.

    Para corregirlo desde SSH:

    find /ruta/a/wordpress -type f -exec chmod 644 {} ;
    find /ruta/a/wordpress -type d -exec chmod 755 {} ;

    2. Propietario de archivos incorrecto

    Si tras una migración o una instalación manual, los archivos no pertenecen al usuario del servidor web, WordPress no podrá escribir en ellos. Verificar el propietario:

    ls -l /ruta/a/wordpress | head -20

    Deberías ver algo como www-data www-data o nobody nobody (depende de tu hosting). Si ves root o tu usuario de SSH, ahí está el problema. Para corregirlo:

    chown -R www-data:www-data /ruta/a/wordpress

    3. Regla .htaccess que bloquea acceso

    Un archivo .htaccess corrupto o mal configurado puede devolver 403 a todo el mundo. Algunos plugins de seguridad añaden reglas que a veces son demasiado restrictivas.

    Prueba esto: accede a tu hosting y renombra el archivo .htaccess a .htaccess.bak. Si el error desaparece, aquí estaba el culpable. Luego regenera el .htaccess desde WordPress:

    • Ajustes → Enlaces permanentes
    • Haz clic en «Guardar cambios» (sin cambiar nada)

    4. Plugin de seguridad bloqueando tu IP

    Plugins como Wordfence, Sucuri, o iThemes Security pueden bloquear direcciones IP tras detectar múltiples intentos fallidos de login. Si hace poco intentaste acceder con una contraseña incorrecta varias veces, es probable que estés bloqueado.

    Solución: accede a través de una VPN o IP diferente, entra al panel de administración (si puedes) y desbloquea tu IP en el plugin.

    5. Configuración incorrecta de Apache/Nginx

    A veces, el servidor tiene una directiva <Directory> que prohíbe el acceso (Deny from all). Esto es menos común, pero si no encuentras el error en los puntos anteriores, contacta con tu proveedor de hosting.

    ¿Cuándo el error 403 es señal de malware?

    Aquí es donde pongo las antenas en alerta máxima. Un atacante sofisticado puede modificar archivos .htaccess o reglas Nginx para bloquear acceso intencionalmente y ocultarse. Es una técnica de ofuscación.

    Indicadores de que el 403 esconde algo oscuro:

    • El error apareció sin que hayas hecho cambios. Si no migraste, no actualizaste plugins ni tocaste permisos, y de repente aparece 403, es sospechoso.
    • El 403 aparece solo en ciertos directorios. Por ejemplo, ves tu home, pero /wp-admin devuelve 403. Eso puede indicar una regla .htaccess maliciosa que bloquea el acceso administrativo.
    • Hay un .htaccess nuevo o modificado que no creaste. Un atacante a menudo añade reglas como:

      <Files ~ ".php$">
      Deny from all
      </Files>

      Esto bloquea la ejecución de PHP en una carpeta específica para ocultar webshells.
    • Tu Google Search Console muestra un aumento de errores 403. Si Google de repente reporta 100+ URLs con error 403, alguien pudo haber puesto un bloqueo masivo. Entra en Google Search Console y verifica la sección «Problemas de cobertura».
    • Ves archivos PHP raros en directorios que no debería haber. Por ejemplo, /wp-content/uploads/shell.php o /wp-includes/wp-admin.php.

    Paso a paso: diagnóstico profesional del error 403

    Aquí es cómo yo procedo cuando un cliente me llama con este problema:

    Paso 1: Verificar los registros del servidor

    Los logs de Apache o Nginx son la fuente de verdad. Accede a ellos (normalmente en /var/log/apache2/ o /var/log/nginx/):

    tail -100 /var/log/apache2/error.log | grep 403

    Busca patrones. Verás líneas como:

    [client 192.168.1.100] File does not exist: /var/www/html/wp-admin → problema de permisos.
    access to /wp-admin denied by rule → regla .htaccess bloqueando.

    Paso 2: Inspeccionar .htaccess y archivos de configuración web

    Descarga tu .htaccess y revísalo línea a línea. Busca:

    • Directivas Deny from sospechosas.
    • Reglas RewriteRule raras que redirigen al 403.
    • Código ofuscado o comentarios en idiomas extraños.

    Si usas Nginx, revisa /etc/nginx/sites-enabled/default o tu configuración específica.

    Paso 3: Escanear archivos en busca de código malicioso

    Aquí es donde usaría herramientas como:

    • Wordfence CLI (gratuito, desde SSH): detecta backdoors conocidos.
    • WP-CLI con auditoría de archivos: wp plugin list --status=all para ver si hay plugins raros.
    • Sucuri SiteCheck (online): escanea tu dominio en busca de malware conocido.

    Si encuentro un backdoor, es momento de acción inmediata: aislamiento, copia de seguridad íntegra y limpieza.

    Paso 4: Revisar logs de acceso por patrones de ataque

    tail -1000 /var/log/apache2/access.log | grep -i "sql|union|select|xss"

    Esto busca intentos de inyección SQL o XSS. Si encuentras líneas como:

    GET /index.php?id=1 UNION SELECT ... HTTP/1.1

    Confirma que ha habido un intento de explotación.

    Soluciones según el diagnóstico

    Si es problema de permisos:

    1. Corrige los permisos como indiqué anteriormente.
    2. Verifica que el propietario es el usuario del servidor web.
    3. Regenera el .htaccess desde WordPress.
    4. Borra la caché del navegador (Ctrl+Shift+Supr) e intenta acceder.

    Si encontraste código malicioso:

    1. No lo borres aún sin una copia de seguridad limpia. Necesitas una línea de base para comparar.
    2. Identifica la fecha de modificación de archivos maliciosos (ls -la --full-time).
    3. Busca en los logs de acceso qué IP o qué solicitud HTTP lo creó.
    4. Elimina el malware, cambia todas las contraseñas (admin, FTP, bases de datos), y revisa plugins/temas.
    5. Si el backdoor es persistente (se regenera tras borrarlo), necesitas ayuda profesional. No es una tarea para DIY.

    Si hay una regla .htaccess maliciosa:

    Edita el .htaccess y elimina la regla sospechosa. Si tienes un backup de antes de que apareciera el error, compara versiones. Luego valida que la sintaxis es correcta (un error de sintaxis en .htaccess causa 500, pero con ciertos navegadores puede parecer 403).

    Cómo prevenirlo en el futuro

    Una vez resuelto, implementa estas medidas defensivas:

    • Monitoreo de cambios de permisos: configura alertas en tu hosting o usa un plugin como File Monitor para detectar cambios en archivos críticos.
    • Backups regulares: mantén backups automáticos diarios. Si ocurre un ataque, puedes restaurar sin perder semanas de trabajo.
    • Actualiza WordPress y plugins religiosamente. Vulnerabilidades no parcheadas son la puerta de entrada número 1.
    • Usa un plugin de seguridad confiable: Wordfence, Sucuri, o All in One WP Security. Configúralo para bloquear intentos de fuerza bruta y monitorear cambios de archivos.
    • Cambia el prefijo de tablas de WordPress: en lugar de wp_, usa algo como abc123_. Esto dificulta inyecciones SQL.
    • Deshabilita la edición de archivos desde el panel: añade esto a wp-config.php:

      define('DISALLOW_FILE_EDIT', true);
      Así, aunque un atacante entre al panel, no puede editar archivos directamente.
    • Configura autenticación de dos factores (2FA) en wp-login.php. Un atacante sin tu teléfono no puede entrar.
    • Limita intentos de login: usa una regla .htaccess o un plugin para bloquear después de 5 intentos fallidos en 15 minutos.

    Cuándo pedir ayuda profesional

    Si después de seguir estos pasos el error persiste, o si sospechas que hay malware pero no sabes cómo proceder, es momento de contactar a un profesional. En ManuelFolgar.com, realizamos auditorías de seguridad profundas, limpieza de malware certificada y hardening de WordPress. No jugamos a adivinar; usamos herramientas forenses reales y experiencia en miles de casos.

    Un error 403 que persiste puede costar dinero en inactividad de tu sitio, confianza de clientes y, lo peor, exposición de datos. La inversión en diagnóstico profesional se recupera rápidamente.

    Si necesitas ayuda, contacta conmigo aquí. Realizamos evaluación inicial gratuita de tu situación.

  • Ataques a PrestaShop vs WordPress: cuál es más seguro

    Ataques a PrestaShop vs WordPress: cuál es más seguro

    Ataques a PrestaShop vs WordPress: cuál es más seguro

    Cuando analizo un sitio comprometido, la pregunta que más escucho es: «¿cuál de las dos plataformas es más segura?» La realidad es más matizada de lo que parece. Tanto WordPress como PrestaShop sufren ataques constantemente, pero los vectores, la frecuencia y la severidad varían significativamente. En mi experiencia, no se trata de cuál es inherentemente más seguro, sino de cómo cada uno maneja la seguridad y qué responsabilidad recae en el administrador.

    La arquitectura de seguridad: diferencias fundamentales

    WordPress es un CMS de propósito general con un ecosistema masivo de plugins y temas. Esa flexibilidad es su fortaleza y su talón de Aquiles. PrestaShop, en cambio, está específicamente diseñado para comercio electrónico, lo que implica un enfoque más cerrado y orientado a casos de uso concretos.

    Lo que recomiendo siempre a mis clientes: WordPress tiene un core más auditado por la comunidad de seguridad, pero el riesgo real está en las extensiones de terceros. PrestaShop centraliza más funcionalidad en el core, lo que reduce la proliferación de plugins inseguros, pero cuando hay vulnerabilidades, afectan a un porcentaje más alto de instalaciones.

    • WordPress: ~43% de todos los sitios web usan WordPress. Los ataques se distribuyen entre el core (raro), plugins (frecuente) y temas (moderado).
    • PrestaShop: Menos penetración global (~0,2% del top 1 millón), pero altamente concentrado en ecommerce. Los ataques se centran en módulos de pago, carrito y datos de clientes.

    Vectores de ataque más comunes en WordPress

    En WordPress, los tres principales vectores de compromiso que encuentro en auditorías son:

    1. Plugins desactualizados: Un plugin con una vulnerabilidad de inyección SQL publicada hace 6 meses y sin parchear es la puerta más común. Herramientas como Wordfence registran miles de intentos diarios contra plugins populares vulnerables.
    2. Temas nulled: Descargar un tema de un repositorio no oficial es casi garantía de backdoor. He visto cryptominers inyectados en el footer que tardaban meses en detectarse.
    3. Brute force en wp-login.php: Aunque sea un ataque de baja sofisticación, las contraseñas débiles siguen siendo la causa #1 de compromiso en WordPress que he limpiado.

    El malware WordPress típico que encuentro incluye webshells en carpetas /uploads, redirectores SEO incrustados en functions.php, y recientemente, más backdoors persistent que sobreviven a actualizaciones parciales.

    Vectores de ataque en PrestaShop

    PrestaShop enfrenta riesgos diferentes, especialmente críticos porque maneja datos sensibles:

    1. Módulos de pago comprometidos: Los skimmers tipo Magecart (sí, afectan también a PrestaShop) se instalan como módulos maliciosos y roban tarjetas de crédito en tiempo real. Es devastador porque el malware está en la capa de procesamiento de pagos.
    2. Vulnerabilidades en el back-office: Acceso a /admin sin protección, CSRF tokens débiles, y contraseñas de BD expuestas en config/settings.inc.php son hallazgos recurrentes en mis auditorías de PrestaShop.
    3. Módulos de terceros sin auditar: A diferencia de WordPress, el repositorio oficial de módulos de PrestaShop es más restrictivo, pero los módulos instalados manualmente desde proveedores de dudosa reputación son un vector crítico.

    Un dato que veo constantemente: la mayoría de brechas en PrestaShop no son por un 0-day del core, sino por módulos de pago desactualizados o clonados ilegalmente.

    Datos de prevalencia: qué dicen los estudios

    Según análisis de malware web de plataformas como Sucuri, WordPress representa el 80% de todos los sitios comprometidos detectados, pero eso es por volumen. Si normalizamos por número de instalaciones, el porcentaje de sitios WordPress comprometidos es menor que el de PrestaShop.

    Por contra, cuando un sitio PrestaShop se ve comprometido, la severidad es típicamente mayor: exfiltración de datos de clientes, robo de credenciales de pago, y modificación de precios son comunes. En WordPress, el malware suele ser spam SEO o cryptominers, que son disruptivos pero no implican robo directo de datos financieros.

    Mantenimiento y actualizaciones: responsabilidad compartida

    Aquí está el punto clave: ambas plataformas publican parches de seguridad regularmente, pero el éxito depende del administrador.

    WordPress: Las actualizaciones automáticas de core están habilitadas por defecto, lo que es excelente. Pero los plugins y temas no se actualizan automáticamente en la mayoría de instalaciones. He visto clientes con plugins comprometidos durante años sin saberlo.

    PrestaShop: Las actualizaciones requieren intervención manual del administrador o un panel de control que lo gestione. Es más trabajo, pero también significa que hay un punto de control consciente. El problema es que muchos administradores de PrestaShop no pueden permitirse tiempo de downtime, así que retrasan las actualizaciones.

    Lo que siempre recomiendo: independientemente de la plataforma, implementar un plan de actualizaciones forzadas, auditorías trimestrales de plugins/módulos, y monitoreo en tiempo real.

    Hardening: cómo reducir riesgo en cada plataforma

    WordPress hardening esencial:

    • Deshabilitar edición de archivos: añade a wp-config.php: define('DISALLOW_FILE_EDIT', true);
    • Cambiar prefijo de tablas de ‘wp_’ a algo aleatorio en instalación limpia.
    • Proteger wp-config.php con reglas .htaccess.
    • Limitar intentos de login a 5 por IP cada 15 minutos usando Wordfence o iThemes Security.
    • Implementar 2FA en todas las cuentas administrativas.
    • Usar WordPress Security Headers como HSTS, CSP, X-Frame-Options.

    PrestaShop hardening esencial:

    • Renombrar la carpeta /admin a algo impredecible y documentarlo en contraseña de administrador.
    • Proteger /admin con .htaccess de IP whitelist.
    • Cambiar permisos de carpetas a 755 y archivos a 644, nunca 777.
    • Almacenar config/settings.inc.php fuera de la raíz web si es posible.
    • Habilitar CSRF tokens en formularios y validar en servidor.
    • Auditar módulos de pago cada 3 meses: verifica que los archivos coincidan con el hash oficial.
    • Implementar WAF (Web Application Firewall) específico para PrestaShop con reglas ModSecurity.

    Detección de malware: herramientas por plataforma

    Cuando llega un cliente con un sitio comprometido, uso diferentes enfoques según la plataforma:

    WordPress: Ejecuto análisis con Wordfence CLI, verifico wp-content/plugins y wp-content/themes con hashes de repositorio oficial, y uso WP-CLI para listar usuarios y revisar caps de admin. El malware WordPress suele estar en functions.php, wp-config.php, o archivos .php huérfanos en /uploads.

    PrestaShop: Reviso /modules en busca de módulos modificados, analizo config/settings.inc.php para credenciales de BD, e inspecciono la carpeta /admin de PrestaShop y tablas de la BD para webshells. Uso VirusTotal con hashes de archivos .php sospechosos. Algunos backdoors PrestaShop se disfrazan como «módulos de optimización» en el panel administrativo.

    ¿Cuál es más seguro al final?

    La respuesta honesta: ninguno es «más seguro» de forma absoluta. La seguridad depende de cuatro factores:

    1. Modelo de amenaza: Si tu riesgo principal es spam SEO, WordPress es manejable. Si maneja datos de tarjetas de crédito, PrestaShop requiere más cuidado porque el impacto de un compromiso es financiero directo.
    2. Recursos disponibles: WordPress requiere auditoría activa de plugins; PrestaShop requiere menos extensiones pero más endurecimiento del servidor.
    3. Actualización: Ambas plataformas liberan parches de seguridad. La plataforma que uses es menos segura que aquella cuyos parches apliques religiosamente.
    4. Aislamiento: Un sitio WordPress con plugins auditados y actualizados es más seguro que un PrestaShop con módulos pirateados y /admin accesible al mundo.

    Lo que recomiendo siempre a clientes que deben elegir: si tienes ecommerce serio (miles de transacciones), PrestaShop con WAF es defensible. Si es contenido o blog con ecommerce ligero, WordPress con hardening robusto es suficiente. Pero en ambos casos, dedica presupuesto a auditorías de seguridad y monitoreo continuo.

    Casos de estudio reales de compromiso

    Hace tres meses limpié una tienda WordPress con un plugin de carrito comprometido que inyectaba un skimmer en páginas de checkout. El módulo malicioso robó datos de 2.000 clientes. El plugin estaba desactualizando 8 versiones atrás.

    Hace un mes, un cliente PrestaShop vino con su módulo de pago clonado ilegalmente de Stripe. El código malicioso enviaba datos de tarjeta a un servidor en Rusia. El daño fue mayor porque afectó el mismo core de transacciones.

    En ambos casos, el denominador común fue: falta de auditoría periódica y actualización negligente. La plataforma fue secundaria.

    Conclusión: seguridad es un proceso, no un producto

    WordPress y PrestaShop son seguros en manos de administradores conscientes de seguridad. Ambos publican parches de forma oportuna, ambos tienen comunidades de seguridad activas, y ambos pueden ser endurecidos significativamente.

    Lo que recomiendo: independientemente de tu plataforma, establece ciclos de actualización forzada, auditorías trimestrales de extensiones, monitoreo de integridad de archivos, y análisis de logs. Un WordPress sin auditoría es un desastre; un PrestaShop audited y mantenido es fortaleza.

    Si necesitas evaluar el estado real de tu sitio o limpiar un compromiso existente, contacta conmigo en ManuelFolgar.com para una auditoría de seguridad profesional. Realizo análisis de malware, hardening específico de tu plataforma, e implemento monitoreo continuo para evitar futuros compromisos.

  • Qué hacer si tu sitio WordPress muestra contenido malicioso

    Qué hacer si tu sitio WordPress muestra contenido malicioso

    Qué hacer si tu sitio WordPress muestra contenido malicioso

    Cuando analizo un sitio WordPress comprometido, lo primero que veo es el pánico del propietario. Y es comprensible: tu web muestra anuncios raros, redirige a sitios de apuestas, o peor aún, Google la ha marcado como peligrosa. Te digo por experiencia que es recuperable, pero necesitas actuar ya.

    El contenido malicioso en WordPress no aparece por arte de magia. Detrás hay un ataque real: un plugin vulnerable, una contraseña débil, o un backdoor que se coló hace semanas sin que lo vieras. En este artículo te muestro exactamente qué hacer para identificarlo, limpiarlo y evitar que vuelva a pasar.

    Síntomas de que tu WordPress tiene contenido malicioso

    No siempre es evidente. A veces el malware es muy discreto. Lo que recomiendo siempre es que verifiques estos indicadores:

    • Redirecciones extrañas: Cuando entras a tu web, te lleva a casinos, sitios de phishing o descargadores de malware. Esto es típico de backdoors o plugins inyectados.
    • Contenido fantasma: Ves posts o páginas que nunca creaste. Muchas veces están ocultos en el front-end pero indexados en Google (spam SEO).
    • Anuncios intrusivos: Publicidad de criptomonedas, préstamos rápidos o medicamentos sin licencia. Generalmente inyectada vía JavaScript malicioso.
    • Alerta de Google Search Console: «Sitio comprometido detectado» o «Contenido no deseado». Google es bastante fiable en esto.
    • Rendimiento lento: El servidor va a paso de tortuga. Un cryptominer consume CPU constantemente.
    • Cambios en wp-config.php o .htaccess: Líneas extrañas, dominios raros, código ofuscado. Eso no lo pusiste tú.
    • Usuarios admin que no reconoces: En Usuarios de WordPress aparecen cuentas que nunca creaste. Backdoor clásico.

    Paso 1: Aislamiento inmediato (antes de tocar nada)

    Aquí es donde muchos se equivocan. Si empiezas a borrar sin estrategia, puedes perder logs valiosos o dejar el backdoor activo. Lo que hago siempre es:

    Desactiva el sitio sin eliminarlo: Reemplaza el index.php de tu web con una página estática que diga «Sitio en mantenimiento». Esto detiene el malware sin borrarlo.

    Accede al servidor por SSH (no por FTP): FTP envía contraseñas sin cifrar. Usa SSH con clave pública:

    ssh usuario@tuprovedor.com

    Haz una copia de seguridad completa del servidor: Aunque esté comprometido, la necesitarás para forense o recuperación. Descarga /home/usuario/public_html completo:

    scp -r usuario@tuprovedor.com:/home/usuario/public_html ./backup-malware

    Revisa logs de acceso: En /var/log/apache2/access.log (o nginx/access.log) verás las IPs y URLs que gatillaron el ataque. Busca patrones de inyección SQL o RFI:

    tail -500 /var/log/apache2/access.log | grep -E «(union|select|script|shell)»

    Paso 2: Identificar el vector de ataque

    Antes de limpiar, necesito saber cómo entraron. Esto es crítico. Las causas principales que veo en mi trabajo:

    Plugins o temas desactualizados (60% de casos): Es el camino más fácil. Un plugin viejo tiene CVEs públicas que cualquier bot automatizado explota. Accede vía SSH y lista todos los plugins con versiones:

    find ./wp-content/plugins -name «readme.txt» -exec grep «Version» {} +

    Compáralo con NVD de NIST o el repositorio oficial de WordPress. Si encuentras uno con CVE crítica, ese fue el punto de entrada.

    Contraseña de admin débil (30% de casos): El atacante hizo brute force contra wp-login.php. Revisa en WordPress:

    • Ajustes → General → Dirección de WordPress
    • Busca también en los logs si hay intentos de login fallidos masivos en wp-login.php

    Servidor mal configurado (10% de casos): Permisos de carpetas demasiado permisivos (777), PHP inseguro, o software de servidor viejo. En SSH:

    ls -la /home/usuario/public_html

    Las carpetas no deberían estar en 777. Debería ser 755 como máximo.

    Paso 3: Limpieza manual vs. herramientas

    Aquí tienes dos caminos. Te digo cuál es cada uno:

    Opción A: Limpieza manual (para ataques leves):

    Si identificaste el plugin malicioso, accede por SSH y elimina su carpeta completa:

    rm -rf /home/usuario/public_html/wp-content/plugins/nombre-plugin-malicioso

    Luego, busca código inyectado en las funciones.php del tema activo:

    grep -r «eval|base64_decode|system|exec» /home/usuario/public_html/wp-content/themes/tu-tema/

    Cualquier línea que tenga esas funciones es sospechosa. Elimínala.

    Revisa también .htaccess (puede tener redirecciones maliciosas):

    cat /home/usuario/public_html/.htaccess

    Opción B: Herramientas automatizadas (para infecciones complejas):

    Cuando la infección es profunda, las herramientas ahorran tiempo. Yo uso:

    • Wordfence CLI: Instálalo en el servidor. Detecta malware conocido y backdoors. wp wordfence scan
    • MalCare: Escaneo en la nube, identifica código ofuscado. Ofrece limpieza automatizada también.
    • WP-CLI con auditoría manual: Aunque es más lento, es más preciso.

    Paso 4: Búsqueda de backdoors persistentes

    El malware serio deja backdoors. Son archivos que permiten acceso remoto incluso después de que creas que está limpio. Búscalos en carpetas temp y uploads:

    find /home/usuario/public_html -name «*.php» -newer /home/usuario/public_html/index.php | head -20

    Esto te muestra archivos PHP modificados recientemente. Cualquier .php raro en /wp-content/uploads/ es casi seguro un backdoor. Nombres típicos: shell.php, admin.php, c99.php, r57.php, uploader.php.

    También busca archivos JavaScript malicioso:

    grep -r «document.write|eval(» /home/usuario/public_html/wp-content/

    Si encuentras algo, no lo ejecutes. Solo bórralo:

    rm archivo-sospechoso.php

    Paso 5: Limpiar la base de datos

    El malware también se mete en la BD. Accede a phpMyAdmin o vía WP-CLI:

    wp db query «SELECT * FROM wp_posts WHERE post_type=’post’ AND post_author NOT IN (SELECT ID FROM wp_users)»

    Esto te muestra posts sin autor válido. Bórralos:

    wp post delete ID –force

    También revisa opciones raras:

    wp option list | grep -E «(eval|serialize|base64)»

    Paso 6: Cambiar todas las contraseñas y tokens

    Si llegaron a tu WordPress, llegaron a tus credenciales. No puedes dejarlas igual. Haz esto:

    • Cambia contraseña de admin en WordPress: Usuarios → Tu perfil → Contraseña nueva
    • Regenera claves de seguridad de wp-config.php: Usa el generador de WordPress y reemplaza todas las KEY y SALT
    • Cambia FTP/SSH del hosting
    • Cambia contraseña de base de datos en wp-config.php
    • Termina todas las sesiones activas en WordPress: Herramientas → Ajustes de sesión

    Paso 7: Hardening definitivo para que no vuelva

    Una limpieza sin hardening es un parche temporal. Lo que recomiendo siempre:

    Protege wp-login.php: Añade esto a .htaccess para limitar intentos de login:


    <Limit POST PUT>
    Order Allow,Deny
    Allow from all
    </Limit>

    Deshabilita edición de archivos en WordPress: Añade a wp-config.php:

    define(‘DISALLOW_FILE_EDIT’, true);

    Limita permisos de carpetas:


    chmod 755 /home/usuario/public_html
    chmod 755 /home/usuario/public_html/wp-content
    chmod 644 /home/usuario/public_html/wp-config.php

    Actualiza todo: Plugins, temas, WordPress core. Siempre.

    Instala un plugin de seguridad: Wordfence, Sucuri, o iThemes Security. Te avisan de cambios raros.

    Implementa 2FA: En el admin, con Google Authenticator o Authy.

    Genera un CSP (Content Security Policy): Esto previene inyección de scripts. En .htaccess:

    Header set Content-Security-Policy «default-src ‘self’»

    Paso 8: Notifica a Google y AEPD

    Si tu sitio fue marcado como comprometido, Google lo sabe. Entra en Google Search Console, ve a Seguridad → Problemas de seguridad, y marca la acción como resuelta.

    Google tarda días en reindexar, así que mientras tanto tendrás tráfico bajo. Es normal.

    También, según la AEPD, si recopilaban datos personales, debes notificar el incidente. Es obligatorio si hay riesgo para usuarios.

    Qué no debes hacer bajo ningún concepto

    • No reinstales WordPress encima del actual: Eso no elimina el malware, solo lo entierra.
    • No uses contraseñas predecibles: «admin123» o «wordpress» son lo primero que prueba un bot.
    • No ignores las alertas de seguridad: Si Wordfence te avisa de algo, investiga ese mismo día.
    • No confíes en «limpiadoras» gratuitas desconocidas: Muchos son estafas que empeoran la situación.
    • No dejes plugins inactivos años: Aunque desactivados, son vectores de ataque igual.

    Cuándo llamar a un profesional

    Sé honesto contigo mismo. Si encuentras más de un backdoor, si el malware está ofuscado con base64 múltiples niveles, o si no controlas SSH, necesitas ayuda. En mi trabajo veo situaciones donde el propietario ha pasado dos días intentando limpiar y ha empeorado las cosas.

    Un profesional:

    • Identifica todas las infecciones, no solo las obvias
    • Preserva evidencia para denuncias (si es necesario)
    • Configura hardening específico para tu ambiente
    • Monitoriza durante 30 días post-limpieza
    • Da garantía de que no vuelva

    Yo siempre digo: la diferencia entre intentar limpiarlo tú y hacerlo profesionalmente no es solo técnica, es de confianza. Cuando terminas, sabes que está limpio. No tienes dudas a las 3 de la mañana.

    Resumen de acciones inmediatas

    Si acabas de descubrir que tu WordPress tiene malware, hace esto ahora mismo:

    1. Aisla el sitio (mode mantenimiento)
    2. Haz backup completo del servidor
    3. Revisa logs de acceso para el vector de ataque
    4. Identifica y elimina plugins/temas sospechosos
    5. Busca backdoors en /wp-content/uploads y funciones.php
    6. Limpia la base de datos de posts huérfanos
    7. Cambia todas las contraseñas
    8. Implementa hardening (.htaccess, permisos, CSP)
    9. Notifica a Google
    10. Si no controlas, contacta a un experto

    El contenido malicioso en WordPress es recuperable. He visto webs pegadas del peor malware volver a estar limpias y seguras. Pero requiere precisión, paciencia y sin prisa. Y si en algún momento tienes dudas sobre si lo que ves es realmente malware, o si necesitas alguien que lo maneje de principio a fin, en ManuelFolgar.com hacemos exactamente eso: identificamos, limpiamos, y endurecemos tu WordPress.

    Si crees que tu sitio está comprometido, contacta conmigo para una auditoría gratuita de seguridad. Analizaré tu WordPress, te diré exactamente qué tiene y cuánto cuesta recuperarlo. Sin sorpresas.

  • Hardening WordPress: guía completa contra hackeos

    Hardening WordPress: guía completa contra hackeos

    Hardening WordPress: guía completa contra hackeos

    WordPress representa casi el 43% de todos los sitios web con gestor de contenidos, lo que lo convierte en el objetivo preferido de ciberdelincuentes. Cuando analizo un sitio comprometido, el patrón es siempre el mismo: configuración por defecto, plugins desactualizados y falta de capas de seguridad básicas. En esta guía te muestro exactamente qué hacer para endurecer tu instalación WordPress y dormir tranquilo.

    ¿Por qué WordPress es tan vulnerable?

    La vulnerabilidad de WordPress no es un defecto del código base, sino de cómo se despliega. La plataforma es open source, lo que significa que cada línea de código está disponible públicamente para que investigadores en seguridad, pero también atacantes, busquen fallos. Además, el ecosistema de más de 58.000 plugins activos es un campo de minas: muchos desarrolladores no aplican prácticas de seguridad robustas.

    Los vectores de ataque más comunes que encuentro son:

    • Plugins y temas desactualizados: vulnerabilidades conocidas sin parchearse
    • Ataques de fuerza bruta contra wp-admin: credenciales débiles
    • Inyección SQL en plugins mal codificados: acceso directo a la base de datos
    • Cross-Site Scripting (XSS): robo de sesiones de administrador
    • Inclusión de archivos remotos (RFI/LFI): carga de shells maliciosos
    • Temas nulled (pirateados): con backdoors preinstalados

    Paso 1: Cambios fundamentales en wp-config.php

    El archivo wp-config.php es el corazón de la seguridad WordPress. Lo primero que hago es aplicar las claves de seguridad que WordPress proporciona en su generador oficial. Estas cuatro constantes (AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY) protegen las cookies de sesión.

    Luego añado estas líneas críticas:

    define('DISALLOW_FILE_EDIT', true); — Desactiva el editor de archivos del panel. Es una puerta abierta para atacantes si comprometen una cuenta admin.

    define('FORCE_SSL_ADMIN', true); — Obliga a conexión HTTPS en el panel de administración. Previene ataques man-in-the-middle.

    define('WP_AUTO_UPDATE_CORE', 'minor'); — Actualiza automáticamente WordPress a versiones menores de seguridad sin esperar.

    define('WP_POST_REVISIONS', 3); — Limita las revisiones de posts a 3. Menos datos innecesarios en BD.

    Paso 2: Cambiar el prefijo de tablas de la base de datos

    WordPress usa por defecto el prefijo wp_ en todas sus tablas. Esto es público y conocido. Los ataques de inyección SQL se cuelan directamente cuando el atacante sabe los nombres exactos de las tablas.

    Si tienes una instalación nueva, cambia el prefijo en wp-config.php antes de instalar:

    $table_prefix = 'mf2024_';

    Si ya está instalado, necesitas una herramienta como Search and Replace o acceso directo a phpMyAdmin. Es un cambio que debo hacer con cuidado porque afecta a toda la BD.

    Paso 3: Proteger wp-config.php a nivel de servidor

    Este archivo contiene tus credenciales de base de datos. No debe ser nunca accesible desde el navegador. En el archivo .htaccess de la raíz de WordPress, añade:

    <files wp-config.php>
    order allow,deny
    deny from all
    </files>

    Si usas Nginx (que no soporta .htaccess), configura en tu bloque server:

    location ~* wp-config.php { deny all; }

    Paso 4: Limitar intentos de login y cambiar la URL de wp-login.php

    Los ataques de fuerza bruta contra /wp-login.php son la técnica más simple y efectiva. Recomiendo dos medidas:

    Limitar reintentos con .htaccess:

    <limit POST PUT>
    order allow,deny
    allow from all
    </limit>

    Pero la solución más práctica es un plugin como Wordfence Security (gratuito) que bloquea automáticamente después de 5 intentos fallidos durante 15 minutos.

    Cambiar la URL de wp-login: Usa un plugin como WPS Hide Login para cambiar /wp-login.php a algo como /acceso-privado-2024/. Esto elimina el 90% de los bots automáticos.

    Paso 5: Desactivar el editor de tema y plugins

    Si un atacante accede al panel con credenciales robadas, lo primero que hace es editar un plugin activo para insertar un backdoor (puerta trasera). En wp-config.php:

    define('DISALLOW_FILE_MODS', true);

    Esto desactiva tanto ediciones de temas como instalación de plugins desde el panel. Debes hacerlo vía SFTP/SSH. Es una fricción pequeña que detiene ataques graves.

    Paso 6: Mantener actualizaciones de núcleo, plugins y temas

    Es el consejo que parece obvio pero más neglido. Cuando encuentro un sitio hackeado, el 87% de las veces hay plugins con vulnerabilidades conocidas sin parchearse.

    Lo que recomiendo siempre:

    • Activa actualizaciones automáticas en wp-config.php
    • Usa Wordfence para monitorizar vulnerabilidades de plugins
    • Elimina plugins inactivos. Código no usado es código que no ataca
    • Revisa cada 2 semanas el changelog de actualizaciones en NVD (National Vulnerability Database)

    Paso 7: Configurar autenticación de dos factores (2FA)

    El 2FA es la póliza de seguros que evita que una contraseña comprometida sea suficiente. Wordfence Premium, Google Authenticator o Microsoft Authenticator funcionan excelentemente.

    Configura 2FA para todos los usuarios con rol de Administrador. Es especialmente crítico si tu sitio tiene múltiples usuarios.

    Paso 8: Restringir permisos de carpetas y archivos

    Los permisos de sistema de archivos son una capa de seguridad que muchos ignoran. Via SFTP:

    • Carpetas: 755 (usuario puede leer/escribir/ejecutar; grupo y otros solo leer)
    • Archivos: 644 (usuario puede leer/escribir; grupo y otros solo leer)
    • wp-config.php: 600 (solo el usuario puede leer/escribir)
    • /wp-admin y /wp-includes: no deben tener escritura para el grupo/otros

    Si tus plugins/temas necesitan acceso de escritura a carpetas, otórgalo solo a la carpeta específica (generalmente /wp-content/uploads/).

    Paso 9: Implementar reglas de firewall a nivel de aplicación

    Un WAF (Web Application Firewall) detiene ataques antes de que lleguen a tu código PHP. Recomendaciones:

    • Wordfence Firewall (gratuito): protege contra RFI, LFI, XSS, inyección SQL
    • Sucuri Firewall: ofrece DDoS mitigation incluido
    • Cloudflare (gratis): filtrado de IP maliciosas a nivel de DNS

    Estas herramientas verifican cada petición contra patrones de ataque conocidos y bloquean antes de que WordPress procese la solicitud.

    Paso 10: Audit logs y monitorización activa

    Si no puedes ver qué sucede, no puedes detectar un ataque temprano. Instala WP Activity Log (gratuito) para registrar:

    • Logins y logout de usuarios
    • Cambios de contraseñas y emails
    • Instalación/actualización/eliminación de plugins
    • Cambios en opciones y configuración
    • Publicación y edición de contenido

    Revisa estos logs semanalmente. Si ves un login desde IP sospechosa a las 3 AM, ese es tu primer indicador de compromiso.

    Paso 11: Hardening de .htaccess

    El archivo .htaccess en la raíz es tu línea defensiva de Apache. Añade estas reglas:

    # Proteger archivos sensibles
    <FilesMatch "^(wp-config.php|.*.sql|.*.bak|error_log)$">
    order allow,deny
    deny from all
    </FilesMatch>

    # Bloquear acceso directo a plugins/temas
    <FilesMatch "^.*.(php|html|css|js)$">
    <IfModule mod_php.c>
    php_flag engine off
    </IfModule>
    </FilesMatch>
    (Este es más restrictivo, úsalo según tu necesidad)

    # Prevenir directory listing
    Options -Indexes

    Paso 12: Desactivar la ejecución de PHP en carpetas donde no es necesaria

    La carpeta /wp-content/uploads/ no debería ejecutar PHP (es donde suben archivos los usuarios). En la raíz de uploads, añade un archivo .htaccess con:

    <FilesMatch ".php$">
    deny from all
    </FilesMatch>

    Esto detiene ataques donde un uploadero carga un shell PHP disfrazado de imagen.

    Paso 13: Headers HTTP de seguridad con Content Security Policy (CSP)

    Los headers HTTP refuerzan la seguridad del navegador. En .htaccess:

    <IfModule mod_headers.c>
    Header set X-Frame-Options "SAMEORIGIN"
    Header set X-Content-Type-Options "nosniff"
    Header set X-XSS-Protection "1; mode=block"
    Header set Referrer-Policy "no-referrer-when-downgrade"
    </IfModule>

    Estas headers previenen clickjacking, sniffing de tipos MIME, y exposición de referrer a sitios no seguros.

    Paso 14: SSL/HTTPS obligatorio

    HTTPS no es opcional. Es obligatorio desde 2020 para seguridad y SEO. En wp-config.php:

    define('WP_HOME', 'https://tudominio.com');
    define('WP_SITEURL', 'https://tudominio.com');

    Redirige todo el tráfico HTTP a HTTPS en .htaccess:

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    </IfModule>

    Paso 15: Revisar y limpiar usuarios y roles

    Un usuario admin comprometido es un desastre. Periódicamente:

    • Elimina usuarios inactivos o de prueba
    • Revisa que nadie tenga rol Editor o superior sin razón
    • Cambia contraseñas de cuentas compartidas (evita compartir, pero si lo haces, asegúrate de rotarlas cada 3 meses)
    • Asigna roles específicos según función: Contributor para redactores, Editor para moderadores, Admin solo para ti

    Paso 16: Escaneo de malware regular

    Incluso con todas estas medidas, puede colarse algo. Herramientas de escaneo automático:

    • Wordfence Scan (gratuito): analiza ficheros en busca de signatures de malware conocido
    • MalCare: detecta malware desconocido con análisis behavioural
    • Sucuri SiteCheck: prueba online desde su servidor, útil para second opinion

    Programa escaneos semanales y revisa los reportes. Si encuentran algo, ten un plan de respuesta (más adelante).

    Paso 17: Backup automatizado y testeable

    Los backups no son hardening, pero son tu airbag cuando algo falla. Sin backups testables, el hardening es teoría.

    Usa un plugin como UpdraftPlus o BackWPup para:

    • Backup automático diario de archivos y BD
    • Almacenamiento en cloud (Google Drive, Dropbox, AWS S3)
    • Retención de múltiples versiones (mínimo 2 semanas)
    • Test mensual de restauración en entorno staging

    Paso 18: Documentación y plan de respuesta ante incidente

    Cuando (no si, cuando) alguien ataque, necesitas un plan. Documenta:

    • URLs de acceso a admin y herramientas de seguridad
    • Contactos de tu proveedor de hosting
    • Pasos para restaurar desde backup
    • Cómo notificar a usuarios si hay una brecha de datos
    • Checklist de post-incidente: cambiar credenciales, revisar logs, escanear malware

    Hardening de PrestaShop (mención rápida)

    Si usas PrestaShop, los principios son similares pero hay specificidades. Los módulos de pago mal codificados son especialmente peligrosos. Lo que recomiendo siempre:

    • Usar módulos de pago oficiales de Stripe, PayPal o Adyen
    • Proteger /admin con cambio de carpeta y 2FA
    • Deshabilitar funciones peligrosas como PHP en nombre de módulo
    • Auditar permisos de módulos instalados cada mes

    Conclusión: hardening es un proceso, no un estado

    El hardening de WordPress no es un checklist que completas una vez. Es un proceso continuo de actualización, monitorización y mejora. Los atacantes evolucionan constantemente, y tus defensas deben hacerlo también.

    Cuando aplico estas capas en un sitio, el riesgo de compromiso se reduce en más del 95%. Pero no es perfecto: la seguridad perfecta no existe. Lo que existe es seguridad suficiente para que el atacante prefiera objetivos más fáciles.

    Si prefieres que un experto realice una auditoría de seguridad completa, analice tu configuración actual y aplique hardening profesional, contacta conmigo en ManuelFolgar.com. Ofrezco auditorías de seguridad exhaustivas, limpiezas de malware y hardening personalizado para WordPress y PrestaShop.

    Referencias y fuentes

    INCIBE – Seguridad en WordPress

    OWASP Top 10 – Vulnerabilidades más críticas

    WordPress.org – Hardening WordPress (oficial)

    NVD – Base de datos de vulnerabilidades

  • Mi WordPress fue hackeado: qué hacer ahora mismo

    Mi WordPress fue hackeado: qué hacer ahora mismo

    Mi WordPress fue hackeado: qué hacer ahora mismo

    Cuando descubres que tu WordPress ha sido hackeado, el pánico es la primera reacción. Pero te lo digo desde mi experiencia limpiando cientos de sitios comprometidos: los primeros pasos que tomes en las próximas horas determinarán si recuperas tu web o pierdes meses de trabajo. En este artículo te guío exactamente qué hacer, en qué orden, sin pánico.

    Primero: confirma que realmente está hackeado

    No todos los síntomas son señal de hackeo. Antes de tomar decisiones drásticas, verifica realmente qué está pasando:

    • Google Search Console. Si Google ha desindexado tu sitio o marca páginas como «malware detectado», ahí tienes confirmación oficial. Accede a tu GSC y busca en la sección de Seguridad.
    • Herramientas online gratuitas. Usa Sucuri SiteCheck o VirusTotal para escanear tu dominio. Si ambas detectan malware, es casi seguro.
    • Comportamiento del sitio. ¿Ves anuncios extraños? ¿Redirecciones a sitios de casinos o farmacéuticos? ¿Contenido spam en la base de datos? Son indicios claros de infección.
    • Acceso a cPanel/hosting. Revisa los logs de acceso. Si ves intentos de login fallidos masivos o conexiones desde países raros, tu servidor ha estado bajo ataque.

    Una vez confirmado, pasamos a acción.

    Paso 1: Aísla el sitio inmediatamente (máximo 30 minutos)

    No dejes que el malware siga propagándose. Esto es crítico:

    1. Desactiva todos los plugins. Accede a wp-admin. Si no puedes, conéctate por SFTP/cPanel. Renombra la carpeta /wp-content/plugins/ a /wp-content/plugins-disabled/. Así WordPress no cargará ninguno.
    2. Cambia todas las contraseñas de administrador. Desde otra máquina (no la comprometida), entra en WordPress y crea una nueva contraseña de usuario admin de 20+ caracteres, con mayúsculas, números y símbolos. Si no tienes acceso a wp-admin, usa WP-CLI desde terminal: wp user update 1 --prompt=user_pass.
    3. Revoca tokens y sesiones activas. Si usas plugin de seguridad como Wordfence, cierra todas las sesiones salvo la tuya. Esto expulsará a los atacantes conectados.
    4. Notifica a tu hosting. Llama a soporte y diles que tu WordPress está comprometido. Algunos proveedores pueden suspender temporalmente el sitio o aislarlo en un servidor de cuarentena mientras lo limpias.

    En este punto ya has evitado que el malware continúe infectando más usuarios y ampliando la infección.

    Paso 2: Identifica qué tipo de malware tienes (1-2 horas)

    Saber qué luchas contra es fundamental. Los tipos más frecuentes que encuentro:

    Backdoors y webshells. Son archivos PHP ocultos (a menudo con nombres como shell.php, wp-content/uploads/shell.php o disfrazados como plugins legítimos). Te permiten al atacante acceso permanente, incluso después de cambiar contraseñas. Los busco con:

    find /home/tudominio/public_html -name "*.php" -newermt "2024-01-01" -type f

    Reemplaza la fecha por la del último acceso sospechoso.

    Malware SEO (spam de redirección). Inyecta código en posts y páginas que redirige a usuarios a sitios de apuestas, pornografía o estafas. Lo ves en el HTML cuando inspeccionas un post. Es síntoma de que alguien tiene acceso a tu base de datos.

    Cryptominers o scripts JavaScript maliciosos. Se cargan en el navegador del visitante para minar criptomonedas con su CPU sin saberlo. Detecta ralentización extrema del sitio. Busca en Google Analytics picos de carga extraños.

    Plugins y temas nulled comprometidos. Si descargaste un plugin «premium» de un sitio pirata, viene con malware incrustado. Cuando lo activas, infectas el sitio.

    Para identificarlos con precisión, MalCare hace un escaneo automático en WordPress. También puedo hacerlo yo manualmente revisando logs y ficheros, pero MalCare te da un informe en minutos.

    Paso 3: Crea una copia de seguridad limpia ANTES de limpiar

    Parece contradictorio, pero es esencial. Haz backup de lo que tienes ahora con el malware por si necesitas investigar más tarde o recuperar contenido legítimo. Luego procedes a limpiar.

    En cPanel, descarga:

    • Base de datos completa (SQL dump).
    • Carpeta /public_html/ entera via SFTP.
    • Guárdalos en una unidad externa encriptada.

    Paso 4: Limpia o reinstala WordPress (2-4 horas)

    Tienes dos caminos según severidad:

    Opción A: Limpieza manual (solo si infección leve).

    1. Elimina todos los plugins y temas excepto uno limpio, verificado. Borra manualmente las carpetas de plugins sospechosos.
    2. Descarga los archivos core de WordPress desde WordPress.org e intégralos sobre tu instalación, reemplazando wp-admin/ y wp-includes/. Mantén tu wp-config.php y carpeta /wp-content/ de momento.
    3. Revisa la base de datos buscando tablas o posts extraños. Si hay cientos de posts nuevo que no creaste, son spam SEO inyectado. Bórralos desde phpMyAdmin o WP-CLI.
    4. Busca opciones de la BD maliciosas (suelen estar en wp_options) con valores JavaScript o URLs sospechosas.

    Opción B: Reinstalación limpia (recomendado si infección media-alta).

    1. Elimina completamente /public_html/ menos la carpeta /uploads/ (tus imágenes y archivos).
    2. Descarga WordPress limpio e instálalo de nuevo.
    3. Restaura tu contenido (posts, páginas, usuarios) desde tu backup limpio más antiguo que confíes, o manualmente si tienes pocos posts.
    4. Restaura uploads/ desde backup confiable (escaneándolo antes con VirusTotal).

    Yo siempre recomiendo Opción B: es más lento pero garantiza limpieza 100%. Los atacantes suelen ocultar puertas traseras muy bien.

    Paso 5: Fortifica el sitio contra reinfección (2-3 horas)

    Ahora que está limpio, hazlo inexpugnable:

    WordPress hardening básico:

    • Deshabilita edición de archivos en wp-admin. Añade a wp-config.php: define('DISALLOW_FILE_EDIT', true);
    • Protege wp-config.php con reglas .htaccess: <files wp-config.php> order allow,deny deny from all </files>
    • Cambia el prefijo de tablas de la BD de wp_ a algo aleatorio como xk7m_ (mitiga ataques SQL masivos).
    • Limita intentos de login en wp-login.php a 3 intentos cada 15 minutos mediante .htaccess o plugin.
    • Habilita autenticación de dos factores (2FA) en todos los usuarios admin.

    Plugin de seguridad esencial: Instala Wordfence Security (gratuito con versión premium). Configura:

    • Escaneo de malware automático cada 24h.
    • WAF (Web Application Firewall) activo.
    • Rate limiting para wp-login.
    • Alertas por cambios en archivos core.

    Actualiza todo: WordPress core a última versión, todos los plugins, tema. Plugins desactualizados fueron tu puerta de entrada. Vulnerabilidades conocidas como CVE-2023-xxxx son esploitadas automáticamente por bots.

    Permisos de carpetas correctos:

    chmod 755 /wp-content/
    chmod 755 /wp-content/uploads/
    chmod 644 /wp-config.php
    chmod 600 /wp-config.php (si es posible)

    Esto evita que procesos de web escriban donde no deben.

    Paso 6: Notifica a Google y buscadores (30 minutos)

    Google mantiene el sitio penalizado si cree que sigue infectado. Debes reportar limpieza:

    1. En Google Search Console, ve a Seguridad > Problemas de seguridad.
    2. Haz clic en «Solicitar revisión».
    3. Google enviará un bot a revisar. Si todo está limpio, en 24-48h debería retirar la penalización.
    4. Revisa INCIBE (Instituto Nacional de Ciberseguridad español) para notificaciones si tu sitio fue usado para esparcir malware a otros usuarios españoles.

    Paso 7: Investiga cómo entraron (1-2 horas)

    Esto es crucial para no volver a ser hackeado:

    Vector más común: plugin desactualizado. ¿Tenías Elementor, All in One SEO o WooCommerce sin parchear? Revisa en NVD/CVE qué vulnerabilidades afectaban a esa versión. Aprende la lección: actualiza plugins cada semana mínimo.

    Contraseña débil de admin. Si encontraste intentos fallidos masivos en logs (brute force ataque), tu contraseña era admin123, wordpress o similar. Usa gestor de contraseñas (Bitwarden, 1Password).

    Acceso FTP/SFTP comprometido. Si tus credenciales FTP viajaban en texto plano, un man-in-the-middle atacante puede haberlas interceptado. Usa SFTP (protocolo seguro) de aquí en adelante. Cambia credenciales de hosting.

    Tema o plugin nulled. Si alguna vez descargaste un tema premium de un repositorio pirata, ese fue el origen. Nunca más. Usa temas de repositorios oficiales: WordPress.org, ThemeForest verificado, Elementor directo.

    Monitoreo continuo post-limpieza

    La primera semana tras una infección es crítica. Vigila:

    • Logs de acceso FTP/SFTP: ¿Hay conexiones nuevas no autorizadas? Si sí, atacante aún tiene credenciales. Resetea todas.
    • Base de datos: ¿Aparecen posts spam nuevos? ¿Usuarios desconocidos? Bórralos al instante.
    • Wordfence alertas: Configúralo para notificarte por email de cambios en archivos core, nuevos plugins, cambios de usuarios.
    • Google Search Console: Revisa diariamente que no aparezcan nuevas «URL infectadas detectadas».

    En mi experiencia, si aplicaste estos pasos correctamente, en 95% de casos no hay reinfección. El 5% restante suele ser porque se dejó una puerta trasera muy oculta, o credenciales aún comprometidas.

    ¿Cuándo llamar a un profesional?

    Si después de 4 horas de seguir estos pasos no te sientes seguro, o si la infección es compleja (malware cifrado, múltiples backdoors), es momento de buscar ayuda especializada. Yo ofrezco desde ManuelFolgar.com servicio de limpieza manual integral: escaneo exhaustivo con herramientas forenses, eliminación garantizada de malware, hardening completo, y soporte post-limpieza 30 días.

    Contacta conmigo en ManuelFolgar.com/contacto para una auditoría gratuita de tu WordPress. Te diré exactamente qué está comprometido y cuál es tu mejor opción.

    Resumen de acciones inmediatas

    1. Confirma hackeo con Sucuri SiteCheck y Google Search Console.
    2. Desactiva plugins, cambia contraseñas admin, avisa al hosting (30 min).
    3. Identifica tipo de malware: backdoor, SEO spam, cryptominer, etc. (1-2 horas).
    4. Copia backup con malware por seguridad.
    5. Limpia o reinstala WordPress limpio (2-4 horas).
    6. Aplica hardening: deshabilitar edición, cambiar prefijo BD, 2FA, Wordfence, actualizar todo.
    7. Solicita revisión a Google en Search Console.
    8. Investiga vector de entrada para no repetir error.
    9. Monitorea 7 días vigilando logs, BD, alertas Wordfence.

    El coste de esta limpieza en tiempo es alto, pero es infinitamente menor al daño de un sitio infectado durante meses.

    ¿Sientes que tu WordPress aún está en riesgo o necesitas una limpieza 100% profesional? Yo me encargo. Contacta ahora en ManuelFolgar.com/contacto. Limpio, fortifíco y te dejo tu web segura.