fix: block sensitive symlink targets

This commit is contained in:
Yoilun
2026-05-25 16:28:57 +08:00
parent dc8b06f961
commit 2f28b4880e
4 changed files with 31 additions and 0 deletions

View File

@@ -101,6 +101,9 @@ func rejectSymlinkEscape(home string, candidate string) error {
if !isInside(evaluatedHome, currentEvaluated) {
return ErrOutsideCodexHome
}
if IsForbidden(currentEvaluated, evaluatedHome) {
return ErrForbiddenPath
}
}
return nil
}

View File

@@ -1,6 +1,7 @@
package codexhome
import (
"errors"
"os"
"path/filepath"
"testing"
@@ -91,3 +92,22 @@ func TestResolveAgentTOMLRejectsUnsafeNames(t *testing.T) {
})
}
}
func TestResolveAgentTOMLRejectsSymlinkToAuthJSON(t *testing.T) {
home := filepath.Join(t.TempDir(), ".codex")
agentsDir := filepath.Join(home, "agents")
if err := os.MkdirAll(agentsDir, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(home, "auth.json"), []byte("{}"), 0o600); err != nil {
t.Fatal(err)
}
if err := os.Symlink("../auth.json", filepath.Join(agentsDir, "demo.toml")); err != nil {
t.Fatal(err)
}
_, err := ResolveAgentTOML(home, "demo.toml")
if !errors.Is(err, ErrForbiddenPath) {
t.Fatalf("expected ErrForbiddenPath, got %v", err)
}
}

View File

@@ -8,6 +8,7 @@
| 2026-05-25 | 0 | review loop | 质量审查发现 docs/project.md 架构语气和 task_plan.md Phase 0 状态问题 | 已修复:改为目标架构语气,并将 Phase 0 标记为 complete |
| 2026-05-25 | 1 | coding agent | 创建 Go 后端骨架和 Codex home 路径边界 | 已完成;未读取真实 `.codex` 数据文件 |
| 2026-05-25 | 1 | review loop | 代码质量审查发现 symlink 绕过、敏感文件大小写、操作域 resolver、`CODEX_HOME` override 问题 | 已按 TDD 修复,并通过最终门禁 |
| 2026-05-25 | 1 | review loop | 规格复审发现 `ResolveAgentTOML` 可经 `agents/demo.toml -> ../auth.json` symlink 绕过 forbidden 检查 | 已按 TDD 修复,并通过最终门禁 |
## Test Results
@@ -27,6 +28,11 @@
| 2026-05-25 | `go test ./...` | PASS | 全量 Go 测试通过 |
| 2026-05-25 | `git diff --check` | PASS | 无 whitespace error |
| 2026-05-25 | `git status --short` | PASS | 仅本轮 Phase 1 修复文件变更 |
| 2026-05-25 | `go test ./internal/codexhome` | FAIL | TDD 红灯:`agents/demo.toml -> ../auth.json` symlink 仍返回 nil |
| 2026-05-25 | `go test ./internal/codexhome` | PASS | symlink final target 指向 root `auth.json` 时返回 forbidden error |
| 2026-05-25 | `go test ./...` | PASS | 全量 Go 测试通过 |
| 2026-05-25 | `git diff --check` | PASS | 无 whitespace error |
| 2026-05-25 | `git status --short` | PASS | 仅本轮 Phase 1 symlink target 修复文件变更 |
## Bug Loop
@@ -36,3 +42,4 @@
| 1 | `AUTH.JSON` 等大小写变体未被敏感文件 denylist 拦截 | 对敏感根文件相对路径做 case-insensitive 匹配 | `go test ./internal/codexhome` PASS |
| 1 | 缺少操作域 resolver通用 `ResolveInside` 容易误用 | 新增 `ResolveAgentTOML`,只允许 `agents/` 直属 `.toml` 文件名 | `go test ./internal/codexhome` PASS |
| 1 | `docs/project.md` 记录 `CODEX_HOME` 但默认配置未读取 | `DefaultConfig` 增加 `CODEX_HOME` 非空 override | `go test ./internal/app` PASS |
| 1 | `ResolveAgentTOML` 可通过 `agents/*.toml` symlink 指向 root `auth.json` 绕过 forbidden 检查 | 在 symlink 解析后对 evaluated final target 再执行 forbidden 检查 | `go test ./internal/codexhome` PASS |

View File

@@ -30,3 +30,4 @@
| Time | Phase | Error | Attempt | Resolution |
| --- | --- | --- | --- | --- |
| 2026-05-25 | 1 | 代码质量审查发现 symlink 边界绕过、敏感文件大小写匹配、缺少操作域 resolver、`CODEX_HOME` 未生效 | TDD 补充失败测试后修复 `codexhome``app` | 已通过最终验证 |
| 2026-05-25 | 1 | 规格复审发现 `ResolveAgentTOML` 可通过 `agents/*.toml` symlink 指向 root `auth.json` 绕过 forbidden 检查 | TDD 补充 symlink-to-auth 测试后检查 resolved final target | 已通过最终验证 |