Documentation ¶
Overview ¶
Package vfs extends the default Golang FS abstraction to support secured write operations.
Index ¶
Examples ¶
Constants ¶
const ( Separator = string(filepath.Separator) SelfDir = "." ParentDir = ".." FakeRoot = "/" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ConfirmedDir ¶
type ConfirmedDir string
ConfirmedDir is a clean, absolute, delinkified path that was confirmed to point to an existing directory.
func ConfirmDir ¶
func ConfirmDir(root FileSystem, path string) (ConfirmedDir, error)
ConfirmDir returns an error if the user-specified path is not an existing directory on root. Otherwise, ConfirmDir returns path, which can be relative, as a ConfirmedDir and all that implies.
Example ¶
// Chroot to temporary directory root, err := Chroot(os.TempDir()) if err != nil { panic(err) } // Use the filesystem to resolve the real target path. cdir, err := ConfirmDir(root, ".") if err != nil { panic(err) }
Output: /
func NewTmpConfirmedDir ¶
func NewTmpConfirmedDir() (ConfirmedDir, error)
NewTmpConfirmedDir returns a temporary dir, else error. The directory is cleaned, no symlinks, etc. so it's returned as a ConfirmedDir.
Example ¶
// Create and resolve a confirmed temporary directory // For MacOS, the final directory is resolved from its symbolic link. cdir, err := NewTmpConfirmedDir() if err != nil { panic(err) } // Try to escape from the confirmed directory cdir1 := cdir.Join("../etc/password") // Check new path validity isValid := cdir.HasPrefix(ConfirmedDir(cdir1))
Output: false
func (ConfirmedDir) HasPrefix ¶
func (d ConfirmedDir) HasPrefix(path ConfirmedDir) bool
HasPrefix ensure that the given path has the confirmed directory as prefix.
func (ConfirmedDir) Join ¶
func (d ConfirmedDir) Join(path string) string
Join the given path to the confirmed directory.
func (ConfirmedDir) String ¶
func (d ConfirmedDir) String() string
type ConstraintError ¶
ConstraintError records an error and the operation and file that violated it.
func (*ConstraintError) Error ¶
func (e *ConstraintError) Error() string
Error returns the formatted error string for the ConstraintError.
func (*ConstraintError) Unwrap ¶
func (e *ConstraintError) Unwrap() error
Unwrap implements error unwrapping.
type FileSystem ¶
type FileSystem interface { fs.FS fs.StatFS fs.ReadDirFS fs.ReadFileFS fs.GlobFS // Create a file. Create(name string) (File, error) // Mkdir creates a directory form the given path. Mkdir(path string, perm fs.FileMode) error // MkdirAll creats a directory path with all intermediary directories. MkdirAll(path string, perm fs.FileMode) error // IsDir returns true if the path is a directory. IsDir(path string) bool // Exists is true if the path exists in the filesystem. Exists(path string) bool // Chmod changes the filemode of the given path. Chmod(name string, mode fs.FileMode) error // Symlink creates a symbolink link. Symlink(name, target string) error // Link creates a hardlink. Link(path, name string) error // RemoveAll removes all path elements from the given path from the filesystem. RemoveAll(path string) error // Remove remove the given path from the filesystem. Remove(path string) error // Resolve the given path to return a real/delinked absolute path. Resolve(path string) (ConfirmedDir, string, error) // WriteFile writes given data to the given path as a file with the given filemode. WriteFile(path string, data []byte, perm fs.FileMode) error // WalkDir the filesystem form the given path. WalkDir(path string, walkFn fs.WalkDirFunc) error }
FileSystem extends the default read-only filesystem abstraction to add write operations.
func Chroot ¶
func Chroot(root string) (FileSystem, error)
Chroot returns a chrooted filesystem assuming an OS base filesystem as root filesystem.
Example ¶
// Chroot to temporary directory root, err := Chroot(os.TempDir()) if err != nil { panic(err) } // Chroot is compatible with Go fs.FS abstraction if err := fs.WalkDir(root, ".", func(path string, d fs.DirEntry, err error) error { // Do something return nil }); err != nil { panic(err) } // Provides filesystem isolation to prevent path traversal. err = root.Mkdir("../wrong", 0o700) fsErr := &ConstraintError{} switch { case err == nil: // No error case errors.As(err, &fsErr): // Constraint error default: // Other error }
Output: IsConstraintError => true
func ChrootFS ¶
func ChrootFS(root FileSystem, path string) (FileSystem, error)
ChrootFS creates a chrooted filesystem instance from the given filesystem and the path. The path must be a directory part of the given root filesystem to be used.
Example ¶
// Chroot to temporary directory root, err := Chroot(os.TempDir()) if err != nil { panic(err) } // Create a chroot from a parent filesystem. subRoot, err := ChrootFS(root, "var") if err != nil { panic(err) } // Try to open an out of chroot file will raise a ConstraintError. _, err = subRoot.Open("../etc/passwd") switch { case err == nil: // No error default: // Other error }
Output:
func OS ¶
func OS() FileSystem
OS returns a new instance of the OS filesystem.
Example ¶
// Create a host writeable filesystem without constraints. root := OS() // Create a chroot from a parent filesystem. subRoot, err := ChrootFS(root, "/etc/datadog") if err != nil { panic(err) } // Try to open an out of chroot file will raise a ConstraintError. _, err = subRoot.Open("../passwd") switch { case err == nil: // No error default: // Other error }
Output: