Last Updated: April 9, 2026
- Always validate ZIP entry names with a safe join. Reject absolute paths, Windows drive or volume paths, and any entry that escapes the target directory after cleaning.
- ZIP entry names use slash semantics, not host OS semantics: validate with
path.Cleanandpath.IsAbs, reject backslashes, and usepath.Basefor hidden-name checks. - Convert ZIP names to OS paths only at write time with
filepath.FromSlash(...). - Enforce destination containment with
filepath.Rel(...)rather than string-prefix checks. - Enforce per-file and total-size budgets to prevent resource exhaustion.
- Skip OS metadata directories such as
__MACOSXand reject suspicious names. - Keep tests for absolute and volume path rejection, traversal skipping,
__MACOSXskipping, size limits, directory creation, and safe nested extraction. - The current implementation lives in
pkg/fs/zip.goviaUnzip,UnzipFile, andsafeJoin.
- Use
pkg/http/safeandsafe.Download(destPath, url, *safe.Options)instead of ad-hocnet/httpdownload code. - Default policy allows only
httpandhttps, enforces timeouts and max size, writes to a0600temp file, then renames into place. - For SSRF protection, set
AllowPrivate=falseunless a test explicitly needs private or loopback addresses. - Validate redirect targets and the final connected peer IP.
- Prefer an image-focused
Acceptheader for image downloads:"image/jpeg, image/png, */*;q=0.1". - Use
internal/thumb/avatar.SafeDownloadfor avatars and other small images; it applies a 15-second timeout, a 10 MiB cap, andAllowPrivate=false. - Tests using
httptest.Serveron127.0.0.1must setAllowPrivate=true. - Keep size budgets small and rely on
io.LimitReaderplusContent-Lengthprechecks.
- Filesystem copy, move, and unzip helpers:
go test ./pkg/fs -run 'Copy|Move|Unzip' -count=1 - Media helpers:
go test ./pkg/media/... -count=1