Skip to content

Harden unsafe Git option validation#2180

Merged
Byron merged 3 commits into
mainfrom
single-char-kwarg
Jul 22, 2026
Merged

Harden unsafe Git option validation#2180
Byron merged 3 commits into
mainfrom
single-char-kwarg

Conversation

@Byron

@Byron Byron commented Jul 22, 2026

Copy link
Copy Markdown
Member

Tasks

This section is for Byron only. Models continuing this PR must not add, remove, check, uncheck, rename, or reorder checkboxes here.

  • refackiew

Everything below this line was generated by Codex GPT-5.

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Summary

Harden GitPython's unsafe-option validation against three high-severity advisories affecting GitPython <= 3.1.53:

  • GHSA-r9mr-m37c-5fr3: prevent split single-character keyword values from smuggling unsafe option tokens.
  • GHSA-6p8h-3wgx-97gf: reject caller-controlled clone templates by default because they can install executable hooks.
  • GHSA-fjr4-x663-mwxc: reject diff output options before revision parsing or Git invocation to prevent arbitrary file overwrite.

No CVEs or patched release versions are assigned yet.

Changes

  • Validate option-like values emitted when single-character kwargs are split.
  • Add --template to the unsafe clone-option denylist.
  • Add allow_unsafe_options=False to commit/tree/index diff paths and consistently guard --output/-o.
  • Preserve explicit opt-in behavior with allow_unsafe_options=True.
  • Add regression coverage for each bypass and affected call path.

Validation

  • Focused Python 3.12 security tests: 3 passed.
  • Ruff lint and formatting: passed.
  • Mypy: passed.
  • Full pre-commit suite: passed.
  • Full Python 3.12 suite: 667 passed, 75 skipped, 35 unrelated fixture/environment failures caused by uninitialized nested test submodules and local Git defaults.

Git behavior was checked against baseline a23bace9.

Copilot AI review requested due to automatic review settings July 22, 2026 02:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 GitPython’s unsafe Git option validation to block additional high-risk option spellings and close bypasses where unsafe options could be smuggled via argument transformation, while preserving explicit opt-in via allow_unsafe_options=True.

Changes:

  • Extend Git._option_candidates() to include option-like values emitted by split single-character kwargs, so unsafe-option checks cover those tokens too.
  • Add --template to the clone unsafe-option denylist to prevent hook installation during clone by default.
  • Add allow_unsafe_options gating and unsafe-option checks to diff call paths (commit/tree/index) to reject --output/-o unless explicitly allowed, with regression tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
git/cmd.py Expands option-candidate detection to include split single-char kwarg values that look like options.
git/repo/base.py Adds --template to unsafe_git_clone_options and documents why it’s unsafe.
git/diff.py Adds allow_unsafe_options and blocks unsafe revision/output options prior to diff invocation.
git/index/base.py Adds allow_unsafe_options to index diff and enforces unsafe-option checks; propagates flag through delegated diff calls.
test/test_git.py Adds regression tests ensuring split single-char kwarg values are included in unsafe-option candidate detection.
test/test_diff.py Adds regression tests ensuring diff output options are rejected by default and allowed only with explicit opt-in.
test/test_clone.py Extends clone unsafe-option tests to cover --template and template=....

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

codex and others added 3 commits July 22, 2026 05:54
<!-- agent -->

Single-character keyword arguments are transformed into an option token and
a separate value token. The unsafe-option candidate builder only checked the
keyword name, allowing an option-like value to bypass guards shared by clone,
remote, revision, blame, and archive operations.

Include dash-prefixed values only when short options are actually split,
including sequence values, while preserving bare values and the non-splitting
compatibility path.

Git baseline a23bace9 defines clone -n and --upload-pack as distinct options,
matching the argv boundary this validation now preserves.

Refs GHSA-r9mr-m37c-5fr3.

Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
<!-- agent -->

Treat git clone --template as unsafe because caller-controlled
templates can install hooks that execute during clone.

Add regression coverage for both direct option and keyword forms.

References GHSA-6p8h-3wgx-97gf.
Validated against Git baseline a23bace9.

Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
<!-- agent -->

Reject unsafe diff options before revision parsing or Git invocation so
callers cannot write command output to arbitrary filesystem paths.

Cover commit and index diffs, including option-like revisions, and
preserve an explicit allow_unsafe_options escape hatch.

References GHSA-fjr4-x663-mwxc.
Validated against Git baseline a23bace9.

Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
@Byron
Byron force-pushed the single-char-kwarg branch from 040de4b to 1d51b89 Compare July 22, 2026 03:56
Copilot AI review requested due to automatic review settings July 22, 2026 03:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@Byron
Byron merged commit a4dc70d into main Jul 22, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants