# 【juice-shop】★ Missing Encoding：消失的图片

# 【juice-shop】★ Missing Encoding：消失的图片

## 0x01 任务简报

<blockquote style="border-left: 5px solid #6f42c1; background-color: #f5f3ff; padding: 20px; margin: 1.5rem 0; color: #5521b5; line-height: 1.8; border-radius: 0 5px 5px 0;">
<div style="font-weight: bold; font-size: 1.1rem; margin-bottom: 10px; display: flex; align-items: center;">
<span style="margin-right: 8px;">💡</span> 核心线索 (Hints)
</div>


1. 在<strong>照片墙</strong>中找一张无法正常加载的图片。<br>
2. 你只需（字面意义上）<strong>检查问题</strong>就能看出症结所在。<br>
3. 试着点击该条目的<strong>推文按钮</strong>，观察一下效果。
   </blockquote>

<blockquote style="border-left: 5px solid #0366d6; background-color: #f1f8ff; padding: 20px; margin: 1.5rem 0; color: #0550ae; line-height: 1.8; border-radius: 0 5px 5px 0;">
<div style="font-weight: bold; font-size: 1.1rem; margin-bottom: 10px; display: flex; align-items: center;">
<span style="margin-right: 8px;">🎓</span> 实战动作 (Action)
</div>
• <strong>目标</strong>：照片墙里那张加载失败的图片。<br>
• <strong>工具</strong>：浏览器开发者工具（F12）。<br>
• <strong>操作</strong>：找到图片的真实 URL，手动修复特殊字符后直接访问。
</blockquote>


-----

## 0x02 实战：复现漏洞

**1. 发现异常**

打开照片墙，发现一个图片位置空白，没有加载出来：

![照片墙中有一张图片加载失败](../../../../../../public/p/juice-shop-missing-encoding消失的图片/assets/Pastedimage20260330145813.png)

**2. 检查病灶**

打开开发者工具，查看该图片的 `src` 地址，问题一目了然——URL 没有做任何转义：

![开发者工具显示图片 URL 包含未转义的特殊字符](../../../../../../public/p/juice-shop-missing-encoding消失的图片/assets/Pastedimage20260330145651.png)

**3. 分析原因**

原始图片链接是：

```
http://127.0.0.1:3000/assets/public/images/uploads/ᓚᘏᗢ-#zatschi-#whoneedsfourlegs-1572600969477.jpg
```

> **关键知识点**：`#` 在 URL 中是**锚点符号（fragment identifier）**，浏览器遇到第一个 `#` 就会截断，后面的内容**根本不会发送给服务器**。

所以服务器实际收到的请求只有：

```
http://127.0.0.1:3000/assets/public/images/uploads/ᓚᘏᗢ-
```

文件名后半段全部丢失，自然找不到图片。

**4. 修复并验证**

将 `#` 替换为其 URL 编码形式 `%23`，手动访问修复后的地址：

```
http://127.0.0.1:3000/assets/public/images/uploads/ᓚᘏᗢ-%23zatschi-%23whoneedsfourlegs-1572600969477.jpg
```

图片成功加载，挑战完成 ✓

![修复编码后图片成功加载](../../../../../../public/p/juice-shop-missing-encoding消失的图片/assets/Pastedimage20260330153030.png)

-----

## 0x03 知识延伸

**为什么叫"Missing Encoding"？**

这类漏洞的根源是：程序在把用户数据（文件名、输入内容等）拼接进 URL 时，**忘记对特殊字符进行编码**。常见的危险字符包括：

|  字符  |   URL 编码   | 含义                 |
| :----: | :----------: | :------------------- |
|  `#`   |    `%23`     | 锚点，浏览器截断标志 |
|  `?`   |    `%3F`     | 查询参数开始         |
|  `&`   |    `%26`     | 参数分隔符           |
| `空格` | `%20` 或 `+` | 空格                 |

**在代码里怎么正确处理？**

```javascript
// 只编码文件名部分，不要对整个 URL 编码
const filename = 'ᓚᘏᗢ-#zatschi-#whoneedsfourlegs-1572600969477.jpg'
const safeUrl = '/assets/public/images/uploads/' + encodeURIComponent(filename)
// 结果：/assets/public/images/uploads/%E1%93%9A%E1%98%8F%E1%97%A2-%23zatschi-%23whoneedsfourlegs-1572600969477.jpg
```

-----

## 0x04 参考资料

- 📖 [MDN：encodeURIComponent()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent)
- 📖 [OWASP：URL 编码防御手册](https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html)
