Package vfs extends the default Golang FS abstraction to support secured write operations.
const (
Separator = string(filepath.Separator)
SelfDir = "."
ParentDir = ".."
FakeRoot = "/"
)
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.
// 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.
// 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
type ConstraintError struct { ... }
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 File
type File interface { ... }
File represents the file writer interface.
type FileSystem
type FileSystem interface { ... }
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.
// 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.
// 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.
// 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
}
type SymlinkFS
type SymlinkFS interface { ... }
SymlinkFS extends the default filesystem abstraction to add symbolic link operations. (target Go 1.23)