Met het CMS WordPress kun je ook zonder specialistische kennis snel een website opzetten. We laten zien hoe aanvallers de standaard niet afgeschermde REST-API kunnen misbruiken als gegevenslek en hoe je die beveiligt.
WordPress-gegevens onbedoeld openbaar via de JSON-API
Met WordPress is het makkelijk om een eigen blog of website op te zetten. Bij vrijwel elke hostingprovider kun je kant-en-klare installaties van het CMS krijgen. Dat is ideaal om informatie te publiceren.
Sommige gegevens alleen toegankelijk maken voor bepaalde gebruikers is daarentegen niet zo eenvoudig. Want wat veel beheerders niet weten: WordPress beschikt over een krachtige JSON-API die standaard behoorlijk veel informatie prijsgeeft. Daarmee kunnen deels gevoelige gegevens worden opgehaald zonder dat je je eerst hoeft aan te melden, en zonder dat de frontend daar iets van merkt.
Dankzij de JSON-API is WordPress bijzonder uitbreidbaar en flexibel. Het maakt de ontwikkeling van uitbreidingen mogelijk op basis van een stabiele, duidelijk gedefinieerde interface, die bovendien stateless is – dus niet afhankelijk van wat andere gebruikers op dat moment op de website doen.
Zo zijn er smartphone-apps en verschillende editors waarmee je inhoud kunt maken en beheren. Naast de Classic Editor zijn er de huidige standaardeditor Gutenberg, Thrive Architect, Elementor en Divi, om maar enkele bekende te noemen. Ook veel plug-ins, zoals contactformulieren, gebruiken de JSON-API als interface met WordPress.
Voor een reisblog is het misschien geen probleem dat alle inhoud standaard voor iedereen toegankelijk is, maar bij een zakelijke website ligt dat anders. Daar is meestal een medewerkers- of zelfs een bestuurdersgedeelte, dat nu eenmaal niet voor iedereen zichtbaar mag zijn.
Want zelfs als het bekijken van die pagina’s via het standaardthema alleen mogelijk zou moeten zijn voor ingelogde gebruikers, kan iedereen via de JSON-API er zonder inloggen bij. Een plug-in die de toegang tot de JSON-API beperkt, biedt hier uitkomst.
Open voor iedereen
Of een website WordPress gebruikt, kun je makkelijk achterhalen door op een willekeurige pagina van de website te kijken. Kijk gewoon even in de HTML-broncode van de pagina. Als je daar zoekt op wp- en verwijzingen vindt naar wp-content, wp-json of wp-admin, dan is WordPress het CMS op de achtergrond.
Je kunt ook de URL van een willekeurige afbeelding op de website controleren – bij WordPress bevat het pad meestal de directory wp-content.
Waar de JSON-API zich bevindt, vind je ook in de broncode van een pagina. Zoek naar api.w.org, vlak daarachter staat het pad naar de API. Meestal is dat /wp-json/, maar bij sommige hosts ook /index.php/wp-json/. Als je die link kunt openen, heb je te maken met een onbeveiligde JSON-API.
Met de zoekmachine Shodan (shodan.io) kunnen aanvallers bijvoorbeeld /wp-json invoeren als onderdeel van de zoekopdracht en dan direct links naar openstaande WordPress-installaties krijgen.

Om in de backend van een WordPress-site rond te kijken, raden we Firefox aan als browser. Daar wordt de informatie gestructureerd weergegeven in een boomstructuur met meerdere niveaus, die je makkelijk kunt uit- en weer inklappen.
Alleen al de startpagina van de JSON-API geeft een aanvaller belangrijke informatie. De tijdzone die onder gmt_offset is ingesteld, kan bijvoorbeeld een aanwijzing zijn voor de locatie van de server. Soms komen de internetadressen die onder home en url staan vermeld ook niet overeen met het adres dat je hebt opgeroepen. Dat kan wijzen op eerder gebruikte domeinen en is vaak een aanwijzing voor frauduleuze sites.

