Skip to content

Conversation

@tnull
Copy link
Collaborator

@tnull tnull commented Jan 7, 2026

Previously, seed files were created using fs::File::create() which inherits the default umask, potentially making the sensitive seed material world-readable on Unix systems.

This change:

  • Creates seed files with mode 0o600 (owner read/write only) on Unix
  • Uses create_new instead of create to atomically fail if the file already exists, providing defense-in-depth against TOCTOU race conditions

Co-Authored-By: Claude AI

@tnull tnull requested a review from benthecarman January 7, 2026 10:31
@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Jan 7, 2026

👋 Thanks for assigning @tankyleo as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

src/io/utils.rs Outdated
// to protect the sensitive seed material. We use `create_new` to fail if the
// file already exists, providing defense-in-depth against race conditions.
#[cfg(unix)]
let mut f = { OpenOptions::new().write(true).create_new(true).mode(0o600).open(keys_seed_path)? };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer we set permissions here to 0400 to protect against accidental writes. Once the seed file is created there really shouldn't be a reason to write anything to the file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair:

> git diff-tree -U2 af77366c 7e2f1fa9
diff --git a/src/io/utils.rs b/src/io/utils.rs
index 47b408e2..965831aa 100644
--- a/src/io/utils.rs
+++ b/src/io/utils.rs
@@ -86,5 +86,5 @@ pub(crate) fn read_or_generate_seed_file(
                // file already exists, providing defense-in-depth against race conditions.
                #[cfg(unix)]
-               let mut f = { OpenOptions::new().write(true).create_new(true).mode(0o600).open(keys_seed_path)? };
+               let mut f = { OpenOptions::new().write(true).create_new(true).mode(0o400).open(keys_seed_path)? };

                #[cfg(not(unix))]

@tnull tnull force-pushed the 2026-01-stricter-seed-file-permissions branch from af77366 to 7e2f1fa Compare January 8, 2026 09:30
@tnull tnull requested a review from tankyleo January 8, 2026 09:31
Copy link

@tankyleo tankyleo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM two nits

Previously, seed files were created using `fs::File::create()` which
inherits the default umask, potentially making the sensitive seed
material world-readable on Unix systems.

This change:
- Creates seed files with mode 0o400 (owner read only) on Unix
- Uses `create_new` instead of `create` to atomically fail if the file
  already exists, providing defense-in-depth against TOCTOU race
  conditions

Co-Authored-By: Claude AI
@tnull tnull force-pushed the 2026-01-stricter-seed-file-permissions branch from 7e2f1fa to e93844a Compare January 9, 2026 09:05
@tnull tnull requested a review from tankyleo January 9, 2026 09:05
@tnull tnull merged commit 4ad1304 into lightningdevkit:main Jan 9, 2026
13 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants