96 lines
3.1 KiB
Markdown
96 lines
3.1 KiB
Markdown
|
|
# 审计:文件编辑器修复 + 编码/EOL 深挖(2026-06-02)
|
|||
|
|
|
|||
|
|
## 审计信息
|
|||
|
|
|
|||
|
|
| 项 | 内容 |
|
|||
|
|
|----|------|
|
|||
|
|
| 日期 | 2026-06-02 |
|
|||
|
|
| 审计人 | Cursor Agent |
|
|||
|
|
| 触发 | 文件页编辑卡死 + Windows/Ubuntu CRLF 深挖 |
|
|||
|
|
|
|||
|
|
## 审计范围
|
|||
|
|
|
|||
|
|
| 文件 | 状态 |
|
|||
|
|
|------|------|
|
|||
|
|
| `frontend/src/pages/FilesPage.vue` | ☑ |
|
|||
|
|
| `frontend/src/utils/remotePath.ts` | ☑ |
|
|||
|
|
| `frontend/src/components/FileEditorWorkbench.vue` | ☑ |
|
|||
|
|
| `frontend/src/components/files/FilesList.vue` | ☑ |
|
|||
|
|
| `frontend/src/composables/files/useFilesPage.ts` | ☑ |
|
|||
|
|
| `frontend/src/monaco/preloadMonaco.ts` | ☑ |
|
|||
|
|
| `server/utils/text_io.py` | ☑ |
|
|||
|
|
| `server/api/install.py` | ☑ |
|
|||
|
|
| `server/api/sync_v2.py` | ☑ |
|
|||
|
|
| `scripts/sync_mysql_mcp_env.py` | ☑ |
|
|||
|
|
| `scripts/check_text_eol.py` | ☑ |
|
|||
|
|
| `deploy/check_shell_eol.sh` | ☑ |
|
|||
|
|
| `deploy/pre_deploy_check.sh` | ☑ |
|
|||
|
|
|
|||
|
|
## Step 3 — 规则扫描 H
|
|||
|
|
|
|||
|
|
| H | 扫描结果 |
|
|||
|
|
|---|----------|
|
|||
|
|
| H1 注入 | `remotePath`/`posix_paths` 路径归一;无用户输入进 shell |
|
|||
|
|
| H2 认证 | 业务 API 仍经 JWT;install 仅安装模式 |
|
|||
|
|
| H3 密钥泄露 | `text_io` 不写日志;install 不写明文密码到日志 |
|
|||
|
|
| H4 静默失败 | `FileEditorWorkbench.openFile` try/catch + snackbar |
|
|||
|
|
| H5 Ref 类型 | `storeToRefs` + `coercePathString` 防御 |
|
|||
|
|
| H6 EOL | `write_utf8_lf` 强制 LF;门控扫 Git 索引 |
|
|||
|
|
|
|||
|
|
## Step 4 — Closure
|
|||
|
|
|
|||
|
|
| H | 判定 | 依据 |
|
|||
|
|
|---|------|------|
|
|||
|
|
| H1 | PASS | 路径工具未拼接 shell |
|
|||
|
|
| H2 | PASS | 未改 auth 中间件 |
|
|||
|
|
| H3 | PASS | 无新增 secret 输出 |
|
|||
|
|
| H4 | PASS | 编辑器错误可见 |
|
|||
|
|
| H5 | FIXED | FilesPage Ref 解包 |
|
|||
|
|
| H6 | PASS | `check_text_eol.py` OK + `test_text_io` 5 passed |
|
|||
|
|
|
|||
|
|
## Step 5 — 入口表
|
|||
|
|
|
|||
|
|
| 入口 | 类型 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| FilesPage 编辑按钮 | UI | → `openFile` |
|
|||
|
|
| `POST /api/sync/v2/read-file` | HTTP | `detect_text_eol` |
|
|||
|
|
| `POST /api/install/*` | HTTP | 安装模式写 `.env`/脚本 |
|
|||
|
|
| `scripts/sync_mysql_mcp_env.py` | CLI | 写 `.env` MCP 块 |
|
|||
|
|
|
|||
|
|
## Step 6 — 输入 → Sink
|
|||
|
|
|
|||
|
|
| 流 | Sink | 控制 |
|
|||
|
|
|----|------|------|
|
|||
|
|
| 远程路径字符串 | SSH read/write | JWT + server_id 校验(既有) |
|
|||
|
|
| 安装表单 | 磁盘 `.env` | `write_utf8_lf` |
|
|||
|
|
| Git 跟踪文件 | bash 执行 | `check_shell_eol` / `check_text_eol` |
|
|||
|
|
|
|||
|
|
## Step 7 — 归类
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
FilesPage.vue 38行 2H 0FINDING
|
|||
|
|
remotePath.ts ~80行 1H 0FINDING
|
|||
|
|
FileEditorWorkbench.vue ~400行 2H 0FINDING
|
|||
|
|
text_io.py ~90行 1H 0FINDING
|
|||
|
|
install.py (diff区) ~30行 1H 0FINDING
|
|||
|
|
────────────────────────────────────────────
|
|||
|
|
总计 7H 0FINDING
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Step 8 — DoD
|
|||
|
|
|
|||
|
|
- [x] `pytest tests/test_text_io.py` 通过
|
|||
|
|
- [x] `python scripts/check_text_eol.py` 通过
|
|||
|
|
- [x] `bash deploy/check_shell_eol.sh` 通过(LF 修复后)
|
|||
|
|
- [x] `vite build` 成功 → `index-DBKIQT7H.js`
|
|||
|
|
- [x] 生产 `/health` ok,`/app/` 200
|
|||
|
|
- [x] changelog 已写(编辑器 + 编码深挖)
|
|||
|
|
|
|||
|
|
## FINDING
|
|||
|
|
|
|||
|
|
无(0 FINDING)
|
|||
|
|
|
|||
|
|
## 结论
|
|||
|
|
|
|||
|
|
☑ 审计通过,可部署。生产已上传前端包与 `text_io`/install/sync 相关后端文件并重启 `nexus`。
|