harden: reject ".", "..", and absolute paths in ValidateSessionID · Entire
harden: reject ".", "..", and absolute paths in ValidateSessionID
71790ea→main·
Soph·1mo ago·2 files·+29 added/-0 removed
ValidateSessionID previously rejected only path separators and empty input. A bare "." or ".." is separator-free yet still traverses when an agent uses the ID as a path segment (e.g. Copilot CLI builds
Because the same validator guards both checkpoint writes and the resume/rewind restore boundaries, this tightens the whole class without affecting UUID-style IDs.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
388c3d8a3b31View transcript
Changes
2
cmd/entire/cli/validation
Mvalidators.go+11
Mvalidators_test.go+18
4 unmodified lines
5
6
7
8
9
10
11
12 unmodified lines
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
4 unmodified lines
import (
"errors"
"fmt"
"path/filepath"
"regexp"
"strings"
)
12 unmodified lines
if strings.ContainsAny(id, "/\\") {
return fmt.Errorf("invalid session ID %q: contains path separators", id)
}
// A bare "." or ".." is separator-free but still traverses when used as a
// path segment (e.g. an agent that uses the ID as a directory component).
if id == "." || id == ".." {
return fmt.Errorf("invalid session ID %q: reserved path segment", id)
}
// Defense in depth against platform-specific absolute forms (e.g. Windows
// drive paths) that the separator check above may not catch.
if filepath.IsAbs(id) {
return fmt.Errorf("invalid session ID %q: must not be an absolute path", id)
}
return nil
}
Mcmd/entire/cli/validation/validators.go+11
71 unmodified lines
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
71 unmodified lines
wantErr: true,
errMsg: "contains path separators",
},
// Bare path segments (separator-free but still traverse as a path component)
{
name: "single dot",
sessionID: ".",
wantErr: true,
errMsg: "reserved path segment",
},
{
name: "double dot",
sessionID: "..",
wantErr: true,
errMsg: "reserved path segment",
},
{
name: "dot in the middle is allowed",
sessionID: "a..b",
wantErr: false,
},
}
for _, tt := range tests {
Mcmd/entire/cli/validation/validators_test.go+18