【juice-shop】★★★ API-only XSS:绕过前端直接调用 API 实施存储型 XSS
0x01 任务简报
💡 提示 (Hints)1. 需要直接调用服务器端 API,通过 API 尝试不同的 HTTP 动作以暴露不同实体。
2. 一个包含已知数据实体及其在 API 中支持的 HTTP 操作动词的矩阵可为你提供帮助。
3. 粗心的开发人员可能暴露了客户端根本不需要的 API 方法。
0x02 实战:复现漏洞
🔍 第一步:API 枚举
这个挑战需要寻找前端没有暴露的 API 接口,使用 FindSomething 插件收集到以下接口:
|
|

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

虽然题目要求不使用前端,但不能被条件完全框住。
我们使用burp的内置浏览器,访问 http://127.0.0.1:3000/api/Products 将对应的请求加入到重放器里


⚙️ 第三步:探测支持的 HTTP 方法
发送 OPTIONS 请求,获取该接口支持的所有请求方法:
|
|


逐一测试各方法:
- PUT — 报错
Error: Unexpected path: /api/Products,无法使用 - POST — 报错
UnauthorizedError: No Authorization header was found,缺少鉴权
🔑 第四步:获取管理员 Authorization
我们使用之前的Login Admin挑战获取一下 Authorization ,直接用admin防止权限不足(这里使用burp内置浏览器,便于捕获本地包)。

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

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

💉 第五步:构造 XSS Payload
整理关键信息:
XSS 有效负载(来自题目描述):
|
|
接口返回的 JSON 结构:
|
|
关键请求头(上传 JSON 数据时必须添加 Content-Type):
|
|
将 XSS 有效负载注入商品的 description 字段,构造并发送 POST 请求。

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


挑战完成!
吐槽
这个挑战因为一些细节粗心,花费了半天时间,我认为这个挑战是非常考验细节的,3 星有点低啊(雾
最后构建 payload 的时候注意不要少符号,容易搞坏这个 API,发现 GET 访问
/api/Products报错的时候直接重启环境(