Saltar al contenido
Vulnerabilidad crítica en WPvivid Backup: subida arbitraria de archivos (CVE-2026-1357) y riesgo de RCE en sitios WordPress
María García
María García 11 dEurope/Budapest February dEurope/Budapest 2026 · 5 min de lectura

Vulnerabilidad crítica en WPvivid Backup: subida arbitraria de archivos (CVE-2026-1357) y riesgo de RCE en sitios WordPress

Se ha publicado un aviso de seguridad importante sobre WPvivid Backup & Migration (slug: wpvivid-backuprestore), un plugin de copias de seguridad/migración con más de 800.000 instalaciones activas. El problema es una subida arbitraria de archivos sin autenticación que, en el peor escenario, permite Remote Code Execution (RCE) y puede desembocar en la toma completa del sitio.

El matiz clave (y práctico) es que el impacto crítico se concentra en sitios donde se ha activado una función concreta del plugin: permitir que otro sitio envíe un backup al tuyo mediante una clave generada en los ajustes. Esta característica viene desactivada por defecto y la caducidad de la clave solo puede configurarse hasta un máximo de 24 horas. Aun así, si se ha usado alguna vez, conviene tratarlo como urgente.

Resumen de la vulnerabilidad (Wordfence Intelligence)

  • Nombre/entrada: “Migration, Backup, Staging <= 0.9.123 - Unauthenticated Arbitrary File Upload”
  • Severidad (CVSS): 9.8 (Critical)
  • CVE: CVE-2026-1357
  • Versiones afectadas: <= 0.9.123
  • Versión corregida: 0.9.124
  • Componente afectado: Migration, Backup, Staging – WPvivid Backup & Migration
  • Vector destacado: wpvivid_action=send_to_site
  • Bounty reportado: $2,145.00 (descubrimiento y reporte responsable por Lucas Montes (NiRoX) vía Bug Bounty Program)

Según el análisis publicado, la vulnerabilidad combina dos problemas: manejo incorrecto de errores durante el descifrado RSA y ausencia de saneamiento de rutas (path sanitization) cuando se escriben archivos subidos. El resultado es que un atacante puede preparar una carga maliciosa, forzar la escritura del archivo fuera del directorio “protegido” del backup y terminar colocando un PHP ejecutable en una ruta accesible públicamente.

¿Cuándo es crítico de verdad?

El aviso recalca que afecta de forma crítica a quienes tengan una clave generada en los ajustes del plugin para permitir la recepción de backups desde otro sitio. La función está desactivada por defecto y la clave caduca como máximo en 24 horas, pero si la has habilitado (aunque sea puntualmente), actualiza y revisa.

Qué permite el ataque: de subida de archivos a ejecución remota de código

Una arbitrary file upload (subida arbitraria de archivos) en WordPress es especialmente peligrosa porque no se limita a “subir un fichero”: si el atacante consigue escribir un .php en una carpeta servida por el servidor web, puede ejecutar ese código vía HTTP y ganar control (por ejemplo, desplegando una webshell, que es un script para ejecutar comandos y gestionar archivos desde el navegador).

En este caso, el flujo vulnerable está ligado a la característica de WPvivid para recibir backups entrantes desde otra instalación. El endpoint/acción mencionada en el informe (wpvivid_action=send_to_site) es la puerta de entrada que un actor malicioso intentaría explotar.

Análisis técnico: dónde falla el proceso de cifrado/descifrado

El plugin gestiona la recepción del backup en la función send_to_site() de la clase WPvivid_Send_to_site. Ahí carga la lógica criptográfica y utiliza una clave generada en la configuración (guardada en opciones) para descifrar el contenido recibido.

public function send_to_site()
{
    include_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-crypt.php';
    $test_log = new WPvivid_Log();
    $test_log->CreateLogFile('test_backup','no_folder','transfer');
    $test_log->WriteLog('test upload.','notice');

    try
    {
        if (isset($_POST['wpvivid_content']))
        {
            global $wpvivid_plugin;
            $wpvivid_plugin->wpvivid_log = new WPvivid_Log();

            $default = array();
            $option = get_option('wpvivid_api_token', $default);
            if (empty($option))
            {
                die();
            }
            if ($option['expires'] != 0 && $option['expires'] < time())
            {
                die();
            }

            $crypt = new WPvivid_crypt(base64_decode($option['private_key']));
            $body  = base64_decode($_POST['wpvivid_content']);
            $data  = $crypt->decrypt_message($body);
        }
    }
    catch (Exception $e)
    {
        // ...
    }
}

La parte interesante (y peligrosa) está en decrypt_message(). El plugin descifra un “session key” con RSA y luego usa ese valor como clave para inicializar el cifrado simétrico (Rijndael/AES vía phpseclib). El informe describe un comportamiento problemático: si el descifrado RSA falla, se obtiene false, pero el código no corta la ejecución y pasa ese false al inicializador del cifrado simétrico.

public function decrypt_message($message)
{
    $len = substr($message, 0, 3);
    $len = hexdec($len);
    $key = substr($message, 3, $len);

    $cipherlen = substr($message, ($len + 3), 16);
    $cipherlen = hexdec($cipherlen);

    $data = substr($message, ($len + 19), $cipherlen);

    $rsa = new Crypt_RSA();
    $rsa->loadKey($this->public_key);
    $key = $rsa->decrypt($key);

    $rij = new Crypt_Rijndael();
    $rij->setKey($key);
    return $rij->decrypt($data);
}

