fix: restore path-traversal rejection and enable tasktool config flag

- Check original key for '/' and '\' before sanitizing in session/manager.go
  and session/tasks.go, so traversal-like keys are rejected rather than
  silently normalized by SanitizeFilename (fixes TestSave_RejectsPathTraversal)
- Add "tasktool" case to IsToolEnabled switch so tools.tasktool.enabled: false
  actually disables the tool instead of falling through to default: true
This commit is contained in:
Dmitrii Balabanov 2026-03-08 00:11:08 +02:00
parent 896fb08f93
commit e7585e8185
3 changed files with 18 additions and 4 deletions

View file

@ -953,6 +953,8 @@ func (t *ToolsConfig) IsToolEnabled(name string) bool {
return t.WriteFile.Enabled
case "mcp":
return t.MCP.Enabled
case "tasktool":
return t.TaskTool.Enabled
default:
return true
}

View file

@ -151,13 +151,19 @@ func (sm *SessionManager) Save(key string) error {
return nil
}
// Reject keys containing path separators before sanitizing, so that
// traversal-like inputs (e.g. "foo/bar") are never silently normalized.
if strings.ContainsAny(key, `/\`) {
return os.ErrInvalid
}
filename := fileutil.SanitizeFilename(key)
// filepath.IsLocal rejects empty names, "..", absolute paths, and
// OS-reserved device names (NUL, COM1 … on Windows).
// The extra checks reject "." and any directory separators so that
// the session file is always written directly inside sm.storage.
if filename == "." || !filepath.IsLocal(filename) || strings.ContainsAny(filename, `/\`) {
// The extra check rejects "." so that the session file is always
// written directly inside sm.storage.
if filename == "." || !filepath.IsLocal(filename) {
return os.ErrInvalid
}

View file

@ -154,9 +154,15 @@ func (tm *TaskManager) Save(key string) error {
if err := os.MkdirAll(tm.storage, 0o755); err != nil {
return err
}
// Reject keys containing path separators before sanitizing, so that
// traversal-like inputs (e.g. "foo/bar") are never silently normalized.
if strings.ContainsAny(key, "/\\") {
return os.ErrInvalid
}
filename := fileutil.SanitizeFilename(key) + "_tasks.json"
if filename == "." || !filepath.IsLocal(filename) || strings.ContainsAny(filename, "/\\") {
if filename == "." || !filepath.IsLocal(filename) {
return os.ErrInvalid
}