FlawOpen

flawopen.com/AI Security/plugin4shell-ai-agent-plugin-sha-pin-bypass

● CWE-345 · High
FlawOpen Security Research

Plugin4Shell: AI-Agent Plugin SHA Bypass

Four AI-agent plugin installers fetched pinned Git revisions but skipped commit verification. Plugin4Shell exposed the gap; check the resolved SHA.[1]

💡 Plain English Explainer (ELI5)

A library reserves a particular book edition by its unique catalog number. The clerk asks for that number but accepts a different book when a shelf label happens to use the same text. A SHA pin is the catalog number; the installer must inspect the checked-out commit itself before trusting or running the plugin.[1]

Core Concepts & Subsystem Terms

Commit SHA
A hash identifying a specific Git commit object. A secure pinning workflow must verify the resolved checkout against this value.[1], [2]
Git ref ambiguity
Git accepts both object IDs and names such as branches as revision expressions. Where a name can resolve as a ref, a request that looks like a commit ID may select that ref instead.[1]
Plugin marketplace
A catalog that distributes agent extensions and may record a reviewed plugin revision. The installing client still has to enforce the pin.[1]
CWE-345
Insufficient Verification of Data Authenticity: a system uses data without adequately checking that it is the expected authentic value.[5]

Framework mappings

  • CWE reference for the weakness described in this guide: CWE-345

Step-by-Step Attack Flow

Step 1

A marketplace records a reviewed commit

A plugin entry points to a repository and a specific commit SHA that reviewers expect the installer to use.[1]

Step 2

The repository owner can change refs

AIR Security reports that a repository controller can create a default branch whose name matches a requested SHA on Git hosts that permit such names. It describes a separate FETCH_HEAD ref-resolution path for Gemini CLI.[1]

Step 3

The installer checks out without checking HEAD

The Codex pre-fix code passed the requested SHA to <code>git checkout</code> and treated a successful Git exit as proof that the pin had been honored.[1], [2]

Step 4

The client rejects or accepts the materialized tree

Codex's fix reads <code>git rev-parse HEAD</code> after checkout and aborts on a mismatch. Without an equivalent check, substituted plugin code may be installed and run with the agent user's permissions.[2], [1]

Source Code: Flaw vs. Secure Implementation

The vulnerable path conflated a successful name resolution with proof of object identity. The patch checks the resulting HEAD against the marketplace pin and refuses to materialize a different commit. This code pair reflects the Codex patch; the other products had distinct installer implementations and must not be assumed to share this exact fix.[2], [6]

UNPATCHED FLAW
// Pre-fix shape from OpenAI Codex PR #34644
if let Some(target) = sha.or(ref_name) {
    run_git(&["checkout", target], Some(destination))?;
}
// A successful checkout was treated as proof that a SHA pin matched.
HARDENED SECURE PATCH
// Codex fix: verify the resolved commit, not only the requested argument
if let Some(sha) = sha {
    run_git(&["checkout", sha], Some(destination))?;
    let checked_out_sha =
        run_git_output(&["rev-parse", "HEAD"], Some(destination))?;
    if !checked_out_sha.eq_ignore_ascii_case(sha) {
        return Err(format!(
            "checked out Git SHA {checked_out_sha} does not match requested SHA {sha}"
        ));
    }
} else if let Some(ref_name) = ref_name {
    run_git(&["checkout", ref_name], Some(destination))?;
}

Engineering & System Hardening Checklist

Sources

← AI Security Hub Directory →