Files
readest/apps/readest-app/src-tauri
Huang Xin 446c2c72de fix(security): unblock app-dir downloads broken by transfer_file fs-scope guard (#4651)
#4639 added a strict `app.fs_scope().is_allowed()` check to download_file/
upload_file. On Android that returns false for the app's own storage, so every
download into the app dir (book covers, dictionaries, books, gloss packs, OPDS
books in the cache dir) failed with "permission denied: path not in filesystem
scope".

Root cause: download_file/upload_file are plain app commands using raw tokio::fs,
so Tauri does not scope file_path. The capability scope patterns that cover the
app's storage ($APPDATA/Readest/**, $APPCACHE/**, **/Readest/**/*) are
command-scoped and absent from the global fs_scope() FsExt exposes (it is
initialized FsScope::default() and only ever gains runtime dialog/persisted-scope
grants), so is_allowed() returns false for the app's own files.

Interim fix mirroring dir_scanner::read_dir: keep rejecting relative and `..`
paths, then accept the path if the fs scope allows it (persisted dialog grants
for custom/external roots) OR it lives inside the app's own storage — matched by
the `Readest` data folder or the app's bundle identifier (app.config().
identifier), which the Android sandbox (/data/user/0/<id>/…, cache dir included)
and the desktop identifier dirs always carry. The `..` rejection keeps the
GHSA-55vr-pvq5-6fmg hardening: foreign targets like ~/.ssh/id_rsa carry neither
segment and stay blocked.

Follow-up (tracked separately): replace the substring fallback with a
BaseDirectory + relative path resolved via app.path(), so targets are in-scope by
construction with no string markers.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:48:10 +02:00
..
2024-10-12 19:51:09 +02:00