Skip to content

fix: validate safe.directory path before writing to global git config#165

Merged
jmaxdev merged 1 commit intoTrixtyAI:mainfrom
matiaspalmac:fix/git-safe-directory-validation
Apr 21, 2026
Merged

fix: validate safe.directory path before writing to global git config#165
jmaxdev merged 1 commit intoTrixtyAI:mainfrom
matiaspalmac:fix/git-safe-directory-validation

Conversation

@matiaspalmac
Copy link
Copy Markdown
Contributor

[Fix]: Validate safe.directory path before writing to the global git config

Description

git_add_safe_directory forwarded the caller-supplied path straight to
git config --global --add safe.directory. Because the target config is
global and persistent, any junk that made it through ended up in
the user's ~/.gitconfig. The worst shape is *, which
auto-whitelists every repository on disk — from that point on any
untrusted repo opened by the user can run pre/post hooks without the
usual dubious-ownership prompt.

Change

apps/desktop/src-tauri/src/lib.rsgit_add_safe_directory now
validates before shelling out:

  • Reject empty input, *, and any value starting with - so it
    cannot be reparsed as a git flag (e.g. --global --get).
  • Path::canonicalize the input and require the result to be an
    existing directory. The only in-tree caller
    (GitExplorerComponent.tsx → "fix dubious ownership" confirmation)
    always passes the current workspace root, which is a real directory
    on disk, so legitimate usage is unchanged.
  • Strip the \\?\ verbatim prefix on Windows before handing the value
    to git config. Git writes entries in plain form and does not
    recognize the UNC-verbatim variant, so this keeps the config entry
    readable and matches what the user saw in the UI confirmation.

The user-facing confirmation dialog in GitExplorerComponent already
shows the exact path being added; canonicalization now makes that
dialog match what actually lands in the global config instead of
whatever string the frontend happened to send.

Trade-offs

  • Enforcing canonical == workspace_root as suggested in the issue
    would require threading the workspace root through an extra Tauri
    command argument, and the frontend can trivially fake it anyway.
    The real defense — "the value must be a real directory, not a
    wildcard or flag" — is applied here. A deeper workspace-scoping
    check is out of scope for this security fix.
  • Non-existent paths now fail loudly instead of silently being
    written to global config. The one legitimate caller always passes
    an existing directory, so no behavior changes for the happy path.

Verification

  • cargo check and cargo clippy -- -D warnings on src-tauri → clean.
  • Manual trace of the validation branches:
    • ""safe.directory path is empty.
    • "*" → refused with the wildcard-specific message.
    • "--global" → refused for leading -.
    • "/path/that/does/not/exist" → canonicalize error.
    • "C:\\path\\to\\a\\file.txt"must be a directory.
    • Current workspace root → canonicalized, UNC-verbatim prefix
      stripped, written to global config (matches previous behavior).

Related Issue

Fixes #57

Checklist

  • I have tested this on the latest version.
  • I have followed the project's coding guidelines.
  • My changes generate no new warnings or errors.
  • I have verified the fix on:
    • OS: Windows
    • Version: v1.0.10

Copilot AI review requested due to automatic review settings April 21, 2026 02:25
@github-actions
Copy link
Copy Markdown

Thanks for the contribution! I'll review it as soon as possible. If you have still changes, please mark this PR as draft and all reviews will be cancelled. Tests reviews will be re-run only when the PR is marked as ready for review.

@github-actions github-actions bot added the bug Something isn't working label Apr 21, 2026
Copy link
Copy Markdown

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

This PR hardens the Tauri backend command that adds safe.directory entries to the user’s global git config by validating and normalizing the provided path before invoking git config --global --add.

Changes:

  • Rejects unsafe safe.directory values (empty, *, and leading -).
  • Canonicalizes the path and requires it to be an existing directory.
  • Attempts to normalize Windows verbatim (\\?\) paths before writing to git config.

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

Comment thread apps/desktop/src-tauri/src/lib.rs
git_add_safe_directory forwarded the caller-supplied path straight to
`git config --global --add safe.directory`. Because the target config is
global and persistent, any junk that made it through — most dangerously
the `*` wildcard — auto-whitelisted every repository on disk, meaning
any repo opened afterwards could run its pre/post hooks without the
usual dubious-ownership prompt.

Validation added before shelling out:

- Reject empty input, `*`, and any value starting with `-` (so it can't
  be reparsed as a git flag like `--global --get`).
- `Path::canonicalize` the path and require it to be an existing
  directory. The frontend only ever calls this with the current
  workspace root, which is a real directory on disk, so legitimate
  usage is unchanged.
- Strip the `\\?\` verbatim prefix on Windows before handing the value
  to `git config`, since git stores entries in plain form and doesn't
  recognize the UNC-verbatim variant.

The user-facing confirmation dialog in GitExplorerComponent already
shows the path being added; canonicalization now makes that dialog
match what actually lands in the global config.
@jmaxdev jmaxdev force-pushed the fix/git-safe-directory-validation branch from a515475 to 974a71a Compare April 21, 2026 03:24
@jmaxdev jmaxdev merged commit 0e0aeeb into TrixtyAI:main Apr 21, 2026
1 check passed
matiaspalmac added a commit to matiaspalmac/ide that referenced this pull request Apr 21, 2026
Addresses review feedback on TrixtyAI#165: on Windows, canonicalize() returns
\\?\UNC\server\share\... for network shares. The previous strip of
just \\?\ turned that into UNC\server\share\..., which is not a valid
Windows path and would land in the user's global git config as
garbage — git would then read "safe.directory = UNC\server\share\..."
and never match the real repo. Map \\?\UNC\... back to
\\server\share\... and keep the simple strip for drive-letter paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix]: git_add_safe_directory accepts arbitrary path and writes to global git config

3 participants