diff --git a/pkg/config/config.go b/pkg/config/config.go index e8bb60274..f8bd15e83 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -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 } diff --git a/pkg/session/manager.go b/pkg/session/manager.go index f39a92d1e..1f953827f 100644 --- a/pkg/session/manager.go +++ b/pkg/session/manager.go @@ -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 } diff --git a/pkg/session/tasks.go b/pkg/session/tasks.go index 48f0c2aeb..b4adaeae4 100644 --- a/pkg/session/tasks.go +++ b/pkg/session/tasks.go @@ -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 }