Repository: atuinsh/atuin (language: rust)

Issue:
state / credential files created with excessive permissions
(as discussed in Discord)

**Describe the bug**

Files in `.local/share/atuin/`, including keys and session tokens, are created with too-open permissions (ie, world-readable)

**To Reproduce**
Steps to reproduce the behavior:
1. Install atuin and go through the setup on a new host
2. Look at the file permissions.

**Expected behavior**
A umask set so that all files are created mode 600.  Perhaps also something to fix existing installations.

I'm not sure what the equivalent is on Windows, but that should be checked too.

**Error logs**

```text
❯ l .local/share/atuin/
total 1.1M
drwxr-xr-x  2 dan users   14 Sep 23 17:01 .
drwx------ 55 dan users   57 Sep 23 17:05 ..
-rw-r--r--  1 dan users 260K Sep 23 10:40 history.db
-rw-r--r--  1 dan users  32K Sep 23 17:13 history.db-shm
-rw-r--r--  1 dan users 2.9M Sep 23 17:13 history.db-wal
-rw-r--r--  1 dan users   32 Sep 22 21:49 host_id
-rw-r--r--  1 dan users   72 Sep 23 17:01 key
-rw-r--r--  1 dan users   35 Sep 23 17:04 last_sync_time
-rw-r--r--  1 dan users   35 Sep 23 16:59 last_version_check_time
-rw-r--r--  1 dan users    6 Sep 23 16:59 latest_version
-rw-r--r--  1 dan users  32K Sep 23 17:03 records.db
-rw-r--r--  1 dan users  32K Sep 23 17:13 records.db-shm
-rw-r--r--  1 dan users  53K Sep 22 21:49 records.db-wal
-rw-r--r--  1 dan users   32 Sep 23 17:01 session
```

In this case, the parent directory has permissions that protect everything underneath it, but we shouldn't rely on that being the case on all platforms.

**Device (please complete the following information):**
 - OS: :Linux / NixOS
 - Shell: bash/nu
 - Version: 16.0.0



Discussion / hints:
Sorry for a "mee too" post, but I'm a 5 minute Atuin user and was about to create a new issue about this. Seeing as there hasn't been any activity here I think a bump is in order.

My setup also has limited access in the parent directories, but that shouldn't be relied on (as OP says).

```
$ namei -l /home/bf/.local/share/atuin/key
f: /home/bf/.local/share/atuin/key
drwxr-xr-x root root  /
drwxr-xr-x root root  home
drwx------ bf   users bf
drwx------ bf   users .local
drwx------ bf   users share
drwxr-xr-x bf   users atuin
-rw-r--r-- bf   users key
```

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 368c8687af6..94b9386d27c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -191,6 +191,7 @@ dependencies = [
  "ratatui",
  "rpassword",
  "runtime-format",
+ "rustix",
  "semver",
  "serde",
  "serde_json",
diff --git a/Cargo.toml b/Cargo.toml
index 9aa038313e5..9dd12204ddc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -44,6 +44,7 @@ whoami = "1.1.2"
 typed-builder = "0.18.0"
 pretty_assertions = "1.3.0"
 thiserror = "1.0"
+rustix = {version = "0.38.28", features=["process", "fs"]}
 
 [workspace.dependencies.reqwest]
 version = "0.11"
diff --git a/atuin/Cargo.toml b/atuin/Cargo.toml
index 95ad677dc8d..bd7234d98ef 100644
--- a/atuin/Cargo.toml
+++ b/atuin/Cargo.toml
@@ -65,6 +65,7 @@ fs-err = { workspace = true }
 whoami = { workspace = true }
 rpassword = "7.0"
 semver = { workspace = true }
+rustix = { workspace = true }
 runtime-format = "0.1.3"
 tiny-bip39 = "1"
 futures-util = "0.3"
diff --git a/atuin/src/command/mod.rs b/atuin/src/command/mod.rs
index bcd209d690a..c76030bd755 100644
--- a/atuin/src/command/mod.rs
+++ b/atuin/src/command/mod.rs
@@ -2,6 +2,8 @@ use clap::{CommandFactory, Subcommand};
 use clap_complete::{generate, generate_to, Shell};
 use eyre::Result;
 
+use rustix::{fs::Mode, process::umask};
+
 #[cfg(feature = "client")]
 mod client;
 
@@ -46,6 +48,11 @@ pub enum AtuinCmd {
 
 impl AtuinCmd {
     pub fn run(self) -> Result<()> {
+        // set umask before we potentially open/create files
+        // or in other words, 077. Do not allow any access to any other user
+        let mode = Mode::RWXG | Mode::RWXO;
+        umask(mode);
+
         match self {
             #[cfg(feature = "client")]
             Self::Client(client) => client.run(),


Test patch: