Documentation
¶
Overview ¶
Package validate provides centralized security validation functions.
This package consolidates validation logic that was previously duplicated across multiple packages, ensuring consistent security checks for:
- Version strings (semver format, path traversal prevention)
- Path components (filename/directory validation)
- Relative paths (traversal prevention)
- Path containment (ensuring paths stay within base directories)
SECURITY: All validation functions are designed to prevent path traversal attacks, including edge cases like embedded separators, double-dot sequences, and platform-specific quirks (Windows reserved names, UNC paths, etc.).
Index ¶
- Constants
- Variables
- func ComponentName(name, kind string) (ok bool, reason string)
- func ContainedPath(baseDir, relPath string) (string, error)
- func ContainsTraversal(s string) bool
- func IsWindowsReserved(name string) bool
- func PathComponent(seg string) error
- func PathSafe(s string) error
- func RejectPathTraversal(s string) error
- func RejectTraversalInPath(s string) error
- func RelativePath(path string) error
- func RelativePathWithPrefix(path, requiredPrefix string) error
- func Version(version string) error
- func WindowsFilename(name string) error
- type SafeInt
- type SemVer
Constants ¶
const MaxSafeInt int64 = (1 << 53) - 1
MaxSafeInt is the maximum integer exactly representable in JSON (2^53 - 1). JavaScript and many JSON parsers use IEEE 754 doubles which lose precision above this value.
const MaxVersionLength = 128
MaxVersionLength is the maximum allowed version string length.
Variables ¶
var ComponentNameRegex = regexp.MustCompile(`^[a-z0-9][a-z0-9._-]{0,63}$`)
ComponentNameRegex validates collector/tool/remote/utility/environment names. Names must start with alphanumeric and contain only alphanumeric, dash, underscore, or dot. Maximum length 64 characters. No path separators, .., or absolute paths allowed.
var VersionRegex = regexp.MustCompile(`^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([a-zA-Z0-9][a-zA-Z0-9.-]*))?$`)
VersionRegex matches semver versions with a safe prerelease charset. SECURITY: The prerelease pattern [a-zA-Z0-9.-]+ explicitly rejects URL-unsafe characters (/, ?, #, %, \, etc.) to prevent path/query smuggling when the version is used in GitHub API URLs.
var WindowsReservedNames = map[string]struct{}{
"con": {}, "prn": {}, "aux": {}, "nul": {},
"com1": {}, "com2": {}, "com3": {}, "com4": {},
"com5": {}, "com6": {}, "com7": {}, "com8": {}, "com9": {},
"lpt1": {}, "lpt2": {}, "lpt3": {}, "lpt4": {},
"lpt5": {}, "lpt6": {}, "lpt7": {}, "lpt8": {}, "lpt9": {},
}
WindowsReservedNames contains device names reserved on Windows. These names are case-insensitive and invalid even with extensions (e.g., "con", "CON", "con.txt" are all reserved).
SECURITY: Use IsWindowsReserved or WindowsFilename to check names. Direct map access requires lowercase conversion first.
Functions ¶
func ComponentName ¶
ComponentName validates a component name for filesystem path safety. Returns ok=true if valid, or ok=false with a reason string.
SECURITY: This is the canonical component name validator. All component name validation should use this function to ensure consistent security checks.
The kind parameter is used only for error messages (e.g., "collector", "tool").
func ContainedPath ¶
ContainedPath validates that joining baseDir + relPath stays within baseDir. Returns the joined absolute path on success.
SECURITY: This is the primary function for safely joining untrusted relative paths with a trusted base directory. It prevents all path traversal attacks including those using symlinks in the path string itself.
Note: This does NOT check for symlinks on the filesystem. For symlink-safe operations, use safefile.ValidatePath or safefile.WriteFile.
func ContainsTraversal ¶
ContainsTraversal checks if a string contains ".." path traversal sequences.
SECURITY: Use this for quick traversal checks. For comprehensive path validation, use RejectPathTraversal which also checks separators.
func IsWindowsReserved ¶
IsWindowsReserved checks if a name is a Windows reserved device name. Handles case-insensitivity and extension stripping (con.txt -> con).
func PathComponent ¶
PathComponent validates a single path component (filename or directory name). Rejects traversal segments and embedded separators.
SECURITY: Use this when validating individual path segments that will be joined into a full path. This prevents injection of traversal sequences.
func PathSafe ¶
PathSafe validates a string is safe for use in path construction. Rejects path traversal patterns without validating path format.
Use cases:
- Component names, versions, project names
- Any untrusted string that becomes part of a path
For validating actual paths, use RelativePath() or ContainedPath().
SECURITY: Delegates to RejectPathTraversal which catches all known path traversal attack vectors including separators, .., and double-dots.
func RejectPathTraversal ¶
RejectPathTraversal rejects strings containing path traversal patterns. Used by Version, ComponentName, and other validators.
SECURITY: This catches all known path traversal attack vectors:
- Path separators (/ and \)
- Exact traversal segments (. and ..)
- Prefix traversal (../ and ..\)
- Embedded traversal (/../ and \..\)
- Double-dot sequences anywhere (catches edge cases like "foo.." or "..bar")
func RejectTraversalInPath ¶
RejectTraversalInPath rejects path traversal patterns while allowing forward slashes. Use this for validating paths like stream identifiers ("org/prod") that legitimately contain "/" but should not contain traversal sequences.
SECURITY: This catches traversal attacks while allowing hierarchical identifiers:
- Backslashes (Windows path separators)
- Exact traversal segments (. and ..)
- Prefix traversal (../)
- Embedded traversal (/../)
- Leading or trailing slashes (could indicate absolute path or ambiguous intent)
- Empty segments (consecutive slashes //)
func RelativePath ¶
RelativePath validates a relative path against traversal and escapes. Does NOT resolve the path against the filesystem - just validates the string.
SECURITY: Use this for paths that should be relative (e.g., paths from untrusted input like zip entries, config files, or user input).
func RelativePathWithPrefix ¶
RelativePathWithPrefix validates a relative path and ensures it has a required prefix. This is useful for paths like "artifacts/foo.json" that must be under a specific directory.
func Version ¶
Version validates a version string for safe filesystem and URL use. Accepts semver-like versions: v1.2.3, v1.2.3-alpha.1, 1.2.3, etc. Rejects path traversal, path separators, and malformed semver.
SECURITY: This is the canonical version validator. All version validation should use this function to ensure consistent security checks.
func WindowsFilename ¶
WindowsFilename validates a filename is safe for use on Windows. Rejects:
- Reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
- Forbidden characters: < > : " | ? *
- Trailing dots and spaces (Windows silently strips these)
Does NOT check path separators - use PathComponent for full validation.
Types ¶
type SafeInt ¶
type SafeInt int64
SafeInt is a JSON-safe non-negative integer that fits within IEEE 754 double precision. Can only be constructed via ParseSafeInt or NewSafeInt.
SECURITY: This type guarantees the integer: - Is non-negative (>= 0) - Is at most MaxSafeInt (2^53 - 1) - Will be parsed identically by all JSON parsers
func NewSafeInt ¶
NewSafeInt creates a SafeInt, panicking if the value is invalid. Use only for compile-time constants or when the value is guaranteed valid.
func ParseSafeInt ¶
ParseSafeInt validates and returns a SafeInt from an int64. Returns an error if the value is negative or exceeds MaxSafeInt.
func (SafeInt) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (*SafeInt) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler with validation. Accepts both JSON numbers and JSON strings containing integers.
func (*SafeInt) UnmarshalYAML ¶
UnmarshalYAML implements yaml.Unmarshaler with validation.
type SemVer ¶
type SemVer string
SemVer is a validated semantic version string safe for filesystem paths and URLs. Can only be constructed via ParseSemVer.
SECURITY: This type guarantees the version string: - Matches semver format (v1.2.3 or v1.2.3-prerelease) - Contains no path traversal patterns (/, \, ..) - Contains no URL-unsafe characters in prerelease - Is under MaxVersionLength bytes
func MustParseSemVer ¶
MustParseSemVer parses a version, panicking on invalid input. Use only for compile-time constants or test fixtures.
func ParseSemVer ¶
ParseSemVer validates and returns a SemVer. Returns an error if the version contains path traversal or invalid characters.
func (*SemVer) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler with validation.
func (*SemVer) UnmarshalYAML ¶
UnmarshalYAML implements yaml.Unmarshaler with validation.