La consecuencia que describe Wordfence es sutil: al pasar false a la librería, esta lo interpreta como una cadena de bytes nulos (null bytes). Eso vuelve la “clave” predecible, permitiendo que un atacante cifre una carga maliciosa con esa clave de bytes nulos y el plugin la “descifre” como válida.

A esto se le suma un segundo problema: el nombre de archivo que llega desde el payload descifrado se acepta sin saneamiento de ruta, lo que permite directory traversal (por ejemplo, escapar del directorio de backups). En un escenario real, eso facilita escribir archivos en directorios públicos y, si el atacante sube un .php, activar la RCE simplemente accediendo a ese fichero.

Qué corrigió el parche (0.9.124)

El proveedor publicó la corrección en WPvivid Backup 0.9.124. La solución aborda ambos frentes: valida el resultado del descifrado y añade controles para limitar el tipo de archivo que se acepta en la recepción.

1) Corte temprano si el descifrado RSA devuelve una clave inválida

La corrección añade una comprobación explícita en decrypt_message() para evitar que false o una clave vacía termine inicializando el cifrado simétrico.

public function decrypt_message($message)
{
    $len = substr($message, 0, 3);
    $len = hexdec($len);
    $key = substr($message, 3, $len);

    $cipherlen = substr($message, ($len + 3), 16);
    $cipherlen = hexdec($cipherlen);

    $data = substr($message, ($len + 19), $cipherlen);

    $rsa = new Crypt_RSA();
    $rsa->loadKey($this->public_key);
    $key = $rsa->decrypt($key);

    if ($key === false || empty($key))
    {
        return false;
    }

    $rij = new Crypt_Rijndael();
    $rij->setKey($key);
    return $rij->decrypt($data);
}

2) Restricción de extensiones para aceptar solo ficheros típicos de backup

Además, se introduce una validación del nombre de archivo y una lista blanca de extensiones permitidas para la función de recepción. En el snippet del parche se ve una normalización del nombre (usando basename() y un preg_replace) y el control de extensiones permitidas: zip, gz, tar, sql.

$safe_name = basename($params['name']);
$safe_name = preg_replace('/[^a-zA-Z0-9._-]/', '', $safe_name);
$allowed_extensions = array('zip', 'gz', 'tar', 'sql');
$file_ext = strtolower(pathinfo($safe_name, PATHINFO_EXTENSION));

if (!in_array($file_ext, $allowed_extensions, true))
{
    $ret['result'] = WPVIVID_FAILED;
    $ret['error']  = 'Invalid file type - only backup files allowed.';
    echo wp_json_encode($ret);
    die();
}

Qué sitios deberían considerarse en riesgo (checklist rápida)

  • Tienes instalado WPvivid Backup & Migration en una versión <= 0.9.123.
  • Has usado o habilitado la funcionalidad para recibir un backup desde otro sitio (clave generada en los ajustes del plugin).
  • Aunque la clave sea temporal (máximo 24 horas), si el endpoint estuvo expuesto durante ese periodo, el riesgo existe.

Mitigación y recomendaciones operativas

La acción principal es simple: actualizar WPvivid Backup a 0.9.124 (versión corregida en el momento de la publicación del aviso). Dada la naturaleza de una subida arbitraria con potencial de RCE, no es el tipo de fallo que convenga posponer.

En paralelo, si en tu entorno se utiliza Wordfence, el aviso indica que Wordfence Premium, Wordfence Care y Wordfence Response recibieron una regla de firewall el 22 de enero de 2026 para bloquear intentos de explotación. En Wordfence Free, esa misma protección llegaría 30 días después, el 21 de febrero de 2026.

Fechas clave del firewall de Wordfence (según el aviso)

Regla disponible para Premium/Care/Response: 22 de enero de 2026. Regla disponible para Wordfence Free: 21 de febrero de 2026.

Timeline de divulgación (Disclosure Timeline)

  • January 12, 2026 – Se recibe el reporte de la vulnerabilidad de subida arbitraria en WPvivid Backup a través del Bug Bounty Program de Wordfence.
  • January 22, 2026 – Se valida el reporte y se confirma el exploit de prueba de concepto (PoC). Se contacta con el proveedor y se le invita a usar el Wordfence Vulnerability Management Portal.
  • January 22, 2026 – Usuarios de Wordfence Premium, Wordfence Care y Wordfence Response reciben una regla de firewall para mitigar intentos de explotación.
  • January 23, 2026 – El proveedor responde y decide gestionar la divulgación por email.
  • January 23, 2026 – Se envían los detalles completos al proveedor; se confirma recepción y se inicia el trabajo de corrección.
  • January 28, 2026 – Se publica la versión corregida del plugin: 0.9.124.
  • February 21, 2026 – Los usuarios de Wordfence Free recibirán la misma protección.

Cierre: qué hacer ahora mismo

El caso de WPvivid Backup es un recordatorio clásico de por qué las rutas de “importación/recepción” (backups, migraciones, staging) son superficie de ataque prioritaria: si algo permite escribir archivos y el control falla, el salto a RCE suele estar cerca.

Si gestionas sitios WordPress con este plugin, verifica versión y actualiza a 0.9.124 cuanto antes, especialmente si has utilizado la opción de clave para recibir backups desde otro sitio. El fallo está catalogado como crítico (CVSS 9.8) y el vector descrito permite ataques sin autenticación.

¡Únete a la comunidad de HelloWP!

Chatea con nosotros sobre WordPress, desarrollo web y comparte experiencias con otros desarrolladores.

- miembros
- en línea
Unirse

Usamos cookies para mejorar tu experiencia. Al continuar, aceptas nuestra Política de cookies.