Skip to content

[P0][security] edit-save save_connection_profile silently wipes the OS keyring password when get() fails #274

Description

@EVWorth

Context

In edit mode the dialog sends password = "" ("leave blank to keep"). The command needs to restore the stored password before save. Currently it does so with if let Ok(stored) = ..., swallowing errors.

Problem

If ConnectionStore::get() returns Err (transient keyring backend failure, locked GNOME Keyring, Flatpak sandbox without Secret Service), profile.password stays empty, save() then treats password.is_empty() as "user wants no password" and calls delete_password(&profile.id)permanently wiping the OS keyring entry. The user sees a success toast and has lost access. test_connection has the same bug: it runs with an empty password and produces a false-negative Access denied error.

Files

  • src-tauri/src/commands/mod.rs:38-56 (esp. 45-49)
  • src-tauri/src/commands/mod.rs:85-109 (test_connection, esp. 92-96)
  • src/components/connection/ConnectionDialog.tsx:261 (empty-string convention)

Repro

  1. Create a profile with a password (saved to keyring).
  2. Mock or force a keyring-backend failure on get().
  3. Open the profile in edit mode → Save (without touching password).
  4. Observe: success toast, but password entry gone from keyring.

Expected

The command returns Err("Failed to read password from keyring: ..."), the keyring entry is preserved, the user sees the error and the form is preserved.

Proposed fix

Scope S. Change both if let Ok(stored) blocks to let stored = state.connection_store.get(&profile.id).map_err(|e| ... )?; so failures propagate. Apply same to test_connection. Add an integration test using db_keystore failure injection.

Acceptance

Simulated PlatformFailure on get() returns the command error to the frontend and the keyring entry is preserved.

Needs human verify

Yes (need to force a keyring failure in test env).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/connectionAudit areaauditTracks a feature-by-feature codebase audit findingkind/securityAudit finding categoryseverity/p0Audit finding severity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions