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
}
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
}