278 lines
9.7 KiB
Markdown
278 lines
9.7 KiB
Markdown
# ephron.ren 2026-05-16 第三轮完整收口版安全审计
|
||
|
||
## 结论摘要
|
||
|
||
本轮在前两轮基础上继续完成:
|
||
|
||
- 路由与攻击面清单化
|
||
- 认证 / 权限 / CSRF 逐路由审计
|
||
- 前端注入与渲染链回溯
|
||
- 上传 / iframe / raw 渲染专项
|
||
- 运行时 / 配置风险复核
|
||
|
||
### 当前总体判断
|
||
|
||
`ephron.ren` **不是“裸奔”状态**,具备以下明确安全基线:
|
||
|
||
- 各服务统一安全响应头在线上已生效
|
||
- admin 页面普遍具备服务端鉴权与权限检查
|
||
- 大部分 admin 写操作具备 CSRF 防护
|
||
- blog 图片上传链具有权限、CSRF、大小限制、Pillow 重编码 WebP
|
||
- auth 登录跳转链带 `validate_redirect()`,本轮**未确认开放重定向成立**
|
||
- canvas `/raw/{slug}` 具备专用 `CSP + SAMEORIGIN`,当前**不作为确认漏洞**
|
||
|
||
但本轮也确认了数个真实安全问题,其中以 `prompt` 与 `home admin` 最值得优先修复。
|
||
|
||
---
|
||
|
||
## 一、确认问题
|
||
|
||
## 1. 高危:`prompt /api/test-connection` 可匿名触发服务端外连(SSRF / 网络探测面)
|
||
|
||
### 风险等级
|
||
高危
|
||
|
||
### 证据
|
||
#### 源码证据
|
||
`prompt/src/routes/api.py`
|
||
- 存在公开 `POST /api/test-connection`
|
||
- 该接口直接接受客户端传入的 `provider/base_url/api_key/model`
|
||
- 服务端随后执行:
|
||
- `POST {payload.base_url}/chat/completions`
|
||
- 并带上 `Authorization: Bearer {payload.api_key}`
|
||
- 未见登录校验、权限校验、CSRF 约束
|
||
|
||
#### 线上验证
|
||
非破坏性 POST 验证:
|
||
- `POST https://prompt.ephron.ren/api/test-connection`
|
||
- 使用 `base_url=http://127.0.0.1:9`
|
||
- 线上返回 `200`,正文为:`{"success":false,"error":"All connection attempts failed"}`
|
||
|
||
这说明:
|
||
- 接口可匿名访问
|
||
- 服务端实际尝试了到指定地址的连接
|
||
- 攻击者可以利用该接口探测不同目标的网络可达性/响应差异
|
||
|
||
### 影响
|
||
- 可被匿名用于对内网/本机/特定外部地址做探测
|
||
- 若未来错误回显更详细,可能进一步暴露内部网络结构或上游服务信息
|
||
- 若某些环境允许访问元数据地址/内部控制面,风险会进一步升级
|
||
|
||
### 修复建议
|
||
1. 该接口至少改为 **管理员鉴权**,不要匿名暴露
|
||
2. 严格限制 `base_url`:
|
||
- 白名单域名/白名单 provider
|
||
- 禁止 `localhost` / `127.0.0.0/8` / RFC1918 内网 / link-local / metadata 地址
|
||
3. 后端不要把原始网络错误细节直接返回给前端
|
||
4. 增加审计日志与更严格限流
|
||
|
||
---
|
||
|
||
## 2. 中危:`prompt` 调试测试链存在潜在 HTML 注入 / XSS
|
||
|
||
### 风险等级
|
||
中危
|
||
|
||
### 证据
|
||
#### 源码链路
|
||
`prompt/static/js/test-prompt.js`
|
||
- `event.type === "error"` 时:
|
||
- `contentDiv.innerHTML = |