toeverything/AFFiNE · error · io::Error

PermissionDenied

PermissionDenied

Error message

mobile file token points outside the workspace cache directory

What it means

Path-containment guard: after canonicalizing the token's path, is_valid_mobile_cache_path shows it is not inside the canonicalized workspace cache directory, indicating a traversal or tampered token; PermissionDenied is returned.

Source

Thrown at packages/frontend/mobile-native/src/cache/mod.rs:303

    let path = value
      .strip_prefix(MOBILE_BLOB_FILE_PREFIX)
      .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidInput, "invalid mobile file token"))?;

    let path = path.strip_prefix("file://").unwrap_or(path);
    let canonical = std::fs::canonicalize(path)?;
    let workspace_dir = {
      self
        .workspace_dirs
        .read()
        .expect("workspace cache lock poisoned")
        .get(universal_id)
        .cloned()
    }
    .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "workspace cache directory not registered"))?;
    let workspace_dir = std::fs::canonicalize(workspace_dir)?;

    if !is_valid_mobile_cache_path(&canonical, &workspace_dir) {
      return Err(std::io::Error::new(
        std::io::ErrorKind::PermissionDenied,
        "mobile file token points outside the workspace cache directory",
      ));
    }

    let metadata = std::fs::metadata(&canonical)?;
    if !metadata.is_file() {
      return Err(std::io::Error::new(
        std::io::ErrorKind::InvalidInput,
        "mobile file token does not resolve to a file",
      ));
    }
    if metadata.len() > MOBILE_BLOB_MAX_READ_BYTES {
      return Err(std::io::Error::new(
        std::io::ErrorKind::InvalidData,
        format!(
          "mobile file token exceeds max size: {} > {}",
          metadata.len(),

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Regenerate the token so it points inside the workspace cache dir.
  2. Reject tokens with path traversal segments.
Defensive patterns

Strategy: validation

When it happens

Trigger: Raised when the canonicalized token path fails the is_valid_mobile_cache_path check against the workspace cache directory, blocking path traversal.

Common situations: The token path resolves outside the workspace cache (symlink or ../ traversal). Treat as a corrupted or malicious blob reference and refresh the document data.


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/af34238c0bf38032. Report an issue: GitHub.