WordPress brengt patch uit voor wp2shell-lek dat aanvallers code laat uitvoeren

Een beveiligingsbedrijf heeft kwetsbaarheden ontdekt die het mogelijk maken om op afstand code uit te voeren op WordPress-sites. De proof-of-concept voor dit 'wp2shell'-lek staat online. WordPress heeft de beveiligingslekken gedicht.

De rce-lek bevindt zich in de WordPress-kern, ontdekte Searchlight Cyber. Anders dan bij de meeste WordPress-kwetsbaarheden zijn daardoor ook sites zonder plug-ins kwetsbaar. De rce-aanval is mogelijk in WordPress-versies vanaf 6.9.0. Hoewel het beveiligingsbedrijf door de ernst van de kwetsbaarheid geen technische informatie deelt, staan er al meerdere proof-of-concepts op GitHub. Die beschrijven in detail hoe aanvallers de kwetsbaarheid kunnen uitbuiten.

De aanval maakt gebruik van twee kwetsbaarheden, CVE-2026-60137 en CVE-2026-63030. De eerste maakt een SQL-injectie in WP_Query mogelijk. Anonieme aanvallers kunnen die combineren met de tweede kwetsbaarheid in de REST-api. Zo kunnen ze de authenticatie omzeilen en code uitvoeren. Het lek wordt actief uitgebuit, zeggen beveiligingsbedrijven tegen SecurityWeek.

WordPress heeft de kwetsbaarheden gepatcht in versies 6.9.5 en 7.0.2. Door de ernst van het lek werkt WordPress sites met de getroffen versies automatisch bij. Sites die automatische updates hebben uitgeschakeld, moeten echter nog steeds handmatig updaten. Ook WordPress-versies 6.8.0 tot en met 6.8.5 zijn kwetsbaar voor de onderliggende SQL-injectie. Deze versies bevatten de kwetsbaarheid in de REST-api niet. WordPress heeft de SQL-injectie in versie 6.8.6 gepatcht.

cybersecurity, security, beveiliging, lock, slot (beeld: Getty Images, JuSun)

Door Kevin Krikhaar

Redacteur

20-07-2026 • 09:12

32

Submitter: topper007

Reacties (32)

Sorteer op:

Weergave:

Ik kan wat extra context geven, aangezien het bedrijf waar ik werk in het SecurityWeek-artikel wordt genoemd.

Dit is geen los beveiligingslek, maar een exploitketen die twee kwetsbaarheden combineert (CVE-2026-63030, aanwezig in WordPress 6.9 t/m 7.0.1). Een unauthenticated SQL-injectie in WP_Query (via de author_exclude/author__not_in-parameter) wordt gecombineerd met een fout in het REST API batch-endpoint (/batch/v1). Door een speciaal gevormd batchverzoek raakt de interne afhandeling van requests uit sync, waardoor een request wel volgens het ene endpoint wordt gevalideerd, maar uiteindelijk door een ander (publiek) endpoint wordt uitgevoerd.

Een belangrijk detail dat in veel berichtgeving ontbreekt, is dat de REST-permission checks zelf niet worden omzeild. Als dat wel zo was, zou dit een directe one-shot RCE zijn geweest.

Een andere belangrijke nuance is dat de SQL-injectie zelf read-only is. De injectie bevindt zich in een SELECT-context en WordPress staat geen stacked queries toe, waardoor een aanvaller niet rechtstreeks INSERT- of UPDATE-queries kan uitvoeren. In plaats daarvan gebruikt de publieke "wp2shell"-PoC een UNION SELECT om vervalste database-rijen in het queryresultaat te injecteren. Vervolgens verwerkt WordPress die gegevens zelf via bestaande functionaliteit (zoals de oEmbed-cache en een customize_changeset), waardoor uiteindelijk een administratoraccount wordt aangemaakt. De schrijfacties worden dus door WordPress zelf uitgevoerd; de SQL-injectie manipuleert alleen de data die WordPress denkt uit de database te lezen. Nadat een administratoraccount is verkregen, wordt een plugin met webshell geïnstalleerd om code op de server uit te voeren.

