crowdsecurity/crowdsec · error
%q: path escapes base directory %q
Error message
%q: path escapes base directory %q
What it means
After computing the absolute joined path, SafePath re-derives filepath.Rel(absBase, absFilePath). If the relative result starts with "..", the requested path climbs outside the base directory, which is rejected to prevent path traversal (e.g. via "../" segments).
Source
Thrown at pkg/cwhub/safepath.go:37
if filepath.IsAbs(relPath) ||
// on windows, IsAbs fails for paths beginning with "/", since it's the root of the drive
strings.HasPrefix(relPath, string(os.PathSeparator)) ||
strings.HasPrefix(relPath, "/") {
return "", fmt.Errorf("%q: must be a relative path", relPath)
}
absFilePath, err := filepath.Abs(filepath.Join(absBase, relPath))
if err != nil {
return "", err
}
rel, err := filepath.Rel(absBase, absFilePath)
if err != nil {
return "", err
}
if strings.HasPrefix(rel, "..") {
return "", fmt.Errorf("%q: path escapes base directory %q", relPath, baseDir)
}
return absFilePath, nil
}
View on GitHub (pinned to 909b515798)
Solutions
- Clean the input with filepath.Clean and reject paths containing ".." before calling
- Validate the item name/remote path against an allow-list pattern (no separators or dots sequences)
- Log the offending input — this usually indicates tampered or malformed data, not a user fix
Example fix
// before
SafePath(baseDir, "../../etc/shadow")
// after
rel := filepath.Clean(userPath)
if strings.HasPrefix(rel, "..") { return errors.New("invalid path") }
p, err := SafePath(baseDir, rel) Defensive patterns
Strategy: validation
Validate before calling
cleaned := filepath.Clean(userPath)
if strings.HasPrefix(cleaned, "..") {
return errors.New("path must stay within the hub directory")
} Try / catch
p, err := cwhub.SafePath(baseDir, rel)
if err != nil {
return fmt.Errorf("rejected unsafe path %q: %w", rel, err) // treat as security event
} Prevention
- Reject any path containing ".." segments at the input boundary
- Log SafePath rejections as potential tampering
- Keep SafePath as the single choke point for all hub file paths
When it happens
Trigger: SafePath called with relative paths containing ".." segments such as "../../escape.yaml" or nested like "a/../../b.yaml" that resolve outside absBase.
Common situations: Malicious hub index entries with traversal segments; buggy path construction concatenating user input; symlink-free traversal attempts during download/install of hub items.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- %q: must be a relative path
- group_name is mandatory for CloudwatchSource
- path must start with /
- basic_auth is selected, but basic_auth is not provided
- basic_auth is selected, but username is not provided
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/fde33a5f9c8e73b0.
Report an issue: GitHub.