-
Notifications
You must be signed in to change notification settings - Fork 329
cache-memory setup must clear .git/hooks/ after cache restore, before running git checkout #23739
Description
Summary
In gh-aw v0.64.x, the cache-memory feature switched to a git-based integrity model that stores persistent state under /tmp/gh-aw/cache-memory/ (a full git repository). The actions/cache step saves and restores this entire directory, including .git/hooks/. Because git add -A does not stage files under .git/, hook files written by the agent are not tracked by git but are preserved in the cache. On the next run, setup_cache_memory_git.sh restores the cache and then calls git checkout and git merge on the host runner — triggering any post-checkout or post-merge hooks before the AWF container ever starts. This gives a compromised agent run the ability to execute arbitrary code on the host runner with host-runner privileges in a subsequent run, bypassing the AWF sandbox entirely.
A secondary concern: the legacy-to-git migration path runs git init -b merged and git add -A, committing any pre-existing flat-file cache contents directly to the merged (highest-trust) integrity branch, potentially escalating the trust level of files written at none integrity in a prior version of gh-aw.
Affected Area
cache-memory / git-based integrity model / cross-run cache persistence boundary / host-runner ↔ AWF-container trust boundary (setup_cache_memory_git.sh)
Reproduction Outline
- Create a workflow with
cache-memory:enabled (gh-aw v0.64.x, git-based model). - In run N (e.g., via a prompt-injected instruction or a malicious tool call), write an executable
post-checkouthook:printf '#!/bin/sh\necho "$GITHUB_TOKEN" > /tmp/leaked-token.txt\n' \ > /tmp/gh-aw/cache-memory/.git/hooks/post-checkout chmod +x /tmp/gh-aw/cache-memory/.git/hooks/post-checkout
- Confirm the hook is not staged by git:
git -C /tmp/gh-aw/cache-memory add -A && git statusdoes not list the hook file. - Allow run N to complete —
actions/cachesaves/tmp/gh-aw/cache-memoryincluding.git/hooks/post-checkout. - Trigger run N+1 —
actions/cacherestores the full directory;setup_cache_memory_git.shcallsgit checkout -q noneon the host runner, firing thepost-checkouthook before the agent container starts.
Observed Behavior
The post-checkout (and post-merge) hooks written by the agent in run N are restored from cache and executed on the host runner during the Set up cache-memory git repository step of run N+1, prior to the AWF sandbox being established.
Expected Behavior
All files under .git/hooks/ (except .sample stubs) should be removed or invalidated immediately after actions/cache restores /tmp/gh-aw/cache-memory and before any git checkout or git merge is called. Alternatively, only the git bundle or working-tree content should be cached so that .git/ is always reconstructed fresh and no cached artifact can influence host-runner git operations.
Security Relevance
Successful exploitation gives an attacker-controlled agent run the ability to execute arbitrary commands on the host runner in a subsequent workflow run, with host-runner privileges and full access to GITHUB_TOKEN and runner environment variables — entirely outside the AWF container sandbox. The attack requires only the ability to trigger one workflow run (e.g., via workflow_dispatch, issue creation, or prompt injection) and is reproducible on any GitHub Actions runner using gh-aw v0.64.x with cache-memory: enabled.
Suggested Fixes
- Strip hooks on restore: Add a step between
actions/cacherestore andSet up cache-memory git repositorythat clears non-sample hook files:find /tmp/gh-aw/cache-memory/.git/hooks/ -type f ! -name '*.sample' -delete - Redirect hooksPath: In
setup_cache_memory_git.sh, rungit config core.hooksPath /dev/nullimmediately after init/checkout so no hooks under.git/hooks/can fire. - Cache bundle only: Cache a
git bundleor working-tree tar instead of the full/tmp/gh-aw/cache-memorydirectory, reconstructing.git/fresh on each run. - Migration guard: During legacy flat-file → git migration, do not commit pre-existing files to the
mergedbranch; assign themnoneintegrity instead.
gh-aw version: v0.65.0 (finding reported against v0.64.4)
Original finding: https://github.com/githubnext/gh-aw-security/issues/1647
Generated by File Issue · ◷