fix: store OAuth credentials and config with owner-only file permissions - #4
Conversation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
Good direction overall — this is a real security improvement over the current 0644 default. Two things worth fixing before merge:
#[cfg(unix)] This eliminates the race entirely — the file never exists with loose permissions.
Apart from these two points, the implementation is solid: the #[cfg(unix)] / #[cfg(not(unix))] split is correct, the tests cover both new-file and tighten-existing-file cases, and calling restrict_dir on startup is a good touch for upgrading old This doesn't replace Keychain/secret-service for token storage (which remains the proper long-term fix), but it's a worthwhile stop-gap that's easy to maintain. — Review assisted by Claude Opus 4.6 |
…fig dir Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Thanks — both points addressed in b3ec85a:
Agreed that Keychain/Secret Service remains the proper long-term fix for token storage; this is the stop-gap. |
Summary
Security fix from a codebase scan. The client persists OAuth access and refresh tokens in
~/.cloudreve/drives.json, and app settings in the config file. Both were written withstd::fs::write, which creates files using the process umask (typically0644— world-readable). On shared macOS/Linux machines, any other local user could read the stored tokens.This PR makes credential/config writes owner-only:
utils::secure_fshelper:write_private(path, contents)— writes thenchmod 0600(Unix); no-op elsewhere.restrict_file/restrict_dir—0600/0700on Unix.Behavior is unchanged on the happy path; only the on-disk permission bits change. Added unit tests asserting the credential file lands at
0600and that an existing0644file is tightened on rewrite.Other findings from the scan (not changed here — need a decision)
CLIENT_SECRETinui/src/utils/constants.ts, shipped in the distributed app. For a native/public client using PKCE the embedded secret provides no real protection and is extractable from any install. Removing it safely requires registering the desktop client as a public PKCE client on the Cloudreve server (droppingclient_secretfrom the token exchange); doing it blindly would break auth, so it's left untouched pending that server-side change.csp: nullandassetProtocolscope**/*intauri.conf.jsonare permissive; tightening them is worthwhile but risks breaking the app (it connects to arbitrary user-configured servers), so it needs testing.sql_querythat uses bind params), thecloudreve://deep-link handler, and Tauri IPC commands were reviewed and looked fine. A dependency audit (cargo audit,yarn npm audit) couldn't run in this environment — recommend wiring it into CI.Testing
cargo test -p cloudreve-sync— all pass (31 unit + integration/scenario tests + 2 new secure_fs tests).Link to Devin session: https://app.devin.ai/sessions/1a95a6aa9b35413d82c31da765c241e4
Requested by: @cedev-1