workspace

package
v0.4.10 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrIsDirectory = errors.New("path is a directory")

ErrIsDirectory is returned by OpenFile when the path is a directory.

View Source
var ErrPathTraversal = errors.New("path traversal detected")

ErrPathTraversal is returned for a path with a ".." component.

Functions

func CheckPath added in v0.4.7

func CheckPath(userPath string) (string, error)

CheckPath rejects a user-provided path that contains a ".." component and returns the path with percent-encoding fully decoded. Callers use it to answer with an error instead of quietly rewriting "../x" to "/x".

The path is URL-decoded in a loop until stable to catch double/triple-encoded traversals (%252e%252e%2f), and the check is per component, not strings.Contains, so "foo..txt" stays valid.

Types

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

func New

func New(baseDir string) *Manager

func (*Manager) Create

func (m *Manager) Create(sessionID uuid.UUID) (string, error)

Create initializes an isolated workspace directory for a session.

os.MkdirAll honours the process umask, which can strip permission bits; the explicit os.Chmod afterwards is umask-independent.

func (*Manager) CreateSnapshot

func (m *Manager) CreateSnapshot(sessionID, snapshotID uuid.UUID) (archivePath string, sizeBytes int64, err error)

CreateSnapshot creates a gzip-compressed tar archive of the session workspace. The archive is written to {baseDir}/snapshots/<snapshotID>.tar.gz and the archive path + uncompressed size are returned.

func (*Manager) Delete

func (m *Manager) Delete(sessionID uuid.UUID) error

Delete removes the workspace directory.

func (*Manager) DeleteSnapshot

func (m *Manager) DeleteSnapshot(archivePath string) error

DeleteSnapshot removes a snapshot archive from disk.

func (*Manager) Exists added in v0.3.2

func (m *Manager) Exists(sessionID uuid.UUID, userPath string) (bool, error)

Exists reports whether userPath refers to a real file/dir inside the session workspace. Symlinks that escape the workspace root are treated as absent (not an oracle for host paths).

func (*Manager) OpenFile

func (m *Manager) OpenFile(sessionID uuid.UUID, userPath string) (*os.File, error)

OpenFile opens a regular file inside the workspace for reading. Symlink targets are validated to remain inside the workspace and directories are rejected with ErrIsDirectory.

func (*Manager) Remove added in v0.4.9

func (m *Manager) Remove(sessionID uuid.UUID, userPath string) error

Remove deletes a file (or empty directory) inside the workspace. The parent directory chain is symlink-resolved and must stay inside the workspace root, so a symlinked directory cannot be used to delete files elsewhere. A symlink in the final component is removed itself, never followed.

func (*Manager) RestoreSnapshot

func (m *Manager) RestoreSnapshot(sessionID uuid.UUID, archivePath string) error

RestoreSnapshot extracts a snapshot archive into the session workspace. Files in the archive overwrite existing files; the workspace is not cleared first so existing files not in the snapshot are preserved.

func (*Manager) SafePath

func (m *Manager) SafePath(sessionID uuid.UUID, userPath string) (string, error)

SafePath resolves a user-provided path within the workspace, enforcing:

  1. URL-decoded (loop until stable) to catch double/triple-encoded traversals
  2. No ".." path components (checked after full decoding, before Clean)
  3. Resolved path stays inside the workspace root (filepath.Clean + HasPrefix)

func (*Manager) SessionDirs added in v0.4.1

func (m *Manager) SessionDirs() ([]uuid.UUID, error)

SessionDirs returns the session IDs that have a directory under the base directory. Entries whose name is not a UUID (snapshots/, warm pool) are skipped.

func (*Manager) SessionPath

func (m *Manager) SessionPath(sessionID uuid.UUID) string

func (*Manager) WriteFile

func (m *Manager) WriteFile(sessionID uuid.UUID, userPath string, r io.Reader, maxBytes int64) (int64, error)

WriteFile writes data to a safe path inside the workspace, creating intermediate directories as needed.

Security: guards against symlink-escape attacks where a container process creates a symlink inside /workspace pointing to a host path outside the workspace root. Two layers of protection are applied:

  1. The entire parent-directory chain is symlink-resolved and verified to stay inside the workspace root before any write takes place.
  2. The file is opened with O_NOFOLLOW so that if the final path component is itself a symlink (e.g. created in a TOCTOU window) the open fails.

Permissions: directories use DirMode and files 0o644. os.Chmod is called after creation to bypass the process umask.

Jump to

Keyboard shortcuts

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