{"id":194,"date":"2026-02-11T16:39:04","date_gmt":"2026-02-11T15:39:04","guid":{"rendered":"https:\/\/helloblog.io\/fi\/wpvivid-backup-migration-kriittinen-tiedostonlataushaavoittuvuus-cve-2026-1357\/"},"modified":"2026-02-11T16:39:04","modified_gmt":"2026-02-11T15:39:04","slug":"wpvivid-backup-migration-kriittinen-tiedostonlataushaavoittuvuus-cve-2026-1357","status":"publish","type":"post","link":"https:\/\/helloblog.io\/fi\/wpvivid-backup-migration-kriittinen-tiedostonlataushaavoittuvuus-cve-2026-1357\/","title":{"rendered":"WPvivid Backup &#038; Migration -lis\u00e4osasta l\u00f6ytyi kriittinen tiedostonlataushaavoittuvuus (CVE-2026-1357): n\u00e4in tarkistat riskin ja paikkaat oikein"},"content":{"rendered":"\n<p>Wordfence raportoi helmikuussa 2026 kriittisest\u00e4 haavoittuvuudesta WPvivid Backup &#038; Migration -lis\u00e4osassa (WordPress.org-slug: <code>wpvivid-backuprestore<\/code>). Lis\u00e4osalla on yli 800\u202f000 aktiivista asennusta, ja kyseess\u00e4 on luokkaa \u201cunauthenticated arbitrary file upload\u201d eli kirjautumaton hy\u00f6kk\u00e4\u00e4j\u00e4 voi tietyiss\u00e4 olosuhteissa ladata palvelimelle mielivaltaisen tiedoston. K\u00e4yt\u00e4nn\u00f6ss\u00e4 t\u00e4m\u00e4 tarkoittaa usein et\u00e4koodin suoritusta (Remote Code Execution, RCE) ja pahimmillaan koko sivuston haltuunottoa.<\/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\">Oleellinen rajaus: kaikki asennukset eiv\u00e4t ole yht\u00e4 lailla kriittisess\u00e4 riskiss\u00e4<\/h4>\n\n\n<p>Wordfencen mukaan haavoittuvuus osuu kriittisesti niihin sivustoihin, joissa WPvividin asetuksista on luotu \u201cgenerated key\u201d toisen sivuston varmuuskopion vastaanottamiseen. Ominaisuus on oletuksena pois p\u00e4\u00e4lt\u00e4, ja avaimen voimassaolo voidaan asettaa enint\u00e4\u00e4n 24 tuntiin.<\/p>\n\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Mik\u00e4 on haavoittuvuuden ydin (CVE-2026-1357)?<\/h2>\n\n\n\n<p>Wordfence Intelligence -tietojen mukaan WPvivid Backup &#038; Migration (haavoittuvuusotsikolla \u201cMigration, Backup, Staging <= 0.9.123 - Unauthenticated Arbitrary File Upload\u201d) on haavoittuva versioihin 0.9.123 asti. CVSS-luokitus on <strong>9.8 (Critical)<\/strong> ja CVE-tunnus on <strong>CVE-2026-1357<\/strong>. Korjattu versio on <strong>0.9.124<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>Vaikutus:<\/strong> kirjautumaton hy\u00f6kk\u00e4\u00e4j\u00e4 voi ladata mielivaltaisia tiedostoja ja saavuttaa et\u00e4koodin suorituksen (RCE), mik\u00e4 on tyypillinen reitti t\u00e4ydelliseen sivuston kompromissiin (esim. webshell).<\/li>\n\n\n<li><strong>Vaikuttavat versiot:<\/strong> <= 0.9.123<\/li>\n\n\n<li><strong>Korjattu versio:<\/strong> 0.9.124<\/li>\n\n\n<li><strong>CVE:<\/strong> CVE-2026-1357<\/li>\n\n\n<li><strong>CVSS:<\/strong> 9.8 (Critical)<\/li>\n\n\n<li><strong>Erityisehto kriittiselle hy\u00f6dynt\u00e4miselle:<\/strong> sivustossa on oltava WPvividiss\u00e4 luotu vastaanottoavain (\u201cgenerated key\u201d), jolla toinen sivusto voi l\u00e4hett\u00e4\u00e4 varmuuskopion t\u00e4h\u00e4n sivustoon.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Miksi t\u00e4m\u00e4 on mahdollinen: virheenk\u00e4sittely, salausavaimen nolla-avaimeksi \u201cputoaminen\u201d ja polun puhdistuksen puute<\/h2>\n\n\n\n<p>Wordfencen tekninen analyysi kuvaa ketjun, jossa useampi ongelma yhdess\u00e4 mahdollistaa hy\u00f6dynt\u00e4misen. WPvividiss\u00e4 on ominaisuus, jossa sivusto voi <strong>vastaanottaa varmuuskopion toiselta sivustolta<\/strong> lyhytik\u00e4isell\u00e4 avaimella. T\u00e4t\u00e4 vastaanottoa k\u00e4sitell\u00e4\u00e4n <code>WPvivid_Send_to_site<\/code>-luokan <code>send_to_site()<\/code>-funktiossa, jossa <code>wpvivid_content<\/code>-POST-parametri base64-dekoodataan ja puretaan <code>WPvivid_crypt<\/code>-luokan <code>decrypt_message()<\/code>-metodilla.<\/p>\n\n\n\n<p>Kriittinen kohta on RSA-purku ja sen virheenk\u00e4sittely: jos RSA-dekryptaus ep\u00e4onnistuu (Wordfencen yhteenvedossa mainitaan tilanne, jossa <code>openssl_private_decrypt()<\/code> ei onnistu), avainarvo voi p\u00e4\u00e4ty\u00e4 boolean <code>false<\/code> -tilaan. Wordfencen mukaan suoritus ei t\u00e4ll\u00f6in pys\u00e4hdy, vaan <code>false<\/code> sy\u00f6tet\u00e4\u00e4n seuraavaan vaiheeseen (phpseclibin AES-\/Rijndael-salauksen alustus). Kirjaston tulkinta johtaa k\u00e4yt\u00e4nn\u00f6ss\u00e4 ennustettavaan \u201cnull byte\u201d -avaimeen (nollatavuja), jolloin hy\u00f6kk\u00e4\u00e4j\u00e4 voi muodostaa hy\u00f6tykuorman, joka on salattu t\u00e4ll\u00e4 ennustettavalla avaimella.<\/p>\n\n\n\n<p>Toinen osa ketjua liittyy tiedoston kirjoittamiseen: Wordfencen mukaan lis\u00e4osa hyv\u00e4ksyy puretusta hy\u00f6tykuormasta tulevan tiedostonimen ilman riitt\u00e4v\u00e4\u00e4 polun sanitointia. T\u00e4m\u00e4 mahdollistaa directory traversal -tyyppisen polkumanipuloinnin, jolla voidaan karata suojatusta varmuuskopiohakemistosta ja kirjoittaa tiedosto julkisesti paljastettuun hakemistoon (esim. webrootin alle). Kun lis\u00e4ksi tiedoston latauksessa ei ollut tiedostotyypin tai p\u00e4\u00e4tteen tarkastusta, hy\u00f6kk\u00e4\u00e4j\u00e4 pystyi latamaan esimerkiksi PHP-tiedoston ja suorittamaan sen.<\/p>\n\n\n\n<div class=\"wp-block-group callout callout-danger is-style-danger 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\">Hy\u00f6kk\u00e4ysvektori Wordfencen mukaan<\/h4>\n\n\n<p>Wordfence kuvaa, ett\u00e4 hy\u00f6dynt\u00e4minen on mahdollista parametrin <code>wpvivid_action=send_to_site<\/code> kautta, jolloin kirjautumaton hy\u00f6kk\u00e4\u00e4j\u00e4 voi saada haitallisen PHP-tiedoston palvelimelle ja ajaa et\u00e4koodia.<\/p>\n\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Mit\u00e4 WPvivid korjasi versiossa 0.9.124?<\/h2>\n\n\n\n<p>Wordfencen mukaan korjaus koostuu kahdesta keskeisest\u00e4 muutoksesta:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li><code>decrypt_message()<\/code>-metodiin lis\u00e4ttiin tarkistus, joka pys\u00e4ytt\u00e4\u00e4 prosessin, jos RSA-purun tuloksena saatava <code>$key<\/code> on <code>false<\/code> tai tyhj\u00e4. K\u00e4yt\u00e4nn\u00f6ss\u00e4 t\u00e4m\u00e4 est\u00e4\u00e4 tilanteen, jossa salauksen avain \u201cputoaa\u201d ennustettavaan nolla-avaimeen.<\/li>\n\n\n<li><code>send_to_site()<\/code>-polkuun lis\u00e4ttiin tiedostop\u00e4\u00e4tteen tarkistus ja nimen turvallistaminen: tiedostonimi otetaan <code>basename()<\/code>-k\u00e4sittelyn kautta, siit\u00e4 poistetaan sallitun merkkijoukon ulkopuoliset merkit (<code>preg_replace('\/[^a-zA-Z0-9._-]\/', '', ...)<\/code>), ja sallittujen p\u00e4\u00e4tteiden listaksi asetetaan <code>zip<\/code>, <code>gz<\/code>, <code>tar<\/code>, <code>sql<\/code>. Jos p\u00e4\u00e4te ei ole sallittu, pyynt\u00f6 hyl\u00e4t\u00e4\u00e4n virheell\u00e4 \u201cInvalid file type &#8211; only backup files allowed.\u201d<\/li>\n\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Korjauksen kannalta kiinnostavat koodimuutokset (l\u00e4hteen mukaisesti)<\/h3>\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    $key = $rsa-&gt;decrypt($key);\n\n    \/\/ Patch: stop if key decrypt fails or empty\n    if ($key === false || empty($key))\n    {\n        return false;\n    }\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 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:#6A737D\">    \/\/ Patch: stop if key decrypt fails or empty<\/span><\/span>\n<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>\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<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\">Kenelle t\u00e4m\u00e4 on oikeasti kiireellinen? (WPvividin \u201csend backup to this site\u201d -avain)<\/h2>\n\n\n\n<p>Jos k\u00e4yt\u00e4t WPvivid Backup &#038; Migration -lis\u00e4osaa vain \u201cperinteiseen\u201d varmuuskopiointiin ja palautukseen ilman, ett\u00e4 olet ottanut k\u00e4ytt\u00f6\u00f6n ominaisuutta, jossa toinen sivusto l\u00e4hett\u00e4\u00e4 backupin sinun sivustollesi, riski on Wordfencen kuvauksen mukaan olennaisesti pienempi. Kriittinen hy\u00f6dynt\u00e4misskenaario edellytt\u00e4\u00e4 nimenomaan sit\u00e4, ett\u00e4 WPvividin asetuksissa on luotu vastaanottoavain (ja ominaisuus on siten kytketty p\u00e4\u00e4lle).<\/p>\n\n\n\n<div class=\"wp-block-group callout callout-info is-style-info 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\">Huomio avaimen voimassaolosta<\/h4>\n\n\n<p>Wordfence korostaa, ett\u00e4 ominaisuus on oletuksena pois p\u00e4\u00e4lt\u00e4 ja avaimen vanheneminen voidaan asettaa enint\u00e4\u00e4n 24 tuntiin. T\u00e4m\u00e4 v\u00e4hent\u00e4\u00e4 riski\u00e4, jos avainta k\u00e4ytet\u00e4\u00e4n vain hetkellisesti ja sen j\u00e4lkeen annetaan vanhentua.<\/p>\n\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Toimenpiteet: mit\u00e4 teet nyt tuotantosivustolla<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>Tarkista WPvivid Backup &#038; Migration -lis\u00e4osan versio. Jos se on <strong>0.9.123 tai vanhempi<\/strong>, sivusto on haavoittuva l\u00e4hteen kuvauksen mukaan.<\/li>\n\n\n<li>P\u00e4ivit\u00e4 lis\u00e4osa v\u00e4litt\u00f6m\u00e4sti korjattuun versioon <strong>0.9.124<\/strong> (julkaisutilanteen mukaan t\u00e4m\u00e4 on paikkaava versio).<\/li>\n\n\n<li>Jos olet k\u00e4ytt\u00e4nyt \u201creceive a backup from another site\u201d \/ \u201csend to site\u201d -ominaisuutta: tarkista, onko vastaanottoavain (generated key) yh\u00e4 aktiivinen, ja varmista ett\u00e4 avain vanhenee lyhyess\u00e4 ajassa (enint\u00e4\u00e4n 24h) tai poista se k\u00e4yt\u00f6st\u00e4, jos et tarvitse ominaisuutta.<\/li>\n\n\n<li>Varmista, ett\u00e4 suojauskerros on kunnossa: Wordfencen palomuuri (endpoint firewall) voi est\u00e4\u00e4 exploit-yrityksi\u00e4, mutta ensisijainen korjaus on aina lis\u00e4osan p\u00e4ivitys.<\/li>\n\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Wordfence-suojaus: milloin palomuuris\u00e4\u00e4nt\u00f6 tuli saataville?<\/h2>\n\n\n\n<p>Wordfencen mukaan palomuuris\u00e4\u00e4nt\u00f6, joka suojaa haavoittuvuuteen kohdistuvilta hy\u00f6kk\u00e4yksilt\u00e4, toimitettiin <strong>22.1.2026<\/strong> k\u00e4ytt\u00e4jille, joilla on <strong>Wordfence Premium<\/strong>, <strong>Wordfence Care<\/strong> tai <strong>Wordfence Response<\/strong>. Wordfence Free -k\u00e4ytt\u00e4jille sama suojaus tulee <strong>30 p\u00e4iv\u00e4\u00e4 my\u00f6hemmin<\/strong>, eli Wordfencen ilmoituksen mukaan <strong>21.2.2026<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Disclosure timeline (l\u00e4hteen aikajana)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>January 12, 2026<\/strong> &#8211; Haavoittuvuusraportti saapui Wordfencen Bug Bounty Programin kautta.<\/li>\n\n\n<li><strong>January 22, 2026<\/strong> &#8211; Wordfence validoi raportin ja vahvisti proof-of-concept -hy\u00f6dynt\u00e4misen. Samana p\u00e4iv\u00e4n\u00e4 Wordfence otti yhteytt\u00e4 toimittajaan ja ehdotti Wordfence Vulnerability Management Portal -palvelun k\u00e4ytt\u00f6\u00e4 haavoittuvuuden k\u00e4sittelyyn: https:\/\/www.wordfence.com\/threat-intel\/vendor\/vulnerability-management-portal\/<\/li>\n\n\n<li><strong>January 22, 2026<\/strong> &#8211; Wordfence Premium\/Care\/Response -asiakkaille julkaistiin palomuuris\u00e4\u00e4nt\u00f6 lis\u00e4suojaksi.<\/li>\n\n\n<li><strong>January 23, 2026<\/strong> &#8211; Toimittaja vastasi ja valitsi viestint\u00e4kanavaksi s\u00e4hk\u00f6postin.<\/li>\n\n\n<li><strong>January 23, 2026<\/strong> &#8211; Wordfence toimitti t\u00e4ydet yksityiskohdat, toimittaja kuittasi ja aloitti korjauksen.<\/li>\n\n\n<li><strong>January 28, 2026<\/strong> &#8211; Korjattu lis\u00e4osaversio <strong>0.9.124<\/strong> julkaistiin.<\/li>\n\n\n<li><strong>February 21, 2026<\/strong> &#8211; Wordfence Free -k\u00e4ytt\u00e4jille palomuuris\u00e4\u00e4nt\u00f6 tulee saataville.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Tutkija ja palkkio<\/h2>\n\n\n\n<p>Haavoittuvuuden l\u00f6ysi ja raportoi vastuullisesti Lucas Montes (NiRoX) Wordfencen Bug Bounty Programin kautta. Wordfencen mukaan raportti tuli ohjelmaan viisi p\u00e4iv\u00e4\u00e4 sen j\u00e4lkeen, kun haavoittuvuus oli ylip\u00e4\u00e4t\u00e4\u00e4n ehtinyt tulla mukaan koodiin. L\u00f6yd\u00f6st\u00e4 maksettu bounty oli <strong>2\u202f145 USD<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Yhteenveto<\/h2>\n\n\n\n<p>WPvivid Backup &#038; Migration -lis\u00e4osan versioissa <strong><= 0.9.123<\/strong> oli kriittinen \u201cunauthenticated arbitrary file upload\u201d -haavoittuvuus (CVE-2026-1357), joka voi mahdollistaa et\u00e4koodin suorituksen ja sivuston haltuunoton. Wordfencen mukaan pahin riski koskee niit\u00e4 asennuksia, joissa on luotu vastaanottoavain toisen sivuston varmuuskopion vastaanottamiseen. Korjaus on julkaistu versiossa <strong>0.9.124<\/strong>, joten t\u00e4rkein ja k\u00e4yt\u00e4nn\u00f6llisin toimenpide on p\u00e4ivitt\u00e4\u00e4 lis\u00e4osa heti.<\/p>\n\n\n<div class=\"references-section\">\n                <h2>Viitteet \/ L\u00e4hteet<\/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 \u2013 Plugin (WordPress.org)<\/a><\/li><\/ul>\n            <\/div>","protected":false},"excerpt":{"rendered":"<p>WPvivid Backup &#038; Migration -lis\u00e4osassa oli kriittinen haavoittuvuus, joka voi mahdollistaa mielivaltaisten tiedostojen lataamisen ja et\u00e4koodin suorituksen. Oikea korjaus on p\u00e4ivitt\u00e4\u00e4 versioon 0.9.124 ja varmistaa, ettei \u201csend backup to this site\u201d -avain j\u00e4\u00e4 turhaan voimaan.<\/p>\n","protected":false},"author":2,"featured_media":193,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[120,58,15,10,119],"class_list":["post-194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tietoturva","tag-cve-2026-1357","tag-haavoittuvuudet","tag-wordfence","tag-wordpress","tag-wpvivid"],"_links":{"self":[{"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/posts\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":0,"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/posts\/194\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/media\/193"}],"wp:attachment":[{"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/media?parent=194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/categories?post=194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helloblog.io\/fi\/wp-json\/wp\/v2\/tags?post=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}