Local File Inclusion (LFI) is een kwetsbaarheid waarbij een aanvaller de webapplicatie kan dwingen om willekeurige bestanden in te laden die lokaal op de server aanwezig zijn. Binnen het WordPress-ecosysteem ontstaan LFI-lekken regelmatig op plekken waar dynamische taalwisselingen of lokalisatiefuncties worden geïmplementeerd. Als een WooCommerce-thema of plug-in de taalbestanden (.mo of .po bestanden) inlaadt op basis van een ongecontroleerde parameter van de gebruiker, kan dit leiden tot informatie-lekkage of zelfs het uitvoeren van kwaadaardige code.
Hoe een LFI-lek in vertalingen ontstaat
Veel geavanceerde WooCommerce-thema's bieden de mogelijkheid om de taal van de interface dynamisch aan te passen via een URL-parameter, bijvoorbeeld voor internationale klanten: https://uwshop.nl/?lang=de
De onderliggende PHP-code van het thema gebruikt deze parameter vervolgens om het juiste vertaalbestand in te laden via een include of require statement:
$language = $_GET['lang'];
include(get_template_directory() . "/languages/" . $language . ".php");
Als een aanvaller deze parameter manipuleert met pad-traversatietekens (../), kan hij de restrictie van de map /languages/ omzeilen: https://uwshop.nl/?lang=../../../../wp-config
De server zal proberen om het bestand wp-config.php in te laden. Hoewel PHP-bestanden normaal gesproken worden uitgevoerd en de code niet direct op het scherm tonen, kan een LFI-lek in combinatie met andere serverfouten of specifieke PHP-functies ertoe leiden dat de gevoelige database-wachtwoorden alsnog worden blootgelegd.
Het grotere gevaar: Remote Code Execution via LFI
LFI kan escaleren naar Remote Code Execution (RCE) via een techniek genaamd Log Poisoning. Een aanvaller stuurt eerst een vervalst HTTP-verzoek naar de server met kwaadaardige PHP-code in de User-Agent header. Deze code wordt vervolgens opgeslagen in de toegangslogboeken van de server (access.log).
Daarna misbruikt de aanvaller het LFI-lek om het access.log bestand in te laden. PHP zal het logbestand verwerken en de geïnjecteerde PHP-code uitvoeren, waardoor de hacker direct een achterdeur op de server kan installeren.
Hoe ontwikkelaars vertaalfuncties beveiligen
Ontwikkelaars moeten de invoer van gebruikers rigoureus opschonen en het liefst gebruikmaken van ingebouwde WordPress-functies voor lokalisatie, zoals load_theme_textdomain(), in plaats van handmatige include constructies.
Als er toch handmatig bestanden moeten worden geladen, gebruik dan een strikte whitelist of sanering met basename():
$language = $_GET['lang'];
// Verwijder alle pad-informatie (../) en sta alleen alfanumerieke tekens toe
$language = sanitize_key(basename($language));
$allowed_languages = array('nl', 'en', 'de', 'fr');
if (in_array($language, $allowed_languages)) {
include(get_template_directory() . "/languages/" . $language . ".php");
} else {
// Val terug op de standaardtala
include(get_template_directory() . "/languages/nl.php");
}
Advies voor site-eigenaren
-
Kies voor vertrouwde vertaalplug-ins: Gebruik voor meertalige WooCommerce-winkels gevestigde en professioneel ondersteunde plug-ins zoals WPML, Polylang of Loco Translate. Deze plug-ins ondergaan regelmatig beveiligingsaudits.
-
PHP open_basedir: Zorg ervoor dat uw hostingomgeving de
open_basedirrestrictie heeft ingeschakeld, zodat PHP-scripts nooit bestanden buiten uw eigen websitemap kunnen openen.
