Skip to content

Save the private key and setup config files with owner-only permissions - #223

Merged
aharoitx merged 2 commits into
bitpay:6.0.xfrom
aharoitx:fix/im194-key-file-permissions
Oct 15, 2026
Merged

aharoitx merged 2 commits into
bitpay:6.0.xfrom
aharoitx:fix/im194-key-file-permissions

Conversation

@aharoitx

@aharoitx aharoitx commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

KeyUtils.SaveEcKey saved the private key with the default permissions. On Linux and macOS that is usually mode 0644, so any local user could read the key. The setup tool saved BitPay.config.json the same way. That file holds the API tokens, and the private key too when the "plain text" option is used.

On Linux and macOS (.NET 7 or later), both files are now saved with mode 0600 (only the owner can read and write).

On Windows, files get their permissions from the folder (NTFS ACLs), not from a mode, so nothing changes there. The same goes for .NET Framework 4.8, which only runs on Windows.

Changes

  • KeyUtils: new private helper CreateOwnerOnlyFile, used by SaveEcKey. It creates the file with UnixCreateMode = 0600. If the file already exists, it is changed to 0600 before it is overwritten, because the create mode only applies to new files. The code is inside #if NET7_0_OR_GREATER and !OperatingSystem.IsWindows(), so it still builds for net48 and passes the platform analyzer (CA1416).
  • BitPaySetup: BitPay.config.json is written the same way.
  • New KeyUtilsTest. It shares an xUnit collection with ClientTest, because both change the key path that KeyUtils keeps in a static field, and they must not run in parallel.

Testing

  • The new tests fail on 6.0.x (mode 0644) and pass with this change.
  • dotnet build -f net8.0: no errors, no new warnings.
  • dotnet test BitPayUnitTest -f net8.0: 59 passed.

Jira: IM-194

KeyUtils.SaveEcKey wrote the private key with the default permissions.
On Linux and macOS that is usually mode 0644, so any local user could
read the key.

On .NET 7 or later, on Linux and macOS, the file is now created with
mode 0600, and an existing file is changed to 0600 before it is
overwritten. On Windows and on .NET Framework the file keeps the
permissions it inherits from its folder, as before.

KeyUtilsTest and ClientTest share a test collection, because both
change the key path that KeyUtils keeps in a static field.
The setup tool wrote BitPay.config.json with the default permissions
(usually mode 0644 on Linux and macOS). The file holds the API tokens,
and with the "plain text" option it also holds the private key.

It is now written the same way as the private key file: mode 0600 on
Linux and macOS with .NET 7 or later.
@aharoitx
aharoitx merged commit 80d08a5 into bitpay:6.0.x Oct 15, 2026
3 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.

2 participants