GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — various fixes by Byron · Pull Request #2258 · gitpython-developers/GitPython

Conversation

@Byron

@Byron Byron commented Sep 30, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Tasks

  • refackiew
  • new release - let's have another fix.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@Byron
Byron force-pushed the sec-audit branch 4 times, most recently from ddc9efb to 7cd2cd4 Compare September 30, 2026 04:08
codex added 8 commits September 30, 2026 08:33
@codex @Byron
refactor(db): deprecate the pure-Python GitDB backend
0b64501
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
The pure-Python `GitDB` backend has performance and security issues in
object reading and resolution, including unbounded delta processing and
incorrect object selection or reconstruction. `GitCmdObjectDB` is already
the default and delegates these operations to Git.

Emit `DeprecationWarning` from `Repo.__init__` when `odbt` selects `GitDB`
or a subclass, directing callers to `GitCmdObjectDB`. Repository opening,
initialization, and cloning all construct a `Repo` through this path.
Keep the existing backend behavior available for compatibility and retain
the `gitdb` dependency needed for shared types and utilities. Deprecation
does not repair or disable the legacy parsers.

Update backend-selection docstrings, the tutorial, and the changelog with
migration guidance. Add regression checks that the deprecated backend and
its subclasses warn at the direct caller's location while continuing to
read objects, and that default, explicit, and subclassed `GitCmdObjectDB`
use remains free of deprecation warnings.

CI follow-up: the new deprecation test exposed that backend annotations
accepted only `LooseObjectDB` descendants, excluding the supported legacy
`GitDB`. Include both types in construction, initialization, and clone
helpers. `basedpyright --warnings` and `mypy --python-version=3.12` pass;
16 focused deprecation/database tests and Ruff checks pass.
@codex @Byron
fix(repo): delegate revision message searches to Git
3ca35bf
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
Python evaluated user-supplied `:/pattern` and `^{/pattern}` searches
with a backtracking regex engine and walked/deserialized history itself.
A short expression could occupy a worker indefinitely on an ordinary
repository (finding 21500).

Delegate matching and traversal to `git rev-parse`, using its extended
regular expressions, and delete the Python regex/history implementation.
Construct fixed-prefix operands so they cannot become options, preserving
support for Git versions without `--end-of-options`. Invalid expressions
now raise `BadName`, like searches without a match.

Resolve revisions before peeling objects in `Repo.commit()` and
`Repo.tree()`; appending a peel suffix previously changed top-level search
patterns. Add bounded subprocess regressions, native-Git parity cases,
and checks that history is not deserialized in Python.

Validation: 27 focused/related tests and Ruff checks passed. A 56-case
comparison preserved previously successful ordinary revision resolutions.
Native behavior was checked against Git and its local source at
`d38352cd43`.
@codex @Byron
fix(refs): bound symbolic reference resolution and updates
c99207e
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
Cyclic loose symbolic refs could keep `dereference_recursive()` reading
forever. Related updates and construction of custom symbolic refs could
recurse without a useful limit (finding 21496).

Bound reads and preflight updates to five references, including the
terminal reference, matching Git's `SYMREF_MAXDEPTH`. Determine detachment
from the current ref's contents without recursively constructing targets.
Reuse validated ref paths for reads to reject escaping symlinks.

Preserve public update signatures and subclass dispatch, including HEAD
reflog updates and creation of unborn terminal references. The write
preflight handles static chains; it does not introduce a transaction for
concurrent external repository changes.
@codex @Byron
fix(cmd): reject the alternate ext:// helper selector
9e8c85e
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
The shared unsafe-protocol check rejected forced `<helper>::` selectors,
but Git also selects `git-remote-ext` for `ext://` URLs. That helper treats
the URL as a command path, leaving a second spelling outside the guard.
This is a sibling of finding 21492, whose original missing `ls_remote`
check was already fixed by `9ad28cc4`.

Extend the existing anchored classifier to reject `ext://` too. Preserve
native case sensitivity, ordinary IPv6 URLs, forced-helper checks, and
the explicit `allow_unsafe_protocols` opt-in across all callers.
@codex @Byron
fix(repo): validate rendered archive remote options
428d205
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
`Repo.archive()` checked only the original `remote` keyword. Git accepts
abbreviated long options, while GitPython renders sequence values as
repeated options and permits a value embedded in the keyword name.
Those spellings could bypass unsafe-protocol validation (finding 21492's
broader URL-validation class).

Inspect the arguments produced by the existing `Git.transform_kwargs()`
and validate every emitted `--remote` value, including its abbreviations,
with the shared protocol checker. Preserve safe repeated IPv6 URLs and
keep unsafe-option and unsafe-protocol opt-ins independent.
@codex @Byron
fix(index): validate paths at native index boundaries
a75aedf
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
Native tree merging and index serialization could install paths that Git's
own index writers reject. A subsequent checkout trusts that index and can
write outside the working tree or into Git metadata (finding 21506 and
the shared write-side cause of finding 21501).

