Skip to content

Harden config directory creation permissions to 0700#25

Merged
Balaji01-4D merged 6 commits intomainfrom
copilot/fix-world-writable-config-directory
Apr 4, 2026
Merged

Harden config directory creation permissions to 0700#25
Balaji01-4D merged 6 commits intomainfrom
copilot/fix-world-writable-config-directory

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 4, 2026

  • Inspect current branch state and review comments
  • Revert unrelated dependency changes in go.mod/go.sum to keep scope focused
  • Rename path/filepath alias in config tests for clarity
  • Run targeted and full tests to validate changes
  • Run final validation and reply to new PR comments

Copilot AI and others added 2 commits April 4, 2026 04:08
Agent-Logs-Url: https://github.com/Balaji01-4D/pgxcli/sessions/f462ef04-e39b-4665-b035-3987b6e3921b

Co-authored-by: Balaji01-4D <172587380+Balaji01-4D@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix config directory permissions to prevent local tampering Harden config directory creation permissions to 0700 Apr 4, 2026
Copilot AI requested a review from Balaji01-4D April 4, 2026 04:09
@Balaji01-4D Balaji01-4D marked this pull request as ready for review April 4, 2026 04:47
Copilot AI review requested due to automatic review settings April 4, 2026 04:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Security hardening to ensure user config parent directories are created with restrictive permissions when bootstrapping the default config.

Changes:

  • Change SaveConfig to create parent directories with mode 0700 instead of os.ModePerm.
  • Add a test asserting restrictive permissions when saving into a nested config path.
  • Run go mod tidy-like dependency cleanup reflected in go.mod/go.sum.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
internal/config/config.go Uses os.MkdirAll(dir, 0o700) to create private config directories.
internal/config/config_test.go Adds a permissions-focused test for nested config saves.
go.mod Removes/reclassifies some dependencies (unrelated to config perms).
go.sum Updates checksums consistent with dependency changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +50 to +60
func TestSaveConfig_CreatesDirWithRestrictivePermission(t *testing.T) {
tempDir := t.TempDir()
configPath := path.Join(tempDir, "nested", "config.toml")

err := SaveConfig(configPath)
assert.NoError(t, err)

info, err := os.Stat(path.Dir(configPath))
assert.NoError(t, err)
assert.Equal(t, os.FileMode(0o700), info.Mode().Perm())
}
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

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

This permission assertion will be unreliable on Windows (and some non-POSIX filesystems), where os.MkdirAll permission bits are ignored and os.Stat(...).Mode().Perm() is synthesized (often reporting 0777). Since CI runs go test on windows-latest, this test is likely to fail there. Consider skipping this test on Windows (e.g., via runtime.GOOS) and/or asserting only that group/other bits are not set instead of strict equality to 0700 (to be resilient to unusual umask/filesystem behavior).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback. skip for the windows

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied. The permission test now skips on Windows using runtime.GOOS == "windows" to avoid unreliable mode-bit assertions there. Commit: c41a4d3.

Comment thread go.mod
Comment on lines 5 to 15
require (
github.com/BurntSushi/toml v1.6.0
github.com/balaji01-4d/pgxspecial v0.2.1
github.com/fatih/color v1.19.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/jedib0t/go-pretty/v6 v6.7.9
github.com/jedib0t/go-prompter v0.1.0
github.com/mattn/go-runewidth v0.0.22
github.com/muesli/termenv v0.16.0
github.com/olekukonko/tablewriter v1.1.4
github.com/pganalyze/pg_query_go/v6 v6.2.2
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

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

The PR description says the scope is limited to internal/config/config.go, but this PR also includes dependency graph changes in go.mod/go.sum (e.g., removing olekukonko/tablewriter and reclassifying some dependencies as indirect). Please either update the PR description to mention the go mod tidy/dependency cleanup, or split these dependency changes into a separate PR to keep the security hardening change focused.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. I restored go.mod and go.sum to the pre-7b879c0 state so this PR stays focused on config permission hardening. Commit: 7972728.

Comment on lines +50 to +58
func TestSaveConfig_CreatesDirWithRestrictivePermission(t *testing.T) {
tempDir := t.TempDir()
configPath := path.Join(tempDir, "nested", "config.toml")

err := SaveConfig(configPath)
assert.NoError(t, err)

info, err := os.Stat(path.Dir(configPath))
assert.NoError(t, err)
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

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

Using the import alias path for the path/filepath package (and then calling path.Join/path.Dir) is easy to confuse with the standard library path package, especially as this file grows. Consider importing path/filepath as filepath (or without an alias) for clarity.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. I replaced the path/filepath alias with filepath and updated usages in internal/config/config_test.go for clarity. Commit: 7972728.

Agent-Logs-Url: https://github.com/Balaji01-4D/pgxcli/sessions/b0931183-9ab3-432c-a30a-e914aa3f8cb4

Co-authored-by: Balaji01-4D <172587380+Balaji01-4D@users.noreply.github.com>
Copilot AI and others added 2 commits April 4, 2026 05:05
Agent-Logs-Url: https://github.com/Balaji01-4D/pgxcli/sessions/f357908d-e7a4-4e2d-8299-f09bac877e53

Co-authored-by: Balaji01-4D <172587380+Balaji01-4D@users.noreply.github.com>
…8d-e7a4-4e2d-8299-f09bac877e53

Co-authored-by: Balaji01-4D <172587380+Balaji01-4D@users.noreply.github.com>
@Balaji01-4D Balaji01-4D merged commit 8954a81 into main Apr 4, 2026
3 checks passed
@Balaji01-4D Balaji01-4D deleted the copilot/fix-world-writable-config-directory branch April 4, 2026 05:43
@Balaji01-4D Balaji01-4D restored the copilot/fix-world-writable-config-directory branch April 4, 2026 05:43
@Balaji01-4D Balaji01-4D deleted the copilot/fix-world-writable-config-directory branch April 4, 2026 05:43
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.

Config directory created with world-writable mode

3 participants