De PoC is inmiddels openbaar beschikbaar en de eerste exploitatiepogingen worden al waargenomen. Daarom is het verstandig om zo snel mogelijk te updaten naar WordPress 7.0.2 (of de beveiligingsupdates voor de 6.8- en 6.9-reeksen).

[Reactie gewijzigd door Stroopwafels op 20 juli 2026 10:42]

De bijvangst op webservers zelfs zonder WordPress van deze categorie bagger levert steevast enorm veel traffic en logs op, door geautomatiseerde scans die nonstop staan te snorren. Enerzijds logisch en "hoort het er bij" anderzijds denk ik wel eens dat het jammer is dat men hier niet voor verantwoordelijk kan worden gehouden tot op zekere hoogte.
"iemand moet verantwoordelijk gehouden voor mensen die dirbuster [ofzo] draaien"? huh? als je je echt zo ergert aan wat log entries dan zet je toch fail2ban er op?
Dus als ik 20x per dag alle deuren langs ga om te kijken welke op slot zijn dan moeten mensen die er wonen maar niet klagen, want ze kunnen ook een hek voor de deur plaatsen?

Tuurlijk kan je de logs an sich blokkeren maar dat lost het probleem niet op dat er mensen zijn die dat eindeloos blijven proberen, is het niet bij jouw is het bij een ander. Gigantische verspilling van resources, sites hebben rustig 3 tot 4x zo verkeer dan daadwerkelijke bezoekersverkeer (ook crawlers/bots/ai spelen daar een grote rol daarin).

En ja ik gebruik fail2ban, maar dan nog hebben ze x aantal pogingen voordat ze gebanned worden, en je moet enorm voorzichtig zijn voor false positives, want legitieme bezoekers wil je natuurlijk nooit blokkeren. Daarnaast moet je steeds weer nieuwe dingen blokkeren en bijwerken/bijhouden. Kost ook gewoon tijd en dus geld.

[Reactie gewijzigd door watercoolertje op 20 juli 2026 09:37]

fail2ban bant op basis van IP-adressen als ik het goed begrijp.

Hoe nuttig en effectief is dat nog in een wereld met dynamische IP-adressen?
Je bant een IP-adres, de dader krijgt een nieuw IP-adres, en een onschuldig iemand kan je website niet bezoeken omdat die dat IP-adres gekregen heeft.
Ik geo-block alles wat niet uit de meest Westerse landen komt, scheelt al zoveel.
Wat heeft een West Taiwanees te zoeken op mijn website? Helemaal niets toch, die komt niet eens voorbij hun grote firewall.
En ik heb geen problemen met een Zuid Koreaan, maar die kan ook geen NL lezen dus jammer dan.

Is dat misschien niet netjes? Vast.
Blokkeer je dan misschien een half PPB die wel legit waren uit die landen? Vast.
Zie het maar als schijnveiligheid. Ook denk ik niet dat ze voor simpele scans hun "achterdehand westerse IPs" gebruiken. Laatst probeerde Kim Jong Un ook nog even mijn site te bezoeken.... Bijzonder.
Als ik voor werk weer in China zit en je site wil bezoeken gebruik ik wel een VPN die via thuis loopt.
Maar goed punt, inderdaad best een praktische manier van aanvliegen.
Ik geo-block ook een aanzienlijk deel van de wereld, zelfs op een internationaal georiënteerde site. De continenten / landen die ik blokkeer zijn toch landen waar we niet heen kunnen / willen (vanwege de extra papierwinkel) versturen. En inderdaad - kwaadwillenden kunnen altijd om die blokkades heen maar dat werpt wel weer een (kleine) extra drempel op voor ze.

Hiernaast heb ik in mijn .htaccess ook nog een "noodknop" zitten. Indien er ellende aan de gang is en ik kan nog wel via SFTP erbij dan kan ik met 1 getal te wijzigen de toegang beperken tot NL / BE / DE / GB voor de gebruikers en alles wat een inlog vereist tot alleen mijn eigen IP. Gelukkig nog nooit gebruik van hoeven maken maar het is wel fijn om het alvast in de htaccess te hebben staan - voor het geval dat.
Ik doe het ook,mijn nederlandstalige website blokkeert automatisch alles buiten west europa en de vs.
Die bots zitten vaak niet op zgn "eyeball"-IPs maar op IP-space van louche/gehackte aanbieders. Je kan een KPN/DTAG/Vodafone/watdanook-klant die in een botnet zit prima onderscheiden van een VM bij Wij Knijpen Een Oogje Toe Hosting BV met hoofdkantoor in Sint-Petersburg ofzo, en je kan daar naar handelen

