anthropics / anthropics/claude-code-action

AGENTS.md is not in SENSITIVE_PATHS — the documented @AGENTS.md import loads the PR head's instructions despite the CLAUDE.md restore

Abierto
#1,696 1 comentario 0 reacciones 0 asignados Ver en GitHub
area:permissions bug p2
Lenguaje dominante
TypeScript
Estrellas
8.9k
Forks
2.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

## Summary

`SENSITIVE_PATHS` (src/github/operations/restore-config.ts, ~line 26 at v1.0.195 / `d40ddef`) restores `CLAUDE.md`, `CLAUDE.local.md`, `.claude`, `.mcp.json`, `.claude.json`, `.gitmodules`, `.ripgreprc`, and `.husky` from the base branch on PR contexts, described in-file as "Paths that are both PR-controllable and read from cwd at CLI startup" — so a PR cannot inject instructions into the run.

`AGENTS.md` is not on that list. But the Claude Code memory docs explicitly recommend keeping shared instructions in `AGENTS.md` and importing them from `CLAUDE.md` via `@AGENTS.md` (https://code.claude.com/docs/en/memory, "AGENTS.md" section). In a repo using that documented pattern, the restored base-branch `CLAUDE.md` still contains the `@AGENTS.md` import — and the import resolves against the working tree, which is the **PR head** checkout (src/github/operations/branch.ts checks out `pull/N/head`, including fork PRs). The import therefore loads the PR author's `AGENTS.md` into the run's instructions, reopening the injection path the CLAUDE.md restore was built to close.

## Impact

Bounded by the trigger gate (write access required by default, `allowed_non_write_users` empty), so exploitation requires a maintainer commenting `@claude` on a PR whose head modifies or adds `AGENTS.md`. That is precisely the scenario `SENSITIVE_PATHS` exists to defend — a maintainer invoking the action on an untrusted contribution — and the file it misses is the one the product's own docs tell users to put their instructions in. Nested `AGENTS.md` files in subdirectories (also part of the agents.md convention) have the same property when imported.

## Reproduction sketch

1. Repo with `CLAUDE.md` containing `@AGENTS.md` (the documented pattern) and both files on the default branch.
2. External PR modifies `AGENTS.md` to include adversarial instructions.
3. Maintainer comments `@claude` on the PR.
4. The action restores `CLAUDE.md` from base (correct), but the `@AGENTS.md` import inside it resolves to the PR head's file — the modified instructions load.

## Suggested fix

Add `AGENTS.md` (and arguably `AGENTS.local.md` / nested `**/AGENTS.md`, matching whatever the import + native-discovery surface grows to) to `SENSITIVE_PATHS`. More generally: any file reachable from a restored `CLAUDE.md` via `@` imports inherits CLAUDE.md's trust requirements — a recursive restore of the import closure would close the class rather than the instance, but the single filename covers the documented pattern today.

Found while auditing our own repo's adoption of the `@AGENTS.md` import pattern (action pinned at v1 → v1.0.195, installing Claude Code 2.1.235; confirmed 2.1.235 does not natively discover AGENTS.md, so the import is the sole loader — which is exactly why it escapes the restore).

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.