harden: address PR review — Windows volume + glob-metachar session IDs · Entire

harden: address PR review — Windows volume + glob-metachar session IDs

fdff08c→main·

Soph·1mo ago·4 files·+81 added/-10 removed

Three issues from PR #1365 review:

Adds regression tests for the drive-relative and glob-metacharacter cases.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

ed740e10abe5View transcript

Changes

532 unmodified lines  
// matchSessionFiles returns the names (not paths) of files in dir that belong to  
// the given session ID — i.e. "<sessionID>.<ext>". It uses literal prefix  
// matching, never glob patterns, so a session ID containing glob metacharacters  
// cannot match unrelated files.  
func matchSessionFiles(dir, sessionID string) []string {  
    entries, err := os.ReadDir(dir)  
    if err != nil {  
        return nil // missing/unreadable dir => nothing to clear  
    }  
    prefix := sessionID + "."  
    var matched []string  
    for _, e := range entries {  
        if name := e.Name(); strings.HasPrefix(name, prefix) {  
            matched = append(matched, name)  
        }  
    }  
    return matched  
}  
// RemoveAll removes the entire session state directory.  
// This is used during uninstall to completely remove all session state.  
func (s *StateStore) RemoveAll() error {  
    // Remove all files for this session (state .json, .model hint, any future hint files).  
    // filepath.Glob finds matches; os.Root ensures traversal-resistant removal.  
    matches, _ := filepath.Glob(filepath.Join(s.stateDir, sessionID + ".*")) //nolint:errcheck // pattern is always valid  
for _, f := range matches {  
    _ = osroot.Remove(root, filepath.Base(f)) //nolint:errcheck // best-effort cleanup  
}  
// Reject glob metacharacters. Session IDs are interpolated into  
// filepath.Glob patterns in several places (agent transcript lookup,  
// session-state cleanup); "*"/"?"/"[" could match and act on unrelated files.  
if strings.ContainsAny(id, "*?[") {  
    return fmt.Errorf("invalid session ID %q: contains glob metacharacters", id)  
}  
89 unmodified lines  
for _, tt := range tests {