Repository navigation
Only read from Git in app security check - #8841
Merged
Merged
Conversation
app security check asks Git which files are tracked, which are ignored and where a repository's top level is. Answering doesn't need Git to run a program, start a background file-system monitor or fetch anything, and the answers should come from the repository that contains the app, not from repository files committed inside it. Git takes the settings behind all of these from the repository being scanned, so the check now overrides them. Every Git command in the engine goes through one runGit helper that applies four protections: - `-c core.fsmonitor=` turns off the file-system monitor, which only speeds up reading the index. - `-c safe.bareRepository=explicit` refuses a bare repository found in the working directory, such as one committed as ordinary files. Older Git versions ignore it; the other protections still apply. - `GIT_NO_LAZY_FETCH=1` stops a partial clone from fetching a missing object, which would use the network and write to the repository. - `GIT_ALLOW_PROTOCOL=` refuses every transport, which also covers Git versions without GIT_NO_LAZY_FETCH. The tests build a repository for each case and show that plain Git runs a program it names. They then show that each protection on its own stops that program and that a scan runs nothing. A protection added without a test fixture fails type-checking. The tests also run on Windows.
jek
force-pushed
the
app-security/git-fsmonitor
branch
from
October 8, 2026 17:12
95961f0 to
0c17a82
Compare
jek
marked this pull request as ready for review
October 8, 2026 17:33
jplhomer
approved these changes
Oct 8, 2026
gonzaloriestra
approved these changes
Oct 9, 2026
lopez-mar
approved these changes
Oct 9, 2026
1 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
WHY are these changes introduced?
shopify app security checkasks Git which files are tracked, which are ignored, and where a repository's top level is. Answering doesn't need Git to:core.fsmonitor).ls-filesandcheck-ignorestart one whenever they read the index.core.sshCommand,remote.<name>.uploadpack), for example when a skip-worktree.gitignoreisn't in the object store.HEAD,config,objects/,refs/), instead of the repository that contains the app.Git takes the settings behind all three from the repository being scanned, so a scanned repository could make the check run a program or get its answers from the wrong place. The check now overrides them.
WHAT is this pull request doing?
Every Git command in the engine now goes through one
runGithelper (scanners/git.ts). It applies four protections, kept in a named table:-c core.fsmonitor=falseas the program's name.-c safe.bareRepository=explicitGIT_NO_LAZY_FETCH=1GIT_ALLOW_PROTOCOL=(empty)GIT_NO_LAZY_FETCH.path-rules.tsandsecret-rules.tslose their private copies ofrunGit.Behaviour changes:
core.fsmonitor=true), scans no longer start agit fsmonitor--daemonfor each scanned directory.Tests (
tests/untrusted-repository.test.ts):.git/confignames a monitor, a bare repository committed into a clone, and a partial clone missing an object. Each fixture first shows that plain Git runs the program it names, so a fixture that stops doing so fails instead of passing.GIT_ALLOW_PROTOCOL.How to manually test your changes?
Create a repository whose own settings name a file-system monitor:
Run
git ls-files./tmp/untrusted-markerappears, which shows the program runs.Delete the marker. Run
shopify app security check --path /tmp/untrusted. The marker doesn't appear.Checklist
patchfor bug fixes ·minorfor new features ·majorfor breaking changes) and added a changeset withpnpm changeset add