{"id":222,"date":"2026-02-11T16:39:52","date_gmt":"2026-02-11T15:39:52","guid":{"rendered":"https:\/\/helloblog.io\/ro\/cve-2026-1357-wpvivid-backup-upload-fisiere-fara-autentificare-rce\/"},"modified":"2026-02-11T16:39:52","modified_gmt":"2026-02-11T15:39:52","slug":"cve-2026-1357-wpvivid-backup-upload-fisiere-fara-autentificare-rce","status":"publish","type":"post","link":"https:\/\/helloblog.io\/ro\/cve-2026-1357-wpvivid-backup-upload-fisiere-fara-autentificare-rce\/","title":{"rendered":"CVE-2026-1357 \u00een WPvivid Backup: upload de fi\u0219iere f\u0103r\u0103 autentificare \u0219i risc de RCE pe site-uri WordPress (p\u00e2n\u0103 la 0.9.123)"},"content":{"rendered":"\n<p>Un advisory publicat de Wordfence atrage aten\u021bia asupra unei vulnerabilit\u0103\u021bi critice din pluginul <strong>Migration, Backup, Staging \u2013 WPvivid Backup &#038; Migration<\/strong> (slug: <code>wpvivid-backuprestore<\/code>), cu peste <strong>800.000<\/strong> de instal\u0103ri active. Problema este clasificat\u0103 ca <strong>Unauthenticated Arbitrary File Upload<\/strong> \u0219i, \u00een scenariul potrivit, poate duce la <strong>Remote Code Execution (RCE)<\/strong> &#8211; adic\u0103 un atacator poate ajunge s\u0103 ruleze cod pe server \u0219i, de multe ori, la compromiterea complet\u0103 a site-ului.<\/p>\n\n\n\n<div class=\"wp-block-group callout callout-warning is-style-warning is-layout-flow wp-block-group-is-layout-flow\" style=\"border-width:1px;border-radius:8px;padding-top:1rem;padding-right:1.5rem;padding-bottom:1rem;padding-left:1.5rem\">\n\n<h4 class=\"wp-block-heading callout-title\">Condi\u021bie important\u0103 de impact<\/h4>\n\n\n<p>Conform analizei Wordfence, vulnerabilitatea afecteaz\u0103 \u00een mod critic doar site-urile care au activat func\u021bia de a primi backup de la un alt site printr-o cheie generat\u0103 \u00een set\u0103rile WPvivid. Op\u021biunea este dezactivat\u0103 implicit, iar expirarea cheii poate fi setat\u0103 la maximum 24 de ore.<\/p>\n\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Pe scurt: ce s-a \u00eent\u00e2mplat \u0219i cine este afectat<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Vulnerabilitate: <strong>Unauthenticated Arbitrary File Upload<\/strong> (\u00eenc\u0103rcare de fi\u0219iere arbitrare f\u0103r\u0103 autentificare).<\/li>\n\n\n<li>Impact: posibil <strong>RCE<\/strong> \u0219i preluare complet\u0103 a site-ului (de ex. prin webshell).<\/li>\n\n\n<li>Plugin: <strong>Migration, Backup, Staging \u2013 WPvivid Backup &#038; Migration<\/strong> (<code>wpvivid-backuprestore<\/code>).<\/li>\n\n\n<li>Versiuni afectate: <strong><= 0.9.123<\/strong>.<\/li>\n\n\n<li>Versiune reparat\u0103: <strong>0.9.124<\/strong>.<\/li>\n\n\n<li>CVE: <strong>CVE-2026-1357<\/strong>.<\/li>\n\n\n<li>Scor: <strong>CVSS 9.8 (Critical)<\/strong>.<\/li>\n\n\n<li>Vector de atac men\u021bionat: parametru <code>wpvivid_action=send_to_site<\/code>.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Detalii din Wordfence Intelligence (rezumatul vulnerabilit\u0103\u021bii)<\/h2>\n\n\n\n<p>Wordfence descrie cauza ca o combina\u021bie \u00eentre <strong>gestionare incorect\u0103 a erorilor \u00een decriptarea RSA<\/strong> \u0219i <strong>lipsa sanitiz\u0103rii c\u0103ii (path) atunci c\u00e2nd fi\u0219ierele sunt scrise pe disc<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Pluginul \u00eencearc\u0103 s\u0103 decripteze o cheie de sesiune cu <code>openssl_private_decrypt()<\/code> (\u00een implementarea lor via <code>Crypt_RSA()<\/code>\/phpseclib).<\/li>\n\n\n<li>C\u00e2nd decriptarea cheii e\u0219ueaz\u0103, rezultatul ajunge s\u0103 fie <code>false<\/code>. \u00cen loc s\u0103 opreasc\u0103 execu\u021bia, codul continu\u0103 \u0219i paseaz\u0103 acest <code>false<\/code> c\u0103tre ini\u021bializarea cifrului AES\/Rijndael.<\/li>\n\n\n<li>Biblioteca (phpseclib) trateaz\u0103 <code>false<\/code> ca un \u0219ir de <strong>null bytes<\/strong>, ceea ce face cheia efectiv <strong>predictibil\u0103<\/strong> (un fel de \u201echeie nul\u0103\u201d).<\/li>\n\n\n<li>Atacatorul poate cripta un payload mali\u021bios folosind aceast\u0103 cheie predictibil\u0103 \u0219i poate controla con\u021binutul decriptat.<\/li>\n\n\n<li>\u00cen plus, numele fi\u0219ierului este luat din payload-ul decriptat f\u0103r\u0103 sanitizare adecvat\u0103, permi\u021b\u00e2nd <strong>directory traversal<\/strong> (ie\u0219irea din directorul protejat de backup).<\/li>\n\n\n<li>Consecin\u021b\u0103: un atacator neautentificat poate \u00eenc\u0103rca fi\u0219iere (inclusiv <strong>PHP<\/strong>) \u00een directoare public accesibile \u0219i apoi le poate accesa pentru a ob\u021bine <strong>RCE<\/strong>.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Cum apare bug-ul \u00een fluxul de \u201esend to site\u201d<\/h2>\n\n\n\n<p>Func\u021bionalitatea relevant\u0103 este cea prin care un site poate primi un backup de la alt site, pe baza unei chei generate din set\u0103rile pluginului. Wordfence indic\u0103 faptul c\u0103 recep\u021bia fi\u0219ierului este gestionat\u0103 de metoda <code>send_to_site()<\/code> din clasa <code>WPvivid_Send_to_site<\/code>, iar mesajul criptat este procesat printr-o rutin\u0103 de decriptare (<code>decrypt_message()<\/code>) din clasa <code>WPvivid_crypt<\/code>.<\/p>\n\n\n\n<p>Din codul analizat de Wordfence rezult\u0103 c\u0103 pluginul ia tokenul\/cheia din op\u021biunile salvate (<code>wpvivid_api_token<\/code>), verific\u0103 existen\u021ba \u0219i expirarea, apoi decripteaz\u0103 con\u021binutul primit \u00een <code>$_POST['wpvivid_content']<\/code>. Problema apare atunci c\u00e2nd decriptarea cheii e\u0219ueaz\u0103, dar codul nu se opre\u0219te, iar cifrul simetric este ini\u021bializat cu o valoare care ajunge s\u0103 fie tratat\u0103 ca \u201enull bytes\u201d.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public function decrypt_message($message)\n{\n    $len = substr($message, 0, 3);\n    $len = hexdec($len);\n\n    $key = substr($message, 3, $len);\n\n    $cipherlen = substr($message, ($len + 3), 16);\n    $cipherlen = hexdec($cipherlen);\n\n    $data = substr($message, ($len + 19), $cipherlen);\n\n    $rsa = new Crypt_RSA();\n    $rsa-&gt;loadKey($this-&gt;public_key);\n\n    $key = $rsa-&gt;decrypt($key);\n\n    $rij = new Crypt_Rijndael();\n    $rij-&gt;setKey($key);\n\n    return $rij-&gt;decrypt($data);\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#F97583\">public<\/span><span style=\"color:#F97583\"> function<\/span><span style=\"color:#B392F0\"> decrypt_message<\/span><span style=\"color:#E1E4E8\">($message)<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $len <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> substr<\/span><span style=\"color:#E1E4E8\">($message, <\/span><span style=\"color:#79B8FF\">0<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#79B8FF\">3<\/span><span style=\"color:#E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $len <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> hexdec<\/span><span style=\"color:#E1E4E8\">($len);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $key <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> substr<\/span><span style=\"color:#E1E4E8\">($message, <\/span><span style=\"color:#79B8FF\">3<\/span><span style=\"color:#E1E4E8\">, $len);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $cipherlen <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> substr<\/span><span style=\"color:#E1E4E8\">($message, ($len <\/span><span style=\"color:#F97583\">+<\/span><span style=\"color:#79B8FF\"> 3<\/span><span style=\"color:#E1E4E8\">), <\/span><span style=\"color:#79B8FF\">16<\/span><span style=\"color:#E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $cipherlen <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> hexdec<\/span><span style=\"color:#E1E4E8\">($cipherlen);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $data <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> substr<\/span><span style=\"color:#E1E4E8\">($message, ($len <\/span><span style=\"color:#F97583\">+<\/span><span style=\"color:#79B8FF\"> 19<\/span><span style=\"color:#E1E4E8\">), $cipherlen);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $rsa <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#F97583\"> new<\/span><span style=\"color:#79B8FF\"> Crypt_RSA<\/span><span style=\"color:#E1E4E8\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $rsa<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#B392F0\">loadKey<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#79B8FF\">$this<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#E1E4E8\">public_key);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $key <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#E1E4E8\"> $rsa<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#B392F0\">decrypt<\/span><span style=\"color:#E1E4E8\">($key);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $rij <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#F97583\"> new<\/span><span style=\"color:#79B8FF\"> Crypt_Rijndael<\/span><span style=\"color:#E1E4E8\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $rij<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#B392F0\">setKey<\/span><span style=\"color:#E1E4E8\">($key);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">    return<\/span><span style=\"color:#E1E4E8\"> $rij<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#B392F0\">decrypt<\/span><span style=\"color:#E1E4E8\">($data);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Interpretarea Wordfence este c\u0103, \u00een cazul unei chei invalide, <code>$key<\/code> devine <code>false<\/code>, iar ini\u021bializarea Rijndael\/AES cu aceast\u0103 valoare produce o cheie efectiv predictibil\u0103 (null bytes). Asta reduce semnificativ bariera criptografic\u0103 \u0219i permite construirea unui payload valid din perspectiva decript\u0103rii.<\/p>\n\n\n\n<p>Mai departe, componenta de upload nu impune verific\u0103ri solide pentru tip\/extensie, iar acceptarea numelor de fi\u0219iere din payload f\u0103r\u0103 sanitizare deschide u\u0219a c\u0103tre <strong>scriere \u00een afara directorului de backup<\/strong> (directory traversal). \u00cen combina\u021bie, rezultatul este un scenariu clasic de <strong>arbitrary file upload<\/strong> care poate ajunge la \u00eenc\u0103rcarea de fi\u0219iere PHP \u0219i executarea lor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ce a schimbat patch-ul (WPvivid 0.9.124)<\/h2>\n\n\n\n<p>Wordfence men\u021bioneaz\u0103 dou\u0103 remedieri principale livrate de vendor \u00een versiunea <strong>0.9.124<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>O verificare explicit\u0103 pentru cheia decriptat\u0103: dac\u0103 <code>$key<\/code> este <code>false<\/code> sau gol, func\u021bia de decriptare se opre\u0219te \u0219i returneaz\u0103 <code>false<\/code> (\u00een loc s\u0103 continue cu o cheie predictibil\u0103).<\/li>\n\n\n<li>O verificare de extensie \u00een <code>send_to_site()<\/code> astfel \u00eenc\u00e2t s\u0103 fie acceptate doar tipuri specifice de fi\u0219iere de backup.<\/li>\n\n<\/ol>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>if ($key === false || empty($key))\n{\n    return false;\n}\n\n$rij = new Crypt_Rijndael();\n$rij-&gt;setKey($key);\nreturn $rij-&gt;decrypt($data);\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#F97583\">if<\/span><span style=\"color:#E1E4E8\"> ($key <\/span><span style=\"color:#F97583\">===<\/span><span style=\"color:#79B8FF\"> false<\/span><span style=\"color:#F97583\"> ||<\/span><span style=\"color:#79B8FF\"> empty<\/span><span style=\"color:#E1E4E8\">($key))<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">    return<\/span><span style=\"color:#79B8FF\"> false<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">$rij <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#F97583\"> new<\/span><span style=\"color:#79B8FF\"> Crypt_Rijndael<\/span><span style=\"color:#E1E4E8\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">$rij<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#B392F0\">setKey<\/span><span style=\"color:#E1E4E8\">($key);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">return<\/span><span style=\"color:#E1E4E8\"> $rij<\/span><span style=\"color:#F97583\">-><\/span><span style=\"color:#B392F0\">decrypt<\/span><span style=\"color:#E1E4E8\">($data);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>$safe_name = basename($params['name']);\n$safe_name = preg_replace('\/[^a-zA-Z0-9._-]\/', '', $safe_name);\n\n$allowed_extensions = array('zip', 'gz', 'tar', 'sql');\n$file_ext = strtolower(pathinfo($safe_name, PATHINFO_EXTENSION));\n\nif (!in_array($file_ext, $allowed_extensions, true))\n{\n    $ret['result'] = WPVIVID_FAILED;\n    $ret['error'] = 'Invalid file type - only backup files allowed.';\n    echo wp_json_encode($ret);\n    die();\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">$safe_name <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> basename<\/span><span style=\"color:#E1E4E8\">($params[<\/span><span style=\"color:#9ECBFF\">'name'<\/span><span style=\"color:#E1E4E8\">]);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">$safe_name <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> preg_replace<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#9ECBFF\">'\/<\/span><span style=\"color:#DBEDFF\">[^a-zA-Z0-9._-]<\/span><span style=\"color:#9ECBFF\">\/'<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">''<\/span><span style=\"color:#E1E4E8\">, $safe_name);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">$allowed_extensions <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> array<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#9ECBFF\">'zip'<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">'gz'<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">'tar'<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">'sql'<\/span><span style=\"color:#E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">$file_ext <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> strtolower<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#79B8FF\">pathinfo<\/span><span style=\"color:#E1E4E8\">($safe_name, <\/span><span style=\"color:#79B8FF\">PATHINFO_EXTENSION<\/span><span style=\"color:#E1E4E8\">));<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">if<\/span><span style=\"color:#E1E4E8\"> (<\/span><span style=\"color:#F97583\">!<\/span><span style=\"color:#79B8FF\">in_array<\/span><span style=\"color:#E1E4E8\">($file_ext, $allowed_extensions, <\/span><span style=\"color:#79B8FF\">true<\/span><span style=\"color:#E1E4E8\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $ret[<\/span><span style=\"color:#9ECBFF\">'result'<\/span><span style=\"color:#E1E4E8\">] <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> WPVIVID_FAILED<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    $ret[<\/span><span style=\"color:#9ECBFF\">'error'<\/span><span style=\"color:#E1E4E8\">] <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#9ECBFF\"> 'Invalid file type - only backup files allowed.'<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    echo<\/span><span style=\"color:#B392F0\"> wp_json_encode<\/span><span style=\"color:#E1E4E8\">($ret);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">    die<\/span><span style=\"color:#E1E4E8\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">M\u0103suri recomandate pentru administratori \u0219i echipe tehnice<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>Actualizeaz\u0103 imediat WPvivid Backup la <strong>0.9.124<\/strong> (sau mai nou, dac\u0103 exist\u0103).<\/li>\n\n\n<li>Verific\u0103 dac\u0103 ai activat func\u021bia de \u201ereceive a backup from another site\u201d \/ trimitere \u00eentre site-uri \u0219i dac\u0103 exist\u0103 o <strong>cheie generat\u0103<\/strong> \u00een set\u0103rile pluginului (acesta e scenariul critic men\u021bionat).<\/li>\n\n\n<li>Dac\u0103 nu ai nevoie de transfer de backup \u00eentre site-uri, p\u0103streaz\u0103 func\u021bia dezactivat\u0103 (este dezactivat\u0103 implicit) \u0219i evit\u0103 p\u0103strarea cheilor active mai mult dec\u00e2t e necesar (expirarea este limitat\u0103 la 24 de ore).<\/li>\n\n\n<li>Aplic\u0103 o protec\u021bie la nivel de firewall\/WAF: Wordfence a distribuit reguli de protec\u021bie pentru clien\u021bii Premium\/Care\/Response \u0219i ulterior pentru Wordfence Free (detalii mai jos).<\/li>\n\n\n<li>Ca verificare post-incident: caut\u0103 fi\u0219iere PHP nea\u0219teptate \u00een directoare publice \u0219i semne de webshell (mai ales dac\u0103 func\u021bia a fost activ\u0103 \u0219i site-ul a fost expus \u00een intervalul respectiv).<\/li>\n\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Protec\u021bia Wordfence: c\u00e2nd au ajuns regulile de firewall<\/h2>\n\n\n\n<p>Conform Wordfence, utilizatorii <strong>Wordfence Premium<\/strong>, <strong>Wordfence Care<\/strong> \u0219i <strong>Wordfence Response<\/strong> au primit o regul\u0103 de firewall pentru blocarea exploit-urilor care \u021bintesc aceast\u0103 vulnerabilitate la data de <strong>January 22, 2026<\/strong>. Pentru <strong>Wordfence Free<\/strong>, aceea\u0219i protec\u021bie este programat\u0103 s\u0103 ajung\u0103 la <strong>February 21, 2026<\/strong> (diferen\u021ba standard de 30 de zile).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Disclosure timeline (cronologia publicat\u0103)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>January 12, 2026 &#8211; Wordfence prime\u0219te raportarea vulnerabilit\u0103\u021bii prin Bug Bounty Program.<\/li>\n\n\n<li>January 22, 2026 &#8211; Wordfence valideaz\u0103 raportul \u0219i confirm\u0103 proof-of-concept; contacteaz\u0103 vendorul \u0219i \u00eel invit\u0103 s\u0103 foloseasc\u0103 Wordfence Vulnerability Management Portal: https:\/\/www.wordfence.com\/threat-intel\/vendor\/vulnerability-management-portal\/<\/li>\n\n\n<li>January 22, 2026 &#8211; Regula de firewall este livrat\u0103 c\u0103tre Wordfence Premium\/Care\/Response.<\/li>\n\n\n<li>January 23, 2026 &#8211; Vendorul r\u0103spunde \u0219i alege comunicarea prin email.<\/li>\n\n\n<li>January 23, 2026 &#8211; Wordfence trimite detaliile complete; vendorul confirm\u0103 \u0219i \u00eencepe remedierea.<\/li>\n\n\n<li>January 28, 2026 &#8211; Este lansat\u0103 versiunea complet patch-uit\u0103: <strong>0.9.124<\/strong>.<\/li>\n\n\n<li>February 21, 2026 &#8211; Wordfence Free urmeaz\u0103 s\u0103 primeasc\u0103 protec\u021bia prin firewall.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Cine a descoperit vulnerabilitatea<\/h2>\n\n\n\n<p>Vulnerabilitatea a fost descoperit\u0103 \u0219i raportat\u0103 responsabil de <strong>Lucas Montes (NiRoX)<\/strong> prin programul Wordfence Bug Bounty. Wordfence noteaz\u0103 c\u0103 raportarea a venit la doar cinci zile dup\u0103 introducerea problemei \u0219i c\u0103 researcherul a primit un bounty de <strong>$2,145.00<\/strong>.<\/p>\n\n\n\n<p>Detalii despre researcher: https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/researchers\/lucas-montes<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Concluzie<\/h2>\n\n\n\n<p>CVE-2026-1357 este un exemplu clar de bug critic care apare din combinarea a dou\u0103 probleme: tratarea gre\u0219it\u0103 a unei erori criptografice (continuarea execu\u021biei cu o cheie invalid\u0103) \u0219i controale insuficiente la scrierea fi\u0219ierelor (inclusiv posibil directory traversal). Dac\u0103 folose\u0219ti WPvivid Backup \u0219i ai activat transferul de backup \u00eentre site-uri cu cheie generat\u0103, actualizarea la <strong>0.9.124<\/strong> este esen\u021bial\u0103.<\/p>\n\n\n\n<div class=\"wp-block-group callout callout-success is-style-success is-layout-flow wp-block-group-is-layout-flow\" style=\"border-width:1px;border-radius:8px;padding-top:1rem;padding-right:1.5rem;padding-bottom:1rem;padding-left:1.5rem\">\n\n<h4 class=\"wp-block-heading callout-title\">Versiunea sigur\u0103<\/h4>\n\n\n<p>Wordfence indic\u0103 drept versiune reparat\u0103 <strong>WPvivid Backup 0.9.124<\/strong> (la momentul public\u0103rii advisory-ului). Versiunile <strong><= 0.9.123<\/strong> sunt afectate.<\/p>\n\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Linkuri utile (din advisory)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Advisory Wordfence: https:\/\/www.wordfence.com\/blog\/2026\/02\/800000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-wpvivid-backup-wordpress-plugin\/<\/li>\n\n\n<li>Fi\u0219a vulnerabilit\u0103\u021bii \u00een Wordfence Intelligence: https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/wordpress-plugins\/wpvivid-backuprestore\/migration-backup-staging-09123-unauthenticated-arbitrary-file-upload<\/li>\n\n\n<li>CVE record: https:\/\/www.cve.org\/CVERecord?id=CVE-2026-1357<\/li>\n\n\n<li>Plugin pe WordPress.org: https:\/\/wordpress.org\/plugins\/wpvivid-backuprestore\/<\/li>\n\n\n<li>Wordfence Bug Bounty Program: https:\/\/www.wordfence.com\/threat-intel\/bug-bounty-program\/<\/li>\n\n\n<li>Submit Vulnerability (Wordfence): https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/submit\/<\/li>\n\n\n<li>Wordfence Vulnerability Management Portal: https:\/\/www.wordfence.com\/threat-intel\/vendor\/vulnerability-management-portal\/<\/li>\n\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1504\" height=\"784\" src=\"https:\/\/helloblog.io\/app\/uploads\/sites\/10\/2026\/02\/FeaturedImage_Wordfence_303.01.png\" alt=\"Imagine de tip featured din advisory-ul Wordfence despre vulnerabilitatea WPvivid Backup\" class=\"wp-image-221\" srcset=\"https:\/\/helloblog.io\/app\/uploads\/sites\/10\/2026\/02\/FeaturedImage_Wordfence_303.01.png 1504w, https:\/\/helloblog.io\/app\/uploads\/sites\/10\/2026\/02\/FeaturedImage_Wordfence_303.01-300x156.png 300w, https:\/\/helloblog.io\/app\/uploads\/sites\/10\/2026\/02\/FeaturedImage_Wordfence_303.01-1024x534.png 1024w, https:\/\/helloblog.io\/app\/uploads\/sites\/10\/2026\/02\/FeaturedImage_Wordfence_303.01-768x400.png 768w, https:\/\/helloblog.io\/app\/uploads\/sites\/10\/2026\/02\/FeaturedImage_Wordfence_303.01-400x209.png 400w\" sizes=\"auto, (max-width: 1504px) 100vw, 1504px\" \/><figcaption class=\"wp-element-caption\">Advisory Wordfence: vulnerabilitate de tip Unauthenticated Arbitrary File Upload \u00een WPvivid Backup \u2014 <em>Forr\u00e1s: Wordfence.com<\/em><\/figcaption><\/figure>\n\n\n<div class=\"references-section\">\n                <h2>Referin\u021be \/ Surse<\/h2>\n                <ul class=\"references-list\"><li><a href=\"https:\/\/www.wordfence.com\/blog\/2026\/02\/800000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-wpvivid-backup-wordpress-plugin\/\" target=\"_blank\" rel=\"noopener noreferrer\">800,000 WordPress Sites Affected by Arbitrary File Upload Vulnerability in WPvivid Backup WordPress Plugin<\/a><\/li><li><a href=\"https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/wordpress-plugins\/wpvivid-backuprestore\/migration-backup-staging-09123-unauthenticated-arbitrary-file-upload\" target=\"_blank\" rel=\"noopener noreferrer\">Migration, Backup, Staging &lt;= 0.9.123 &#8212; Unauthenticated Arbitrary File Upload<\/a><\/li><li><a href=\"https:\/\/www.cve.org\/CVERecord?id=CVE-2026-1357\" target=\"_blank\" rel=\"noopener noreferrer\">CVE-2026-1357<\/a><\/li><li><a href=\"https:\/\/wordpress.org\/plugins\/wpvivid-backuprestore\/\" target=\"_blank\" rel=\"noopener noreferrer\">WPvivid Backup Plugin \u2013 wpvivid-backuprestore<\/a><\/li><li><a href=\"https:\/\/www.wordfence.com\/threat-intel\/bug-bounty-program\/\" target=\"_blank\" rel=\"noopener noreferrer\">Wordfence Bug Bounty Program<\/a><\/li><li><a href=\"https:\/\/www.wordfence.com\/threat-intel\/vendor\/vulnerability-management-portal\/\" target=\"_blank\" rel=\"noopener noreferrer\">Wordfence Vulnerability Management Portal<\/a><\/li><li><a href=\"https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/submit\/\" target=\"_blank\" rel=\"noopener noreferrer\">Submit Vulnerability<\/a><\/li><li><a href=\"https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/researchers\/lucas-montes\" target=\"_blank\" rel=\"noopener noreferrer\">Lucas Montes (NiRoX)<\/a><\/li><\/ul>\n            <\/div>","protected":false},"excerpt":{"rendered":"<p>O vulnerabilitate critic\u0103 (CVSS 9.8) din WPvivid Backup poate permite \u00eenc\u0103rcarea de fi\u0219iere arbitrare f\u0103r\u0103 autentificare \u0219i execu\u021bie de cod pe server, \u00een anumite configura\u021bii. Patch-ul exist\u0103: WPvivid 0.9.124.<\/p>\n","protected":false},"author":30,"featured_media":220,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[114,11,15,10,115],"class_list":["post-222","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-securitate","tag-cve-2026-1357","tag-securitate","tag-wordfence","tag-wordpress","tag-wpvivid-backup"],"_links":{"self":[{"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/posts\/222","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/users\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/comments?post=222"}],"version-history":[{"count":0,"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/posts\/222\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/media\/220"}],"wp:attachment":[{"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/media?parent=222"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/categories?post=222"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helloblog.io\/ro\/wp-json\/wp\/v2\/tags?post=222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}