AlistGo/alist · error

share path out of range

Error message

share path out of range

What it means

Returned by resolveShareTarget (server/handles/share.go:370) when the cleaned, joined target path falls outside share.RootPath according to utils.IsSubPath. This is the share engine's path-traversal guard: after FixAndCleanPath and stdpath.Join, any residue of ".." that would escape the shared root produces this error instead of a filesystem read.

Source

Thrown at server/handles/share.go:370

	}
	return true
}

func shouldTrackShareContentAccess(c *gin.Context) bool {
	return c.Request.Method != http.MethodHead
}

func resolveShareTarget(share *model.Share, rawRelPath string) (string, string, error) {
	cleanRelPath := utils.FixAndCleanPath(rawRelPath)
	if !share.IsDir && cleanRelPath != "/" {
		return "", "", fmt.Errorf("file share does not support nested path")
	}
	if cleanRelPath == "/" {
		return share.RootPath, "/", nil
	}
	target := utils.FixAndCleanPath(stdpath.Join(share.RootPath, cleanRelPath))
	if !utils.IsSubPath(share.RootPath, target) {
		return "", "", fmt.Errorf("share path out of range")
	}
	return target, cleanRelPath, nil
}

func resolveShareWildcardTarget(share *model.Share, rawPath string) (string, string, error) {
	path, err := url.PathUnescape(rawPath)
	if err != nil {
		return "", "", err
	}
	return resolveShareTarget(share, strings.TrimPrefix(path, "/"))
}

func buildPublicShareAssetURL(c *gin.Context, prefix, shareID, relPath, token string, preview bool) string {
	base := common.GetApiUrl(c.Request) + prefix + shareID
	cleanPath := utils.FixAndCleanPath(relPath)
	if cleanPath != "/" {
		base += utils.EncodePath(cleanPath, true)
	}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Request only paths that lexically sit inside the share root
  2. URL-encode path segments and never hand-build ../ sequences
  3. If you legitimately need a sibling path, create a share rooted at the common parent

Example fix

// before
rel := "../../secret.txt"
// after
rel := "docs/secret.txt" // relative to the share root
Defensive patterns

Strategy: validation

Validate before calling

func insideShareRoot(root, rel string) bool {
  joined := path.Clean(path.Join(root, rel))
  return joined == root || strings.HasPrefix(joined, root+"/")
}

Try / catch

// treat as a security signal, not a retry candidate:
if err != nil && strings.Contains(err.Error(), "out of range") { log.Warnf("traversal attempt: %v", rawPath) }

Prevention

When it happens

Trigger: GET /s/<shareID>/../../etc/passwd style URLs; URL-encoded traversal (%2e%2e%2f) that survives cleaning; crafted wildcard share paths after url.PathUnescape in resolveShareWildcardTarget — this fires purely on lexical path analysis, not on symlink targets.

Common situations: Security scanners probing share links; mis-encoded paths from clients; hand-built relative paths mixing absolute and relative segments.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/20c7c4535ac6172d. Report an issue: GitHub.