Validate complete paths when importing tree entries, reading or writing
index entries, and building trees from the index. Reject traversal,
absolute/drive paths, embedded NULs, and Git metadata aliases on NTFS/HFS
while retaining ordinary POSIX filename characters. Validate before
creating trees, and preserve index writer rollback on failure.

Refresh the on-disk index before checkout, including when entries were
cached. Parse full sentinel-length names and check their terminators and
padding so validation sees the same paths as Git. Reject unsupported
mandatory extensions such as split indexes: validating only their inline
entries would overlook paths from external shared indexes.

QA review follow-up: reject unsupported index versions with an explicit
exception, preserving `AssertionError` for compatibility. Python's `-O`
mode removed the former assertion, allowing version 4 prefix-compressed
paths to be parsed with version 2/3 rules before native checkout.
Validation must never accept a format whose paths Git interprets
differently. Optimized subprocess regressions for unsupported versions
fail before this fix and pass afterward. All 76 selected index tests
pass, with two platform skips; locked Basedpyright, mypy, Codespell, and
Ruff checks pass.
@codex @Byron
fix(tree): validate entry names and record boundaries
d1576c4
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
`TreeModifier.add()` checked only for slashes in names. Embedded NULs
could change serialized record boundaries, while dot components and Git
metadata aliases produced unsafe tree paths (finding 21507).

Reuse the repository path validator for single-component tree names and
check both the public modifier and shared serializer. Validate object ID
lengths and object modes at serialization, including entries inserted
through unchecked or direct-cache APIs.

Validate incoming records in `tree_entries_from_data()` as well: use
bounded delimiter searches, require octal modes and complete 20-byte
object IDs, and reject invalid names before exposing entries. Preserve
`bytearray` inputs, immutable returned object IDs, undecodable filenames,
and valid whitespace, Unicode, and POSIX backslash and colon names. Check
drive/root restrictions on complete paths, not isolated tree components.
Update the existing decoding fixture to contain a complete object ID.
@codex @Byron
fix(index): confine staging reads to worktree files
f2dfa9f
<!-- Byron -->
rubber-stamp, after checking diff quickly.

<!-- agent -->
`IndexFile.add()` could read through intermediate directory symlinks and
store files outside the working tree. Null-SHA `Blob` and
`BaseIndexEntry` inputs reached the same reader, while unsafe entry and
rewritten paths could enter the in-memory index with `write=False`
(finding 21501).

Validate supplied object paths and all final entry paths with the shared
repository path checker. Confine filesystem inputs in `_store_path()`
and reject intermediate symlinks or redirected directories before
opening files. Preserve final symlinks as links, including when rewriting
paths, and reject special files. Use `O_NOFOLLOW` and `O_NONBLOCK` where
available and check the opened regular file with `fstat()`.

Skip Git metadata during directory expansion and stage directory
symlinks themselves. Validate complete relative directory paths so nested
POSIX colon names are not mistaken for drive-prefixed paths.

Parent-directory checks handle the existing filesystem layout; they do
not make staging atomic against concurrent directory replacement. The
open flags protect final-component substitution on supporting platforms.

Tests cover path/glob/object inputs, inside and outside symlink targets,
rewriters, in-memory index validation, metadata exclusion, directory
symlinks, special files, and nested colon names. Validation: 129 combined
tree/index tests passed, with two platform skips; Ruff checks and
formatting checks passed.
@Byron
Byron force-pushed the sec-audit branch from 7cd2cd4 to f2dfa9f Compare September 30, 2026 07:37
codex added 2 commits September 30, 2026 09:40
@codex @Byron
ci: remove codespell checks and configuration
cc02e45
<!-- Byron -->
Reason: it triggered quite often, is an external dependency
that isn't crucial, and... spelling issues aren't a problem
that GitPython really needs to solve.

rubber-stamp, after checking diff quickly.

<!-- agent -->
Remove `codespell` from the project's pre-commit checks so it no longer
runs locally or in the shared CI lint workflow. This also removes the
need to maintain spelling exceptions for intentional test inputs.

Delete its hook-specific `tomli` dependency, the entire `[tool.codespell]`
configuration and word exception list, and the obsolete inline suppression
on the `remot` archive-option regression case.
@codex @Byron
fix(remote): validate protocols in rendered transport arguments
1a2117c
<!-- Byron -->

Rubber-stamp, checked diff

<!-- agent -->
`Remote.fetch()`, `pull()`, and `push()` checked only their refspecs for
unsafe protocols. A split short-option value such as `q="ext::helper"`
was rendered as `-q ext::helper`, making it Git's repository operand before
the intended remote. This bypassed `allow_unsafe_protocols=False` wherever
Git's own protocol policy permitted the helper.