Aanknopingspunten
De lijst met links op de startpagina bevat naast de plug-ins ook links naar de gebruikersdatabase en naar de inhoud. De lijst met gebruikers vind je onder /wp-json/wp/v2/users. Ook die pagina is standaard voor iedereen toegankelijk.
Aanvallers zijn niet alleen geïnteresseerd in de gebruikersnamen die daar staan, maar ook in de namen van de personen. Zo kun je makkelijk achterhalen wie WordPress beheert – voor het inloggen heb je dan alleen nog het wachtwoord nodig.
Om bijvoorbeeld via phishing aan het wachtwoord te komen, is de zogeheten slug soms ook interessant voor aanvallers. Dat is een soort zoekmachine-geoptimaliseerde korte beschrijving die WordPress automatisch toekent. De slug bestaat alleen uit letters en cijfers, maar soms kun je er toch het e-mailadres uit afleiden en dat misbruiken voor een valse e-mail, bijvoorbeeld van een andere gebruiker.

Inhoud verkennen
Via de paden /wp-json/wp/v2/pages en /wp-json/wp/v2/posts heb je toegang tot de inhoud van een WordPress-site. Standaard wordt er niet gecontroleerd of je bent ingelogd of niet – waardoor je bijvoorbeeld op pagina’s met een ledengedeelte ook toegang hebt tot de inhoud die eigenlijk alleen voor bepaalde gebruikers bedoeld is.
Bijzonder interessant zijn de rendered-velden, daar vind je de ruwe inhoud in HTML-notatie – maar dan zonder thema en zonder andere visuele opmaak. Om inhoud automatisch te doorzoeken, bijvoorbeeld op trefwoorden, is dat een goede gegevensbron.
Een ware schatkamer is het pad /wp-json/wp/v2/media. Daar staan alle afbeeldingen, video’s, PDF-documenten en andere bijlagen en uploads die via WordPress zijn geüpload. Standaard worden alleen de laatste tien uploads weergegeven, maar met de GET-parameter per_page kun je de lijst uitbreiden tot maximaal 100 items. Zijn er nog meer, dan kun je met de parameter page een bepaalde pagina opvragen. Hoeveel pagina’s of vermeldingen er zijn, vertelt WordPress je in de header van het antwoord.
Afhankelijk van het geïnstalleerde thema, de plug-ins en de instellingen maakt WordPress automatisch lagere resoluties van de geüploade afbeeldingen om die in de pagina’s of als voorbeeld te kunnen gebruiken. Niet alleen de URL’s van de daadwerkelijk gebruikte afbeeldingen vind je onder media_details en sizes, maar onder source_url ook de URL van de afbeelding in originele resolutie – waarnaar op de gewone WordPress-pagina’s meestal niet gelinkt wordt.
Afgeschermd
De meest ingrijpende manier om onbevoegde toegang tot de JSON-API te voorkomen, is door het pad /wp-json achter een wachtwoordvraag van de webserver te verbergen. Dat is echter niet aan te raden, want dan werken sommige plug-ins niet meer, zoals contactformulieren, die regelmatig gebruikmaken van de JSON-API.
Het door ons aanbevolen alternatief is de WordPress-plug-in Disable WP REST API. Die sluit gebruikers die niet bij WordPress zijn ingelogd uit van de JSON-API, maar heeft geen invloed op andere plug-ins.
Het installeren is eenvoudig. Log als beheerder in bij WordPress en klik in het navigatiemenu aan de linkerkant op Plugins. Linksboven vind je de knop Plugin toevoegen, waarmee je naar het overzicht van beschikbare plug-ins gaat. Als zoekterm raden we disable rest api aan, waarna de plug-in Disable WP REST API als suggestie zou moeten verschijnen.

Met een klik op Nu installeren wordt de plug-in geïnstalleerd. Daarna moet je nog op Activeren klikken om hem te activeren. Vervolgens krijgen niet-aangemelde gebruikers die de JSON-API oproepen alleen nog foutmelding 401 (Unauthorized) te zien. We zijn niet op de hoogte van negatieve gevolgen voor andere plug-ins die gebruikmaken van de JSON-API. De plug-in is daarom aan te raden voor alle WordPress-installaties. Zo voorkom je met weinig moeite heel effectief dat aanvallers de interne gegevens van je WordPress-installatie misbruiken als springplank voor bijvoorbeeld phishing-aanvallen, of informatie stelen die eigenlijk niet voor het grote publiek bedoeld is.
(Mirko Dölle en Marco den Teuling)
Praat mee