edit: bovendien komt 99.9% van het gedonder over IPv4 binnen. Met schaarste enzovoorts wordt het wel moeilijker om als "bad actor" lukraak van adres te wijzigen

[Reactie gewijzigd door SampleUser op 20 juli 2026 12:51]

Er zijn meerdere "VPN diensten" die toegang via "residential proxies" verkopen. Soms botnets, soms netwerken van mensen die vrijwillig een proxy app installeren om wat bij te verdienen. Het huren van toegang via Nederlandse residential proxies is niet super duur, en beslist niet iets wat alleen staatshackers zich kunnen veroorloven.

Zie bijvoorbeeld https://krebsonsecurity.com/tag/residential-proxy/
Ken ik ja. Meeste Nederlandse ISPs zijn snel genoeg met blokkeren van klanten die dit soort dingen in hun netwerk hebben.
Ik draai geen wordpress, geen joomla, geen PHP etc. Als een IP meer dan 5x in een dag iets wat daarop lijkt probeert te accessen gaat ie de blocklist in.
Als het een ISP is waarvan ik weet dat ze goed abusemeldingen afhandelen (dus ook niet geoutsourced aan een of ander AI bedrijf) dan krijg ik een conceptmelding in mijn mailbox die ik direct doorzet.
Zolang er "failed states" zijn die dit soort gedrag toelaten/tolereren of tenminste een oog dichtdoen hiervoor zal deze ruis bestaan.
Ik heb 't specifiek over de oorzaak, niet hoe je gevolgen al dan niet deels kunt mitigeren. Het is een gigantische post aan resources die men veroorzaakt.
edit:
Overigens komt WordPress mij sowieso enorm de keel uit als het gaat om kwetsbaarheden in de core of in/door zwakke plugins, die veel schade veroorzaken.

[Reactie gewijzigd door Klauwhamer op 20 juli 2026 09:34]

Tja, zolang er financieel gewin uit te halen valt zullen mensen het proberen. Valt weinig aan te doen als je zaakje verder op orde is
Ik vind het nog meevallen deze keer. Heb het wel eens erger gezien. Zal wel komen omdat het vakantie is en omdat je precies 1 url is die je uit kan buiten. Met de log4j bug bijvoorbeeld moest je veel meer urls proberen en toen zagen we na 1 dag al ruim een miljoen aanvalspogingen.

Op Tweakers zag ik de eerste scans op 17 juli langs komen en totaal zijn er sindsdien 404 requests gedaan op /wp-json/batch/v1 (en die kregen allemaal een 403)
Wat wij vangen op onze servers aan requests is natuurlijk nog niet eens een afrondingsfoutje op het totaal aan traffic wereldwijd door bots die hier naar zochten of aan het zoeken zijn.
Klopt, maar dan nog valt het relatief mee. Deze exploit kun je al vergeten als je geen reactie op /wp-json/batch/v1 krijgt. Bij andere exploits moet je alle url's van een website proberen.
Dus je wilt de ontwikkelaar van dit stukje code, die dit overigens hoogstwaarschijnlijk vrijwillig en onbezoldigd gedaan heeft, aanklagen voor nalatigheid of iets dergelijks?

Als dat mogelijk gaat zijn gaat níemand meer bijdragen aan open source en dan ligt letterlijk de wereldeconomie plat.
Wat ik zou willen is dat men security-issues serieuzer neemt, zodat men niet meteen denkt bij WordPress aan "exploits to be found" -- and rightfully so. En ja, ik begrijp heel goed dat een deel onvermijdelijk is. Maar als het ergens altijd wel ruk is op één of andere manier, dan is het wel bij WordPress (core of plugins). Als je mijn post leest, mag je dat er prima uit opmaken in plaats van wat je mij in de mond legt.
Tjah.

Zitten ook mensen tussen die gewoon op bugbounties aan het jagen zijn en dus in principe goede bedoelingen hebben.
Ik zag gisteren al bergen mails binnenkomen dat mijn installaties geüpdate waren naar 7.0.2.

