Een WordPress-site controleren, opschonen en beveiligen tegen wp2shell (CVE-2026-63030)
In WordPress-versies ouder dan 7.0.3 zit een kwetsbaarheid, bekend als wp2shell (CVE-2026-63030), waarmee iemand zonder in te loggen een site kan overnemen. De fout zit in de batch-endpoint van de REST API: normaal controleert WordPress bij elke handeling of je daar rechten voor hebt, maar op dit punt gaat die controle mis. Een aanvaller kan daar een reeks opdrachten naartoe sturen die worden uitgevoerd alsof hij beheerder is, terwijl hij nooit heeft ingelogd.
Wat er daarna gebeurt is standaardwerk: er wordt een extra beheerdersaccount aangemaakt, een webshell (een PHP-bestand waarmee de aanvaller commando's op de server kan uitvoeren) tussen de uploads gezet, en er wordt op een paar plekken tegelijk zorgvuldig een terugweg ingebouwd. Vanaf dat moment is de site niet alleen kwetsbaar, maar overgenomen: spam vanaf het account, bezoekers die worden doorgestuurd, SEO-spam in de pagina's en toegang tot klant- en ordergegevens.
Dit lek wordt geautomatiseerd afgescand door kwaadwillenden. Onze hostingpartner scant hier ook op en attendeert ons hierop, zodat wij jou kunnen waarschuwen. Een site die kwetsbaar online staat, wordt doorgaans binnen enkele dagen gevonden: dat is waarom snel handelen loont.
Deze handleiding loopt alles langs in de volgorde waarin je het moet aanpakken: eerst controleren of de site kwetsbaar of al besmet is, dan indien nodig opschonen, en pas daarna bijwerken. Je doet vrijwel alles vanuit het WordPress-dashboard en de bestandsbeheerder in cPanel. Terminal-toegang is alleen nodig voor een paar optionele, snellere manieren van werken.
Ga hier uit van één principe: alles wat je niet kunt verklaren, is verdacht totdat je het tegendeel hebt vastgesteld.
Voordat je begint
Werk de site nog niet bij. Zolang een eventuele backdoor er nog in zit, sluit je met een update alleen de ingang waarmee de aanvaller binnenkwam, terwijl hij via zijn eigen weg gewoon terug kan. Bijwerken komt pas nadat je hebt gecontroleerd of de site al besmet is.
Zet de site niet meteen offline. Een site die uit de lucht gaat, zorgt vooral voor onrust en verandert niets aan een eventuele besmetting. Uitzondering: verstuurt de site actief spam, of staan er klantgegevens open, dan is offline halen wel de juiste eerste stap.
Trek er een aaneengesloten blok tijd voor uit, zeker als je signalen van besmetting vindt. Een half opgeschoonde site is lastiger te beoordelen dan een besmette site: de sporen zijn dan weg, maar de backdoor niet.
De bestandsbeheerder openen
Een deel van de controles doe je in de bestanden van de site. Zo kom je daar:
- Log in op cPanel.
- Klik onder Bestanden op Bestandsbeheer.
- Klik rechtsboven op Instellingen en zet Verborgen bestanden weergeven aan. Zonder deze instelling zie je
.htaccessniet staan, en dat is een van de bestanden die je moet controleren. - Ga naar de map van de site. Voor je hoofddomein is dat
public_html. Voor een addon-domein of subdomein is dat de map die je bij het aanmaken hebt opgegeven.
Je bent op de goede plek als je daar wp-config.php , wp-content en wp-admin ziet staan.
Stap 1: controleer je WordPress-versie
In WordPress zelf staat het versienummer onderaan het dashboard, rechtsonder, en op Dashboard > Updates.
Heb je toegang tot SSH of de cPanel Terminal, dan gaat het ook zo, vanuit de map van de installatie:
wp core version
Staat er een versie lager dan 7.0.3, dan is de site kwetsbaar en ga je verder met stap 2.
Stap 2: controleer of de site al besmet is
Dit is de belangrijkste stap. Loop deze drie punten na voordat je iets bijwerkt:
- Ga in WordPress naar Gebruikers, klik boven de lijst op Beheerder om alleen beheerders te zien, en zet de lijst op datum via de kolom Geregistreerd (zie je die kolom niet, klik dan rechtsboven op Scherminstellingen en zet hem aan). Let op accounts met
wpsvc_,wp2_ofw2s_als begin van de naam, op namen als admin1, support of wpadmin die niemand kan verklaren, op willekeurige lettercombinaties, en op e-mailadressen op domeinen die niets met het project te maken hebben. Let vooral op de registratiedatum: een beheerder die op een willekeurige dinsdagnacht is aangemaakt, is er niet door een collega bij gezet. - Ga in de bestandsbeheerder naar
wp-content/uploadsen zoek daar naar.php-bestanden. Die horen daar normaal niet te staan, alleen afbeeldingen, pdf's en dergelijke. (Eén uitzondering: gebruik je WPML, dan zet die plugin legitiem PHP-bestanden in zijn twig-cache.) Doe hetzelfde inwp-content/cacheals die map bestaat. - Kijk of de map
wp-content/mu-pluginsbestaat en of daar iets in staat dat je niet zelf hebt neergezet. In een standaardinstallatie is die map er niet, en bestanden erin worden bij elke pagina-aanroep geladen zonder dat ze in je pluginoverzicht staan of uit te schakelen zijn.
Wil je dit sneller controleren en heb je toegang tot SSH of de cPanel Terminal, dan doe je dat zo vanuit de map van de installatie:
wp user list --role=administrator find wp-content/uploads -name "*.php" ls -la wp-content/mu-plugins
Vind je geen van deze signalen? Ga dan direct door naar Bijwerken.
Vind je één van deze signalen? Werk de site dan nog niet bij en ga verder met De site opschonen.
De site opschonen
Is een site overgenomen, dan is bijwerken niet genoeg: de aanvaller heeft vaak op meerdere plekken tegelijk een terugweg ingebouwd, en zolang er één achterblijft is de site binnen een dag opnieuw besmet. Loop daarom alle onderstaande punten na, in deze volgorde.
-
Andere sites in het account
Een aanvaller die één site in een cPanel-account overneemt, komt in veel gevallen ook bij de andere sites in datzelfde account: ze staan onder dezelfde gebruiker op dezelfde server. Ga naar Domeinen in cPanel en noteer alle domeinen en subdomeinen in dit account. Kijk per stuk of er WordPress op draait, en behandel elke installatie apart en volledig. Let vooral op oude installaties in een submap, bijvoorbeeld onder /oud of /staging — die worden zelden bijgewerkt en het vaakst vergeten.
-
Onbekende beheerders verwijderen
Ga naar Gebruikers in WordPress, verwijder elk account dat je hebt aangemerkt als verdacht (zie stap 2) via verwijderen. WordPress vraagt dan wat er met de berichten van dat account moet gebeuren: kies Alle inhoud toewijzen aan en wijs ze toe aan een bestaand, vertrouwd account. Kies hier niet voor "verwijderen", anders raak je mogelijk echte pagina's kwijt.
Loop daarna ook de rest van de gebruikerslijst na. Het komt voor dat een bestaand abonnee-account stilletjes tot beheerder is gemaakt, wat minder opvalt dan een nieuw account.
-
PHP-bestanden in de uploadsmap
Verwijder elk PHP-bestand dat je in wp-content/uploads (en wp-content/cache ) hebt gevonden, met uitzondering van legitieme WPML-cachebestanden. Krijg je bij het verwijderen een foutmelding over rechten, pas dan niet zelf de rechten aan — stuur ons het volledige pad van het bestand, dan halen wij het weg.
-
mu-plugins, drop-ins en nep-plugins
Verwijder alles in wp-content/mu-plugins dat je niet zelf hebt neergezet.
Kijk ook in wp-content zelf of daar losse PHP-bestanden staan, zoals object-cache.php of advanced-cache.php (zogeheten drop-ins, die WordPress automatisch laadt). Die horen er alleen te staan als een plugin ze heeft neergezet en je die plugin kunt aanwijzen.
Ga in WordPress naar Plugins en loop de hele lijst door, ook de inactieve. Verdacht zijn: plugins met een reeks willekeurige letters en cijfers achter de naam (bijvoorbeeld seo-tools-a3f91c), plugins die niemand heeft geïnstalleerd, en plugins met "WordPress.org Community" als auteur — dat is geen bestaande auteur.
-
wp-config.php en .htaccess
Open wp-config.php via Bewerken in de bestandsbeheerder en lees het bestand helemaal door, tot onderaan. Let op een include of require die naar een ander bestand op de server verwijst, een regel met auto_prepend_file , of code met base64_decode of eval erin — dat laatste staat vaak op één hele lange regel onderaan.
Doe daarna hetzelfde met .htaccess , niet alleen in de hoofdmap maar ook in submappen zoals wp-content en uploads . Een standaard .htaccess van WordPress is kort: één blok tussen # BEGIN WordPress en # END WordPress . Staat er buiten dat blok iets dat je niet kunt verklaren (en heb je geen cache- of redirectplugin die dat erin heeft gezet), dan is dat verdacht.
Weet je niet zeker of een regel erin hoort? Verwijder hem dan niet meteen: sla eerst een kopie van het bestand op en stuur ons de inhoud. Een verkeerd weggehaalde regel kan de site onbereikbaar maken.
-
Kijk naar het tijdstip
Je weet uit de gebruikerscontrole ongeveer wanneer de site is overgenomen. Bestanden die rond dat moment zijn gewijzigd, zijn vaak wat je hierboven hebt gemist.
Ga in de bestandsbeheerder naar de hoofdmap van de site en klik op de kolomkop Laatst gewijzigd om te sorteren, nieuwste boven. Loop de bestanden na die rond die datum zijn gewijzigd zonder dat er op dat moment een update of aanpassing liep. Doe dit ook in wp-content en wp-includes .
Kijk daarnaast in cPanel bij Geplande taken of daar taken staan die je niet herkent — een taak die op vaste tijden een onbekend bestand aanroept, is een manier om de besmetting terug te zetten nadat jij hem hebt opgeruimd.
-
WordPress opnieuw neerzetten en bijwerken
Login op je WordPress installatie
- Ga naar Dashboard > Updates.
- Klik op Nu opnieuw installeren (deze knop staat er ook als je al op de nieuwste versie zit — hij vervangt alleen de WordPress-bestanden zelf en laat thema's, plugins, uploads en database met rust).
- Werk daarna WordPress bij naar 7.0.3 of hoger als dat nog niet is gebeurd.
- Werk al je plugins bij, en daarna je thema's.
Kom je bij een plugin een update tegen die niet doorgaat omdat de plugin niet meer bestaat of niet meer wordt onderhouden: verwijder hem of vervang hem. Een plugin die geen updates meer krijgt, is de volgende ingang.
-
Alle wachtwoorden en sleutels vervangen
De aanvaller heeft toegang gehad tot de bestanden en de database. Ga ervan uit dat elk wachtwoord en elke sleutel op die site bekend is.
Beheerderswachtwoorden. Open in Gebruikers elk beheerdersaccount, klik op Nieuw wachtwoord instellen en sla op. Doe dit voor alle beheerders, niet alleen voor jezelf.
Beveiligingssleutels (de zogenoemde salts in wp-config.php ). Door ze te vervangen worden alle openstaande sessies ongeldig, ook die van de aanvaller.
- Ga naar https://api.wordpress.org/secret-key/1.1/salt/. Je krijgt daar acht regels code, elke keer opnieuw gegenereerd.
- Open
wp-config.phpin de bestandsbeheerder. - Zoek het bestaande blok van acht regels die beginnen met
define('AUTH_KEY'en verder. - Vervang die acht regels door de acht regels van de website hierboven en sla op.
Je wordt daarna uitgelogd uit WordPress. Dat hoort zo.
Databasewachtwoord. Ga in cPanel naar MySQL-databases, zoek de gebruiker die bij deze site hoort en stel een nieuw wachtwoord in. Zet datzelfde wachtwoord daarna in wp-config.php bij DB_PASSWORD . Doe deze twee stappen kort na elkaar: tussen het wijzigen en het aanpassen van wp-config.php is de site niet bereikbaar.
En verder: vergeet het cPanel-wachtwoord zelf niet, eventuele FTP-accounts, en API-sleutels van betaalproviders of koppelingen die in de site staan.
Controleren of het echt schoon is
Loop dit lijstje af voordat je de site vrijgeeft:
- Geen onbekende beheerders meer, en geen bestaand account met een rol die het niet hoort te hebben.
- Geen PHP-bestanden in
uploadsencache. mu-pluginsleeg of verwijderd, en geen onverklaarbare bestanden los inwp-content.wp-config.phpen.htaccessgecontroleerd en schoon.- WordPress opnieuw neergezet, versie 7.0.3 of hoger, plugins en thema's bijgewerkt.
- Beheerderswachtwoorden, beveiligingssleutels en databasewachtwoord vervangen.
Open daarna de site in een privévenster en controleer de homepage, een subpagina en het dashboard. Bekijk ook een pagina via een zoekresultaat in Google, want sommige besmettingen sturen alleen bezoekers door die via een zoekmachine binnenkomen.
Houd de site daarna een week in de gaten. Duikt er opnieuw een bestand of account op, dan is er nog een terugweg blijven staan, en heeft doorzoeken meer zin dan nog een keer hetzelfde opschonen.
Optioneel: de laatste controle via de Terminal
Er is één controle die je niet vanuit WordPress kunt doen: elk bestand van de installatie vergelijken met de officiële versie van wordpress.org. Niet verplicht, maar wel de meeste zekerheid — zeker bij een webshop of een site met klantgegevens.
- Log in op cPanel.
- Klik onder Geavanceerd op Terminal (verschijnt er een waarschuwing, bevestig die).
- Ga naar de map van de site, bijvoorbeeld
cd public_html.
Voer daarna uit:
wp core verify-checksums
Geen meldingen? Dan zijn alle WordPress-bestanden identiek aan de officiële versie. Krijg je wel meldingen over gewijzigde of onbekende bestanden, laat het ons weten met de uitvoer erbij, dan kijken we mee.
Zie je Terminal niet staan in cPanel, dan staat die functie voor je account uit — stuur ons een bericht, dan zetten we hem aan.
Bijwerken
Vond je in stap 2 geen signalen van besmetting? Dan kun je direct bijwerken.
- Maak eerst een back-up, of controleer of er een recente back-up klaarstaat.
- Ga naar Dashboard > Updates en werk WordPress zelf bij. Wacht tot de pagina meldt dat het gelukt is.
- Werk daarna al je plugins bij, en daarna je thema's — in deze volgorde, want plugins verwachten de nieuwe core, niet andersom.
- Ga terug naar Dashboard > Updates en controleer of er nu 7.0.3 of hoger staat.
Loopt de update via het dashboard vast op een time-out, dan lukt het via SSH of de cPanel Terminal vaak wel, omdat die niet gebonden zijn aan de uitvoeringstijd van een webrequest:
wp core update wp core version wp plugin update --all wp theme update --all wp core verify-checksums
Heb je meerdere installaties in één cPanel-account, vergeet dan de addon-domeinen en subdomeinen niet. Deze regel laat zien waar overal een WordPress-installatie staat:
find ~ -name "wp-config.php" -not -path "*/wp-content/*"
Na het bijwerken controleer je:
- Draait de site normaal? Open de homepage, een subpagina en het dashboard.
- Staat er 7.0.3 of hoger?
- Zijn er geen beheerdersaccounts bijgekomen die je niet kent?
- Staan er geen PHP-bestanden in
wp-content/uploads?
Voorkomen dat dit opnieuw gebeurt
Dit specifieke lek is dan opgelost, maar de volgende is een kwestie van tijd. Een paar dingen structureel regelen loont:
- Automatische updates. Zet die aan voor de core en voor plugins waarvan je weet dat ze stabiel updaten (regel je per plugin op de pagina Plugins, kolom Automatische updates). Voor sites met maatwerk is een vaste maandelijkse onderhoudsronde vaak een beter idee dan alles blind laten bijwerken.
- Bestandseditor uitzetten. Voeg dit toe aan
wp-config.php, boven de regel die begint met/* That's all:
define( 'DISALLOW_FILE_EDIT', true );
- Onnodige beheerdersaccounts opruimen, bijvoorbeeld van een bureau of freelancer dat niet meer bij het project betrokken is. Elk account dat blijft staan is een ingang die niemand in de gaten houdt.
- XML-RPC uitzetten als je dat niet gebruikt (bijvoorbeeld voor de WordPress-app of Jetpack) — het is een veelgebruikt doelwit voor geautomatiseerde inlogpogingen.
Wat wij al doen
Onze hostingomgeving blokkeert op platformniveau de aanvalspaden richting deze kwetsbaarheid die nu bekend zijn, inclusief varianten die scanners gebruiken om blokkades te omzeilen, en er wordt gemonitord op bestanden en gedrag die bij deze aanval horen. Dit geeft tijdelijke, aanvullende bescherming, maar dekt geen nieuwe varianten en vervangt de update niet. Zelf bijwerken (en indien nodig opschonen) is het enige dat het lek écht sluit.
Kom je er niet uit?
Opschonen kost tijd en moet in één keer volledig gebeuren. Twijfel je of een site kwetsbaar of al besmet is, loopt een update ergens op vast, of wil je dit soort meldingen, controles en updates voortaan liever niet zelf doen?
Neem contact met ons op. Vermoed je dat een site al is overgenomen, stuur dan het domein door, dan denken we mee over de te volgen stappen. Wil je dit hele proces (updates, controles en opschonen bij een besmetting) structureel bij ons onderbrengen, dan kun je overstappen naar ons onderhoud & beheerpakket, dan nemen wij dit voortaan voor je uit handen.