Share protocol validation with `Git.ls_remote()` using flattened operands
and the existing `transform_kwargs()` renderer. Check the remote name as
well as refspecs and standalone option values. Repeated values now receive
the same checks, while joined short values and ordinary long-option values
retain their existing treatment. Keep the unsafe-option and unsafe-protocol
opt-ins independent.

Render fetch's documented boolean `verbose` parameter as a boolean flag.
Its previous unchecked `v=verbose` conversion could introduce another URL
or an unsafe option outside either guard.

Add public-API regressions for all three transports, repeated values,
unsafe remote names, safe argument forms, and the independent opt-ins.
The split-value and `verbose` regressions failed before their fixes. Git
execution is intercepted in these tests.
@Byron
Byron force-pushed the sec-audit branch from ce5012d to 1a2117c Compare September 30, 2026 08:33
@Byron
Byron marked this pull request as ready for review September 30, 2026 09:03
Copilot AI balanced review requested due to automatic review settings September 30, 2026 09:03
Copilot started reviewing on behalf of Byron September 30, 2026 09:04
View session
@Byron
Byron merged commit a3e1ea4 into main Sep 30, 2026
51 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@Byron
Byron deleted the sec-audit branch September 30, 2026 09:06
Copilot AI reviewed Sep 30, 2026
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Race-prone staging validation and an unprotected packed-reference fallback leave security boundaries incomplete.

Review effort: Balanced
Findings: 2 High severity · 2 Medium severity · 1 Low severity

Open (5)
  • High severity TOCTOU race allows staging files outside the worktree · New
  • High severity Packed refs bypass containment checks via symlinked packed-refs · New
  • Medium severity Malformed refs raise unexpected exceptions instead of ValueError · New
  • Medium severity Deprecation warning points to internal calls through public APIs · New
  • Low severity Shared validator reports an index-specific error for tree entries · New
What changed in this PR

Hardens repository parsing and command execution while deprecating the pure-Python GitDB backend.

Changes:

  • Validates tree, index, staging, and symbolic-reference paths.
  • Strengthens protocol guards and native revision-message searches.
  • Adds regression tests and GitDB deprecation documentation.
File Description
git/​util.py Adds repository-path validation.
git/​index/​base.py Hardens staging and checkout.
git/​index/​fun.py Validates index parsing and serialization.
git/​objects/​fun.py Validates tree records.
git/​objects/​tree.py Validates modified tree entries.
git/​refs/​symbolic.py Bounds and validates symbolic-reference traversal.
git/​cmd.py Expands unsafe-protocol detection.
git/​remote.py Guards rendered remote arguments.
git/​repo/​base.py Deprecates GitDB and strengthens archive handling.
git/​repo/​fun.py Delegates message searches to Git.
test/​test_index.py Tests index and staging hardening.
test/​test_tree.py Tests tree-name validation.
test/​test_fun.py Tests malformed tree records.
test/​test_refs.py Tests symbolic-reference security.
test/​test_repo.py Tests archive protocol guards.
test/​test_rev_parse.py Tests revision-message behavior.
test/​test_command_guards.py Tests command protocol guards.
test/​deprecation/​test_basic.py Tests GitDB warnings.
doc/​source/​tutorial.rst Documents recommended ODB usage.
doc/​source/​changes.rst Records the deprecation.
.pre-commit-config.yaml Removes the codespell hook.
pyproject.toml Removes codespell configuration.
.basedpyright/​baseline.json Removes resolved type-check suppressions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread git/index/base.py
Comment on lines +744 to +748
parent = osp.realpath(self.repo.working_dir)
for component in os.fspath(filepath).split("/")[:-1]:
parent = osp.join(parent, component)
if osp.islink(parent) or osp.normcase(osp.realpath(parent)) != osp.normcase(osp.abspath(parent)):
raise ValueError("Cannot stage a path beyond a symbolic link: %r" % filepath)
Comment thread git/refs/symbolic.py
cls._check_ref_name_valid(ref_path)
if ref_path is None:
raise ValueError("Reference at %r does not exist" % ref_path)
ref_file = cls._get_validated_ref_path(repo, ref_path)
Comment thread git/refs/symbolic.py
Comment on lines +197 to +199
:raise ValueError:
If the reference is missing, invalid, or exceeds Git's limit of five
references in a symbolic reference chain (including the terminal ref).
Comment thread git/repo/base.py
"GitDB is deprecated as a GitPython backend due to security and performance issues. "
"Use the default GitCmdObjectDB backend instead.",
DeprecationWarning,
stacklevel=2,
Comment thread git/util.py
if not name or "\0" in name or ntpath.splitdrive(name)[0] or name.startswith("/"):
raise ValueError("Invalid repository path %r" % name)
if os.name == "nt" and "\\" in name:
raise ValueError("Index paths must use '/' separators: %r" % name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot
Copilot review effort
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@Byron @codex
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.