Die updates heb ik normaal op handmatig staan bij de grootste websites, maar in dit geval leken ze geforceerd te worden?
Klopt, er is een forced updated voor de zwaarste variant bugs. Gek genoeg kreeg ik hem niet automatisch op een 'network' install van WP, waar ik wel zag dat hij klaar stond, maar ik moest er doorheen klikken.

Gek dat ze geen mailing list hebben van allen geregistreerde admins.
Heb je ook security updates op handmatig staan? Lijkt me niet verstandig, zeker als je 'bergen' sites beheert.

Ik heb overal define( 'WP_AUTO_UPDATE_CORE', 'minor'); in wp-config.php
Nee, dat heb ik blijkbaar dus niet :)
Wordpress is lek by-design. Geen ORM, query's uit niet-authenticated bron accepteren, geen goede escaping van user-input. Man, dit is 15 jaar geleden al opgelost voor elk serieus pakket.
- knip, moest reactie zijn, excuus

[Reactie gewijzigd door HyperioN op 20 juli 2026 09:35]

Dankzij dit nieuws raakte ik in de Wordpress-broncode en de kwaliteit is volstrekt kansloos. Zie: https://github.com/WordPress/WordPress/commit/3a640e1c5e39aa60d98bd5a048b603402e70209c waar men met sprintf een query bouwt. Ongekend.
Het lijkt erop dat jij enkel triggert op het woordje `sprintf` zonder de context eromheen.

Hoe zou jij die lap code willen schrijven om tot dezelfde oplossing te komen?
Alle user input zou verwerkt moeten worden via Prepared Statements, in dat geval is het onmogelijk om SQL-injectie te doen.

In dit concrete voorbeeld wordt een ' NOT IN' gebruikt waarbij er wat bijkomende uitdagingen bijkomen, maar ook dan is het nog steeds mogelijk om een prepared statement te gebruiken (hoewel het wel wat lastiger wordt). [edit]De nu gebruikte oplossing om de user input eerst te casten naar integers is natuurlijk in dit concrete geval voldoende en zoals ik al aangaf is een [NOT] IN statement best wel bewerkelijk/lastig om te realiseren in een Prepared Statement...[/edit]

Natuurlijk kun je ook zelf aan validatie doen (hetgeen WordPress ook doet - anders zouden er veel meer issues zijn), maar zo veel mogelijk aan reeds opgebouwde functionaliteit van het framework uitbesteden is vaak een betere optie.

Nu is WordPress al best oud en had PHP in het verleden niet dezelfde goede bescherming als tegenwordig, dat laat onverlet dat het een goed idee zou zijn dat men bij WordPress eens zou gaan werken aan het vervangen van legacy oplossingen...

[Reactie gewijzigd door Little Penguin op 20 juli 2026 15:13]

Jij weet dit denk ik wel (little penguin), maar voor mensen die denken dat het ingewikkeld is dit probleem op te lossen, een voorbeeld. Je kunt van alles doen ook in oudere versies, iets als dit, voor nieuwere versies zijn er waarschijnlijk al weer betere oplossingen:


$arr = ['Amsterdam','Breda','Maastricht'];
$in = str_repeat('?,', count($arr) - 1) . '?';
$sql = "SELECT id, name FROM accounts WHERE city IN ($in)";
$stmt = $mysqli->prepare($sql);
$types = str_repeat('s', count($arr));
$stmt->bind_param($types, ...$arr);
$stmt->execute();


bind_param is er vanaf php 5 als je mysqli gebruikt, voor postgresql kun je overstappen naar PDO, dat is ook uit ongeveer dezelfde tijd volgens mij. PDO heeft ook bind_param en bind_value, er zit wat verschil tussen hoe bind_param werkt op mysqli met PDO (dat ook het mysql/mariadb protocol aankan), als je iets nieuws doet even zelf uitzoeken aub, ik gebruik te weinig php tegenwoordig.
Volgens WordPresses minimum requirements kan dit pas sinds begin dit jaar. Het komt vast wel, maar het lijkt me geen verrassing dat dit nog niet gebruikt word.

Om te kunnen reageren moet je ingelogd zijn