
Schwachstelle: Authentifiziertes (Contributor+) gespeichertes Cross-Site Scripting (XSS)
Betroffene Version: Autoptimize <= 3.1.13
Gepatchte Version: Autoptimize 3.1.14
Datei: classes/autoptimizeImages.php
Die Schwachstelle besteht in der Methode create_img_preload_tag() innerhalb von classes/autoptimizeImages.php. Diese Funktion ist dafür verantwortlich, <link rel="preload">-Tags für Bilder zu erzeugen, die im Inhalt gefunden werden, wenn Bildoptimierung oder Preloading aktiviert ist.
In Version 3.1.13 verwendet die Funktion einen „Blacklist“-Ansatz (über preg_replace), um bestimmte Attribute wie title, alt, class, id, width und height aus dem ursprünglichen ``-Tag zu entfernen, bevor es in ein <link>-Tag umgewandelt wird. Sie entfernt jedoch keine Event-Handler-Attribute wie onload oder onerror.
Ein authentifizierter Angreifer (mit mindestens der Rolle Contributor) kann ein schadhaftes ``-Tag in einem Beitrag platzieren. Wenn das Plugin diesen Beitrag verarbeitet, um Preload-Links zu erzeugen, bleibt der schadhafte Event-Handler erhalten und wird in den <head> der Seite innerhalb eines <link>-Tags eingefügt. Da <link rel="preload"> das onload-Ereignis unterstützt, wird das JavaScript ausgeführt, sobald die Ressource geladen wird.
// 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/HEAD/," 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 wird häufig für Bilder ausgelöst, die im Viewport erkannt oder explizit vorgeladen werden.<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/HEAD/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 usw. können entfernt werden, aber onload bleibt erhalten.<link>-Tag, lädt die Ressource vor und löst das onload-Ereignis aus, wodurch das XSS ausgeführt wird.Der Patch ersetzt den Blacklist-Regex durch wp_kses(), wodurch eine strikte Whitelist der zulässigen Attribute für das erzeugte <link>-Tag ermöglicht wird.
// 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 );