Критична уязвимост за произволно качване на файлове в WPvivid Backup: кога реално те засяга и какво да направиш
Сериозен security advisory от Wordfence засегна плъгина WPvivid Backup & Migration (в Wordfence Intelligence е описан като Migration, Backup, Staging), който има над 800,000 активни инсталации. Става дума за Unauthenticated Arbitrary File Upload уязвимост, която при успешна експлоатация води до Remote Code Execution (RCE) – класически сценарий за пълен takeover на WordPress сайт.
Важният нюанс: по данните в публикацията уязвимостта е критично релевантна основно за сайтове, на които е генериран ключ в настройките на плъгина, за да позволят друг сайт да изпрати бекъп към тях. Тази функционалност е изключена по подразбиране, а валидността на ключа може да се зададе до максимум 24 часа.
Обобщение на уязвимостта (CVE, версии, риск)
- Уязвимост: Unauthenticated Arbitrary File Upload (произволно качване на файлове без автентикация)
- Оценка: CVSS 9.8 (Critical)
- CVE: CVE-2026-1357
- Засегнати версии: <= 0.9.123
- Поправена версия: 0.9.124
- Компонент/slug: wpvivid-backuprestore
- Вектор на атака (според описанието): параметър
wpvivid_action=send_to_site
Кога уязвимостта те засяга реално
Wordfence изрично отбелязват, че проблемът става критичен при конкретна конфигурация: когато в WPvivid е генериран краткосрочен ключ (token/key) за функцията, която позволява сайтът ти да получава бекъп от друг сайт. Ако не използваш този сценарий и не си активирал/генерирал ключ, рискът е значително по-нисък.
Провери настройките на WPvivid
Ако имаш активиран режим за получаване на бекъп от друг сайт (генериран ключ), приеми, че сайтът ти е в най-рисковата група и обнови веднага до 0.9.124.
Как работи атаката: как една грешка в криптирането отваря път за качване на PHP
Техническата част е интересна, защото не е просто „липсва проверка за разширение“. Описанието сочи комбинация от два проблема:
- Неправилно обработване на грешки при RSA дешифриране + липса на sanitize на пътя/името при запис на качения файл.
- При провал на RSA дешифриране (в публикацията е посочено
openssl_private_decrypt()като контекст), плъгинът не прекратява изпълнението, а вместо това подава булева стойностfalseкъм инициализацията на AES cipher в phpseclib. - Библиотеката третира
falseкато низ от null байтове, което прави ключа предвидим (null-byte key). Така атакуващ може да изгради криптиран payload, който да бъде успешно „дешифриран“ с този предвидим ключ. - Отделно, плъгинът приема имена на файлове от дешифрирания payload без path sanitization, което позволява directory traversal и излизане извън защитената директория за бекъпи.
- Крайният резултат: неавтентикиран атакуващ може да качи произволен PHP файл в публично достъпна директория и да го изпълни, което води до RCE.
Къде в кода се случва
Wordfence посочват, че приемането на бекъп файл се обработва от send_to_site() в класа WPvivid_Send_to_site. Там се взима wpvivid_content от $_POST, декодира се, и се подава към decrypt_message() от WPvivid_crypt.
public function send_to_site()
{
include_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-crypt.php';
// ...
if (isset($_POST['wpvivid_content'])) {
$option = get_option('wpvivid_api_token', array());
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);
// ... обработка и запис на файл
}
}В decrypt_message() проблемът е, че при неуспешно RSA дешифриране стойността $key може да стане false, но въпреки това се ползва за ключ на Crypt_Rijndael().
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);
}Това отваря вратата за предвидим „нулев“ ключ и възможност за злонамерен криптиран payload. В комбинация с липсваща sanitation на пътя/името, атакуващ може да избяга от backup директорията и да запише файл там, където после може да бъде изпълнен от PHP.
Какво променя пачът в 0.9.124
По описанието в Wordfence, фиксовете са в две направления: (1) валидиране на резултата от RSA дешифриране; (2) ограничаване на качваните файлове до типове, характерни за бекъп.
1) Stop-логика при невалиден ключ
Разработчикът добавя проверка дали $key е false или празен и прекратява процеса (връща false), преди да инициализира cipher-а.
$key = $rsa->decrypt($key);
if ($key === false || empty($key))
{
return false;
}
$rij = new Crypt_Rijndael();
$rij->setKey($key);
return $rij->decrypt($data);2) Проверка на разширението и sanitize на името
В send_to_site() е добавена проверка на разширението и по-безопасно формиране на името чрез basename() и preg_replace(). Позволени са само разширения, типични за бекъп/архиви: 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();
}Как да се защитиш (чеклист за админи и дев екипи)
- Обнови WPvivid Backup до 0.9.124 (или по-нова, ако вече има). Това е ключовото действие, защото уязвимостта е напълно адресирана в 0.9.124 според публикацията.
- Провери дали е генериран ключ за „receive backup from another site“ функционалността. Ако този сценарий не ти трябва, не го активирай.
- Ако функционалността ти трябва: дръж ключовете краткосрочни. Плъгинът позволява expiration максимум 24 часа – използвай го по предназначение и не оставяй ключове активни без нужда.
- Ако ползваш Wordfence: имай предвид, че Wordfence Premium/Care/Response са получили firewall правило на January 22, 2026, а Wordfence Free получава същата защита 30 дни по-късно – February 21, 2026.
- Прегледай файловата система за неочаквани PHP файлове в директории, които са публично достъпни (типичен признак при arbitrary upload → webshell). Това е особено важно, ако знаеш, че е имало активиран ключ в рисковия период.
- Минимизирай щетите при пробив: ограничи write права там, където не са нужни, и следи за промени по файловете (file integrity monitoring).
Детайли от disclosure процеса (хронология)
Wordfence публикуват и ясна timeline на disclosure-а, която е полезна за оценка на риска и прозореца за експлоатация:
- January 12, 2026 – подаден е репорт за Arbitrary File Upload уязвимостта чрез Wordfence Bug Bounty Program.
- January 22, 2026 – Wordfence валидират репорта и потвърждават proof-of-concept експлойта. Изпращат първоначален контакт към доставчика и предлагат използване на Wordfence Vulnerability Management Portal.
- January 22, 2026 – потребителите на Wordfence Premium, Wordfence Care и Wordfence Response получават firewall правило за допълнителна защита.
- January 23, 2026 – доставчикът отговаря и избира комуникация по email.
- January 23, 2026 – Wordfence изпращат пълните детайли по disclosure-а; доставчикът потвърждава и започва работа по fix.
- January 28, 2026 – излиза напълно поправената версия 0.9.124.
- February 21, 2026 – потребителите на Wordfence Free получават същото firewall правило.
Кредит към откривателя и контекст за Bug Bounty
Уязвимостта е открита и докладвана от Lucas Montes (NiRoX) чрез Wordfence Bug Bounty Program. По публикацията репортът е постъпил само 5 дни след въвеждането на уязвимостта, а изплатената награда е $2,145.00.
Тези детайли са полезни, защото показват колко бързо може да се появи критичен дефект и колко важни са процесите по disclosure и реакция от страна на доставчика. В конкретния случай разработчиците на WPvivid пускат пач сравнително бързо и Wordfence ги отбелязват за навременна и прозрачна реакция.
Заключение
CVE-2026-1357 е критична уязвимост в WPvivid Backup & Migration (версии 0.9.123 и по-стари), която позволява неавтентикирано качване на произволни файлове и потенциално RCE, включително чрез webshell сценарии. Фиксът е наличен в 0.9.124 и включва както правилно прекратяване при невалиден криптографски ключ, така и ограничения върху типовете файлове, които могат да бъдат качвани през функционалността за receiving backups.
Препратки / Източници
Мария Иванова
Главен редактор на българския екип, разработчик на AI и машинно обучение. PyTorch и обработката на естествен език са моите основни области. Бъдещето вече е тук.
Всички публикации