Om te voldoen aan de wettelijke administratieve verplichtingen, maken vrijwel alle WooCommerce-webshops gebruik van plug-ins die automatisch PDF-facturen en pakbonnen genereren zodra een bestelling is afgerond. Deze PDF-generatoren moeten dynamisch sjablonen (templates) inladen om de lay-out van de factuur te bepalen. Als de plug-in de naam of de locatie van dit sjabloon baseert op een parameter die door de gebruiker kan worden gemanipuleerd, ontstaat er een ernstig risico op een Local File Inclusion (LFI) kwetsbaarheid.
Het mechanisme van een PDF-LFI lek
PDF-factuur plug-ins bieden vaak de mogelijkheid om de lay-out van de factuur aan te passen via de URL, bijvoorbeeld om een speciaal sjabloon te tonen voor zakelijke klanten of voor internationale bestellingen: https://uwshop.nl/wp-admin/admin-ajax.php?action=generate_pdf&template=business
De onderliggende PHP-code van de plug-in verwerkt dit verzoek en laadt het bijbehorende PHP-sjabloon in via een include statement:
$template_name = $_GET['template'];
include( WP_PLUGIN_DIR . "/woocommerce-pdf-invoices/templates/" . $template_name . ".php" );
Een aanvaller (bijvoorbeeld een geregistreerde klant die zijn eigen factuur bekijkt) kan de parameter template manipuleren met pad-traversatietekens (../): ?action=generate_pdf&template=../../../../wp-config
Wanneer de PDF-generator dit verzoek verwerkt, zal PHP het wp-config.php bestand inladen binnen de context van de PDF-generator. De PHP-code van de configuratie wordt uitgevoerd, en eventuele variabelen of foutmeldingen kunnen embedded raken in de gegenereerde PDF. Als de aanvaller de PDF vervolgens downloadt, kan hij de database-inloggegevens en geheime salts rechtstreeks uit de tekst van de factuur kopiëren.
Hoe ontwikkelaars PDF-sjablonen veilig inladen
Ontwikkelaars moeten ervoor zorgen dat gebruikers NOOIT directe invloed kunnen uitoefenen op de bestandsnaam of het pad van een in te laden sjabloon.
-
Gebruik een strikte whitelist: Definieer vooraf welke sjablonen bestaan en sta alleen exacte overeenkomsten toe.
-
Saniseer met
basename(): Verwijder alle mappenstructuren en traversatiepogingen uit de invoer.
$allowed_templates = array('default', 'business', 'minimal');
$chosen_template = basename( $_GET['template'] );
if ( in_array( $chosen_template, $allowed_templates ) ) {
include( WP_PLUGIN_DIR . "/woocommerce-pdf-invoices/templates/" . $chosen_template . ".php" );
} else {
include( WP_PLUGIN_DIR . "/woocommerce-pdf-invoices/templates/default.php" );
}
Advies voor site-beheerders
-
Beveilig de uploads-map van facturen: PDF-plug-ins slaan gegenereerde facturen vaak tijdelijk op in een submap van
wp-content/uploads/. Zorg ervoor dat deze specifieke map is beveiligd met een.htaccessbestand dat directe indexering (Options -Indexes) inschakelt en de toegang voor onbevoegden blokkeert.
