
Prova di concetto per XSS memorizzato autenticato in Autoptimize < 3.1.14, che sfrutta una sanificazione insufficiente degli attributi nella generazione di tag di preload delle immagini.
Vulnerabilità: Cross-Site Scripting (XSS) Memorizzato Autenticato (Contributore+)
Versione Affetta: Autoptimize <= 3.1.13
Versione Corretta: Autoptimize 3.1.14
File: classes/autoptimizeImages.php
La vulnerabilità risiede nel metodo create_img_preload_tag() all'interno di classes/autoptimizeImages.php. Questa funzione è responsabile della generazione dei tag <link rel="preload"> per le immagini trovate nel contenuto quando l'ottimizzazione delle immagini o il preloading è abilitato.
Nella versione 3.1.13, la funzione utilizza un approccio basato su "blacklist" (tramite preg_replace) per rimuovere attributi specifici come title, alt, class, id, width e height dal tag `` originale prima di convertirlo in un tag <link>. Tuttavia, non riesce a rimuovere attributi gestori di eventi come onload o onerror.
Un attaccante autenticato (con almeno il ruolo Contributore) può incorporare un tag `` malevolo in un post. Quando il plugin elabora questo post per generare link di preload, il gestore di eventi malevolo viene preservato e iniettato nell'<head> della pagina all'interno di un tag <link>. Poiché <link rel="preload"> supporta l'evento onload, il JavaScript viene eseguito quando la risorsa viene caricata.
// 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 viene spesso attivata per le immagini rilevate nel viewport o esplicitamente precaricate.<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)">
(Utilizzare una risorsa locale garantisce spesso che l'evento load venga attivato rapidamente. Qualsiasi URL di immagine valido funziona.)<link rel="preload" as="image" href="/wp-content/plugins/autoptimize/classes/external/js/lazysizes.min.js" onload="alert(document.cookie)">
Nota: Gli attributi width, height, ecc. potrebbero essere rimossi, ma onload rimane.<link>, precarica la risorsa e attiva l'evento onload, eseguendo la XSS.La patch sostituisce la regex basata su blacklist con wp_kses(), consentendo una whitelist rigorosa degli attributi permessi per il tag <link> generato.
// 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 );