Fix arbitrary file check vulnerability in data_dir_has_documents

This commit mitigates an arbitrary file existence check vulnerability by
validating the provided directory path against Tauri's allowed filesystem
scope using `tauri_plugin_fs`.

- Added `tauri-plugin-fs` dependency.
- Injected `AppHandle` into the `data_dir_has_documents` command.
- Verified that the target file path (`documents.json`) is allowed
  within the app's `fs_scope` before calling `.exists()`.
- Registered `tauri_plugin_fs` builder on startup.

Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot] 2026-08-09 10:22:14 +00:00
parent c958f30662
commit da34544806
3 changed files with 13 additions and 2 deletions

1
src-tauri/Cargo.lock generated
View file

@ -3735,6 +3735,7 @@ dependencies = [
"tauri-build", "tauri-build",
"tauri-plugin-autostart", "tauri-plugin-autostart",
"tauri-plugin-dialog", "tauri-plugin-dialog",
"tauri-plugin-fs",
"tauri-plugin-global-shortcut", "tauri-plugin-global-shortcut",
"tauri-plugin-opener", "tauri-plugin-opener",
"tauri-plugin-process", "tauri-plugin-process",

View file

@ -21,6 +21,7 @@ serde_json = "1"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
chrono = "0.4" chrono = "0.4"
futures = "0.3.32" futures = "0.3.32"
tauri-plugin-fs = "2.5.1"
[profile.release] [profile.release]
strip = true strip = true

View file

@ -10,6 +10,7 @@ use tauri::menu::{Menu, MenuItem};
use tauri::tray::TrayIconBuilder; use tauri::tray::TrayIconBuilder;
use tauri::{AppHandle, Emitter, Manager, WindowEvent}; use tauri::{AppHandle, Emitter, Manager, WindowEvent};
use tauri_plugin_dialog::DialogExt; use tauri_plugin_dialog::DialogExt;
use tauri_plugin_fs::FsExt;
use tauri_plugin_opener::OpenerExt; use tauri_plugin_opener::OpenerExt;
const RATES_TTL_SECS: u64 = 3600; const RATES_TTL_SECS: u64 = 3600;
@ -538,8 +539,15 @@ fn open_backups_folder(app: AppHandle, dir: Option<String>) -> Result<(), String
// ---------- data folder migration // ---------- data folder migration
#[tauri::command] #[tauri::command]
fn data_dir_has_documents(dir: String) -> bool { fn data_dir_has_documents(app: AppHandle, dir: String) -> bool {
PathBuf::from(dir).join("documents.json").exists() let path = PathBuf::from(dir).join("documents.json");
if !app
.try_fs_scope()
.is_some_and(|scope| scope.is_allowed(&path))
{
return false;
}
path.exists()
} }
/// strategy: "move" (copy mine, delete originals), "overwrite" (same, target /// strategy: "move" (copy mine, delete originals), "overwrite" (same, target
@ -715,6 +723,7 @@ fn toggle_window(app: &AppHandle) {
fn main() { fn main() {
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| { .plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
if let Some(path) = args.iter().skip(1).find(|a| is_sheet_path(a)) { if let Some(path) = args.iter().skip(1).find(|a| is_sheet_path(a)) {
if let Ok(content) = fs::read_to_string(path) { if let Ok(content) = fs::read_to_string(path) {