validate

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

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

View Source
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.

View Source
const MaxVersionLength = 128

MaxVersionLength is the maximum allowed version string length.

Variables

View Source
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.

View Source
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.

View Source
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

func ComponentName(name, kind string) (ok bool, reason string)

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

func ContainedPath(baseDir, relPath string) (string, error)

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

func ContainsTraversal(s string) bool

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

func IsWindowsReserved(name string) bool

IsWindowsReserved checks if a name is a Windows reserved device name. Handles case-insensitivity and extension stripping (con.txt -> con).

func PathComponent

func PathComponent(seg string) error

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

func PathSafe(s string) error

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

func RejectPathTraversal(s string) error

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

func RejectTraversalInPath(s string) error

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

func RelativePath(path string) error

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

func RelativePathWithPrefix(path, requiredPrefix string) error

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

func Version(version string) error

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

func WindowsFilename(name string) error

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

func NewSafeInt(n int64) SafeInt

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

func ParseSafeInt(n int64) (SafeInt, error)

ParseSafeInt validates and returns a SafeInt from an int64. Returns an error if the value is negative or exceeds MaxSafeInt.

func (SafeInt) Int64

func (s SafeInt) Int64() int64

Int64 returns the SafeInt as an int64.

func (SafeInt) MarshalJSON

func (s SafeInt) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (SafeInt) String

func (s SafeInt) String() string

String returns the SafeInt as a decimal string.

func (*SafeInt) UnmarshalJSON

func (s *SafeInt) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler with validation. Accepts both JSON numbers and JSON strings containing integers.

func (*SafeInt) UnmarshalYAML

func (s *SafeInt) UnmarshalYAML(unmarshal func(interface{}) error) error

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

func MustParseSemVer(version string) SemVer

MustParseSemVer parses a version, panicking on invalid input. Use only for compile-time constants or test fixtures.

func ParseSemVer

func ParseSemVer(version string) (SemVer, error)

ParseSemVer validates and returns a SemVer. Returns an error if the version contains path traversal or invalid characters.

func (SemVer) String

func (v SemVer) String() string

String returns the version as a string.

func (*SemVer) UnmarshalJSON

func (v *SemVer) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler with validation.

func (*SemVer) UnmarshalYAML

func (v *SemVer) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements yaml.Unmarshaler with validation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL