MCPcopy Create free account
hub / github.com/diillson/chatcli / validatePath

Method validatePath

pkg/coder/engine/engine.go:127–189  ·  view source on GitHub ↗

validatePath checks that a file path is within the workspace boundary and not sensitive.

(target string)

Source from the content-addressed store, hash-verified

125
126// validatePath checks that a file path is within the workspace boundary and not sensitive.
127func (e *Engine) validatePath(target string) error {
128 if target == "" {
129 return nil
130 }
131
132 abs, err := filepath.Abs(target)
133 if err != nil {
134 return fmt.Errorf("cannot resolve path %q: %w", target, err)
135 }
136
137 // Resolve symlinks (follow the real path)
138 resolved := abs
139 if evalPath, err := filepath.EvalSymlinks(abs); err == nil {
140 resolved = evalPath
141 } else {
142 parent := filepath.Dir(abs)
143 if evalParent, err2 := filepath.EvalSymlinks(parent); err2 == nil {
144 resolved = filepath.Join(evalParent, filepath.Base(abs))
145 }
146 }
147
148 // Block sensitive system paths
149 for _, sp := range sensitivePaths {
150 if strings.HasPrefix(resolved, sp) {
151 return fmt.Errorf("access to sensitive path %q is blocked", target)
152 }
153 }
154
155 // Enforce workspace boundary
156 if e.WorkspaceRoot != "" {
157 boundary, err := filepath.Abs(e.WorkspaceRoot)
158 if err == nil {
159 if evalB, err2 := filepath.EvalSymlinks(boundary); err2 == nil {
160 boundary = evalB
161 }
162 }
163
164 isSystemBin := false
165 for _, bp := range systemBinPaths {
166 if strings.HasPrefix(resolved, bp) {
167 isSystemBin = true
168 break
169 }
170 }
171
172 if !isSystemBin && resolved != boundary && !strings.HasPrefix(resolved, boundary+"/") {
173 // Check aux allowlist (e.g. session scratch dir, tool-result
174 // overflow). These are registered only by the CLI itself, so
175 // they're trusted.
176 for _, aux := range auxAllowedPathsSnapshot() {
177 if evalAux, err := filepath.EvalSymlinks(aux); err == nil {
178 aux = evalAux
179 }
180 if resolved == aux || strings.HasPrefix(resolved, aux+string(filepath.Separator)) {
181 return nil
182 }
183 }
184 return fmt.Errorf("path %q is outside workspace boundary %q", target, e.WorkspaceRoot)

Callers 8

handleMultipatchMethod · 0.95
handleReadMethod · 0.95
handleWriteMethod · 0.95
handlePatchMethod · 0.95
handleRollbackMethod · 0.95
handleCleanMethod · 0.95
handleExecMethod · 0.95
handleTestMethod · 0.95

Calls 3

auxAllowedPathsSnapshotFunction · 0.85
ErrorfMethod · 0.80
DirMethod · 0.45

Tested by

no test coverage detected