Skip to content

🐛 contain git-mode file reads within the checkout root - #5164

Open
Sahana2524 wants to merge 1 commit into
ossf:mainfrom
Sahana2524:gitfile-open-in-root
Open

🐛 contain git-mode file reads within the checkout root#5164
Sahana2524 wants to merge 1 commit into
ossf:mainfrom
Sahana2524:gitfile-open-in-root

Conversation

@Sahana2524

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

Bug fix (security): keeps file reads in git mode inside the repository checkout.

What is the current behavior?

In git mode (--file-mode git) the target repo is cloned to a temp dir with a
non-bare git.PlainClone, which materializes symlinks on disk for symlink
entries in the tree. internal/gitfile's GetFile checks the requested name for
../ traversal but then reads with os.Open, which follows symlinks. A scanned
repo can commit a symlink whose name matches a check's file predicate (a workflow
file, a Dockerfile, and so on) and make the read resolve outside the checkout:

innocent.txt -> /etc/passwd   # committed in the scanned repo
GetFile("innocent.txt")       # os.Open follows the link, reads the host file

clients/git's GetFileReader has the same non-bare-clone plus os.Open shape
with no containment check at all.

  • Tests for the changes have been added (for bug fixes/features)

What is the new behavior (if this is a feature change)?

Both readers now use os.OpenInRoot(tempDir, filename), which refuses names that
escape the root through ../ or a symlink, so a within-repo path reads normally
while an escaping one returns an error. This is the same approach
clients/localdir already uses. A regression test commits an escaping symlink
and checks the read is refused; the existing ../ traversal test still passes.

Which issue(s) this PR fixes

NONE

Special notes for your reviewer

os.OpenInRoot landed in Go 1.24 and the module is already on 1.25, so no
version bump is needed. I left the archive/zip handlers alone since they skip
symlink entries during extraction and never write them to disk, so the same read
path is not reachable there.

Does this PR introduce a user-facing change?

In git file mode, file reads are now contained to the repository checkout, so a symlink committed in a scanned repo can no longer redirect a read to a file outside it.

Signed-off-by: Sahana Bogar <sahana@digiscrypt.com>
@Sahana2524
Sahana2524 requested a review from a team as a code owner August 8, 2026 11:03
@Sahana2524
Sahana2524 requested review from AdamKorcz and justaugustus and removed request for a team August 8, 2026 11:03
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant