Skip to content

cache-memory setup must clear .git/hooks/ after cache restore, before running git checkout #23739

Description

@szabta89

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

  1. Create a workflow with cache-memory: enabled (gh-aw v0.64.x, git-based model).
  2. In run N (e.g., via a prompt-injected instruction or a malicious tool call), write an executable post-checkout hook:
    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
  3. Confirm the hook is not staged by git: git -C /tmp/gh-aw/cache-memory add -A && git status does not list the hook file.
  4. Allow run N to complete — actions/cache saves /tmp/gh-aw/cache-memory including .git/hooks/post-checkout.
  5. Trigger run N+1 — actions/cache restores the full directory; setup_cache_memory_git.sh calls git checkout -q none on the host runner, firing the post-checkout hook 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/cache restore and Set up cache-memory git repository that 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, run git config core.hooksPath /dev/null immediately after init/checkout so no hooks under .git/hooks/ can fire.
  • Cache bundle only: Cache a git bundle or working-tree tar instead of the full /tmp/gh-aw/cache-memory directory, reconstructing .git/ fresh on each run.
  • Migration guard: During legacy flat-file → git migration, do not commit pre-existing files to the merged branch; assign them none integrity 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 ·

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions