Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions internal/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func LoadFromFile(configPath string) (*Config, error) {
}

// Create data directory if it doesn't exist
if err := os.MkdirAll(cfg.DataDir, 0755); err != nil {
if err := os.MkdirAll(cfg.DataDir, 0700); err != nil {
return nil, fmt.Errorf("failed to create data directory %s: %w", cfg.DataDir, err)
}

Expand Down Expand Up @@ -91,7 +91,7 @@ func Load() (*Config, error) {
}

// Create data directory if it doesn't exist
if err := os.MkdirAll(cfg.DataDir, 0755); err != nil {
if err := os.MkdirAll(cfg.DataDir, 0700); err != nil {
return nil, fmt.Errorf("failed to create data directory %s: %w", cfg.DataDir, err)
}

Expand Down Expand Up @@ -124,7 +124,7 @@ func Load() (*Config, error) {
}

// Create data directory if it doesn't exist
if err := os.MkdirAll(cfg.DataDir, 0755); err != nil {
if err := os.MkdirAll(cfg.DataDir, 0700); err != nil {
return nil, fmt.Errorf("failed to create data directory %s: %w", cfg.DataDir, err)
}

Expand Down Expand Up @@ -350,7 +350,7 @@ func SaveConfig(cfg *Config, path string) error {

// Ensure directory exists
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
if err := os.MkdirAll(dir, 0700); err != nil {
fmt.Printf("[DEBUG] SaveConfig - MkdirAll failed: %v\n", err)
return fmt.Errorf("failed to create config directory: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/runtime/apply_config_restart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func TestApplyConfig_SaveFailure(t *testing.T) {
err = os.Chmod(tmpDir, 0555)
require.NoError(t, err)
defer func() {
_ = os.Chmod(tmpDir, 0755)
_ = os.Chmod(tmpDir, 0700)
}()

// Create new config
Expand Down
38 changes: 32 additions & 6 deletions internal/server/listener_permissions_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,38 @@ func validateDataDirectoryPermissionsPlatform(dataDir string, info os.FileInfo,
// Unix: Check permissions are secure (0700 or stricter)
perm := info.Mode().Perm()
if perm&0077 != 0 {
return fmt.Errorf(
"data directory has insecure permissions %#o, must be 0700 or stricter\n"+
"Security risk: Other users can access mcpproxy data and control socket\n"+
"To fix, run: chmod 0700 %s",
perm, dataDir,
)
logger.Warn("Data directory has insecure permissions; attempting automatic repair",
zap.String("path", dataDir),
zap.String("current_permissions", fmt.Sprintf("%#o", perm)))

if err := os.Chmod(dataDir, 0700); err != nil {
return fmt.Errorf(
"data directory has insecure permissions %#o, must be 0700 or stricter\n"+
"automatic repair failed: %w\n"+
"Security risk: Other users can access mcpproxy data and control socket\n"+
"To fix manually, run: chmod 0700 %s",
perm, err, dataDir,
)
}

updatedInfo, err := os.Stat(dataDir)
if err != nil {
return fmt.Errorf("failed to recheck data directory after permission repair: %w", err)
}
perm = updatedInfo.Mode().Perm()
if perm&0077 != 0 {
return fmt.Errorf(
"data directory remains with insecure permissions %#o even after automatic repair, must be 0700 or stricter\n"+
"Security risk: Other users can access mcpproxy data and control socket\n"+
"To fix manually, run: chmod 0700 %s",
perm, dataDir,
)
}

logger.Info("Data directory permissions tightened automatically",
zap.String("path", dataDir),
zap.String("permissions", fmt.Sprintf("%#o", perm)))
return nil
}

logger.Info("Data directory security validation passed",
Expand Down
8 changes: 5 additions & 3 deletions internal/server/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,11 @@ func TestValidateDataDirectory_InsecurePermissions(t *testing.T) {
require.NoError(t, err)

err = ValidateDataDirectory(tmpDir, logger)
assert.Error(t, err)
assert.Contains(t, err.Error(), "insecure permissions")
assert.Contains(t, err.Error(), "chmod 0700")
require.NoError(t, err)

info, statErr := os.Stat(tmpDir)
require.NoError(t, statErr)
assert.Equal(t, os.FileMode(0700), info.Mode().Perm(), "validate should tighten permissions automatically")
}

func TestValidateDataDirectory_CreateIfNotExists(t *testing.T) {
Expand Down
Loading