Prefect GitRepository Git Argument Injection RCE via `commit_sha` — CVE-2026-5366
by renat0z3r0 · 2026-07-05
- Severity
- High
- CVE
- CVE-2026-5366 (Huntr bounty e2e88a0f-a8f6-49c9-94c5-e98dc385f07a)
- Category
- web
- Affected product
- Prefect (workflow orchestration platform), GitRepository storage class
- Affected versions
- 3.6.23 (vulnerable); fixed in 3.6.25+
- Disclosed
- 2026-07-05
- Patch status
- patched
Tags
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-06 |
| Author / Researcher | renat0z3r0 |
| CVE / Advisory | CVE-2026-5366 (Huntr bounty e2e88a0f-a8f6-49c9-94c5-e98dc385f07a) |
| Category | web |
| Severity | High |
| CVSS Score | Not specified in source |
| Status | PoC |
| Tags | prefect, git, argument-injection, rce, upload-pack, workflow-orchestration, supply-chain, python |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Prefect (workflow orchestration platform), GitRepository storage class |
| Versions Affected | 3.6.23 (vulnerable); fixed in 3.6.25+ |
| Language / Platform | Python (prefect.runner.storage.GitRepository) |
| Authentication Required | No additional auth beyond ability to configure a GitRepository (e.g. via a flow/deployment definition) |
| Network Access Required | No — reproducible entirely offline against a local file:// git repo; only fires on local/ssh git transports, not https:// |
Summary
CVE-2026-5366 is a git argument-injection vulnerability in Prefect’s GitRepository storage class (src/prefect/runner/storage.py). The commit_sha parameter is stored verbatim with no validation beyond a branch/commit_sha mutual-exclusion check, then passed directly into git fetch origin <commit_sha> and git checkout <commit_sha> argument lists with no -- separator. Because git parses any leading-dash value as an option rather than a positional argument, a commit_sha of --upload-pack=/bin/sh -c '<command>' causes git to execute the attacker’s shell command locally in place of the real git-upload-pack helper when the repository is fetched over a local or ssh transport, achieving remote code execution on the Prefect worker. A sibling directories parameter is injectable in the same way but lands in git sparse-checkout set, which has no --upload-pack option, so it is argument injection without RCE.
Vulnerability Details
Root Cause
In src/prefect/runner/storage.py (3.6.23): commit_sha is assigned unvalidated at line 181, then used at pull_code() lines ~379/391 and _clone_repo() lines ~475/480 as ["git", "fetch", "origin", self._commit_sha] / ["git", "checkout", self._commit_sha] — an argument list (no shell) but with no -- separator, so a value starting with - is parsed by git as an option. directories (line ~191) is used similarly at pull_code() line ~360 / _clone_repo() line ~489 in ["git", "sparse-checkout", "set", *self._directories], also without a -- separator.
Attack Vector
- Construct/control a
GitRepository(url=..., commit_sha=..., directories=...)object (e.g. via a Prefect deployment/flow configuration that accepts these fields). - Ensure the destination directory does not already contain a
.git(force-delete it) so Prefect takes the full_clone_repo()path rather than the “update existing repo” path. - Set
commit_shato--upload-pack=/bin/sh -c '<attacker command>'. - Trigger
pull_code()/_clone_repo(); when the remote is reached over a local (file://) or ssh transport, git invokes the attacker’s program locally as the pack-transfer helper, executing arbitrary code on the Prefect worker before the (expected) subsequent git protocol error.
Impact
Remote code execution on the Prefect worker process under the identity running the flow/deployment, achievable via a single attacker-controlled commit_sha value with no shell metacharacters required (pure git argument injection).
Environment / Lab Setup
Target: prefect==3.6.23 (vulnerable) installed in an isolated virtualenv/container
Attacker: Python 3.12, git in PATH; run_offline.sh builds a local file:// bare repo
so the exploit fires without any network access
Proof of Concept
PoC Script
See
poc.pyandrun_offline.shin this folder.
| |
poc.py builds a --upload-pack=/bin/sh -c '...' payload for both the commit_sha and directories parameters, force-cleans the destination so Prefect takes the _clone_repo() path, constructs a GitRepository with the poisoned field, calls pull_code(), and checks for a timestamped marker file to confirm code execution; run_offline.sh provides a network-free file:// repo so the local-transport --upload-pack vector reliably fires.
Detection & IOCs
git fetch origin --upload-pack=<program> ...
git checkout --upload-pack=<program> ...
Unexpected child processes (/bin/sh, cmd.exe) spawned by a Prefect worker/agent process
Signs of compromise:
- Prefect worker processes spawning shell interpreters as children shortly after a flow/deployment run referencing a
GitRepositorystorage block. commit_shaordirectoriesvalues in flow/deployment definitions beginning with-(especially--upload-pack=).- Marker/side-effect files or outbound connections created during what should be a routine
git fetch/checkout.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade to Prefect >= 3.6.25, which validates commit_sha against ^[0-9a-fA-F]{4,64}$ (rejecting non-hash values at construction) and adds a -- separator before directories values in the git command. |
| Interim mitigation | Restrict who can define/modify GitRepository storage blocks; validate commit_sha/directories values before they reach Prefect if using an older version. |
References
- Source repository
- Huntr bounty: https://huntr.com/bounties/e2e88a0f-a8f6-49c9-94c5-e98dc385f07a
- Vulnerable tag:
3.6.23; patch commit6a9d9918716ce4ee0297b69f3046f7067ef1faae
Notes
Mirrored from https://github.com/renat0z3r0/prefect-cve-2026-5366 on 2026-07-05. The PoC only demonstrates RCE against local/ssh git transports (not the default https:// remote) — this is a property of --upload-pack, not a limitation of the PoC. Categorized under “web” to match this archive’s convention for workflow/orchestration-platform vulnerabilities (Prefect is a web-managed data/flow orchestration tool), though the exploited component is a backend git-storage integration rather than an HTTP endpoint.
| |