summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames O'Doherty <james@theodohertyfamily.com>2026-06-07 21:51:48 -0400
committerJames O'Doherty <james@theodohertyfamily.com>2026-06-07 21:51:48 -0400
commit7010768877c227c9410a06908e4cb3e54db403bd (patch)
tree317512603d9358b272240d53ea4b09b1b81eacd3
parent184deac4efe2062db6ecd2285ec8db1e919f9441 (diff)
security: restrict permissions of imported WireGuard profiles to 0600
WireGuard profile files contain sensitive private keys. Previously, these files were written with 0644 permissions, making them world-readable. This commit changes the file mode to 0600 to ensure only the owner can read and write the profiles. - Updated `handleProfileImport` to use 0600 permissions. - Added tests to verify that imported profiles have the correct permissions.
-rw-r--r--internal/cli/cli.go2
-rw-r--r--internal/cli/profile_test.go17
2 files changed, 17 insertions, 2 deletions
diff --git a/internal/cli/cli.go b/internal/cli/cli.go
index a4b9a9a..d100d4f 100644
--- a/internal/cli/cli.go
+++ b/internal/cli/cli.go
@@ -324,7 +324,7 @@ func (a *App) handleProfileImport(srcPath string, name string) error {
return fmt.Errorf("failed to read source file: %w", err)
}
- if err := os.WriteFile(destPath, data, 0644); err != nil {
+ if err := os.WriteFile(destPath, data, 0600); err != nil {
return fmt.Errorf("failed to write profile to %s: %w", destPath, err)
}
diff --git a/internal/cli/profile_test.go b/internal/cli/profile_test.go
index e08ffc5..d373e95 100644
--- a/internal/cli/profile_test.go
+++ b/internal/cli/profile_test.go
@@ -50,11 +50,19 @@ func TestProfileImport(t *testing.T) {
t.Errorf("expected no error, got %v", err)
}
- // Verify the file was actually copied to derived name
+ // Verify the file was actually copied to derived name and has correct permissions
destFile := filepath.Join(profilesDir, "source.conf")
if _, err := os.Stat(destFile); os.IsNotExist(err) {
t.Errorf("expected profile to be imported to %s", destFile)
}
+ var info os.FileInfo
+ info, err = os.Stat(destFile)
+ if err != nil {
+ t.Fatalf("failed to stat imported profile: %v", err)
+ }
+ if info.Mode().Perm() != 0600 {
+ t.Errorf("expected imported profile to have permissions 0600, got %o", info.Mode().Perm())
+ }
// 2. Test importing with explicit name argument
customName := "custom-vpn"
@@ -70,6 +78,13 @@ func TestProfileImport(t *testing.T) {
if _, err := os.Stat(destCustomFile); os.IsNotExist(err) {
t.Errorf("expected profile to be imported to %s", destCustomFile)
}
+ info, err = os.Stat(destCustomFile)
+ if err != nil {
+ t.Fatalf("failed to stat imported profile: %v", err)
+ }
+ if info.Mode().Perm() != 0600 {
+ t.Errorf("expected imported profile to have permissions 0600, got %o", info.Mode().Perm())
+ }
// 3. Test duplicate import (should fail)
appDup := NewApp([]string{"wg-wrap", "profile", "import", srcFile, customName})