detection: agent instruction and memory files are an instruction channel that earns no trait

Abierto
#151 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
30/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
python
Área
security

Línea de trabajo

Start by reading UNTRUSTED_INPUT_COMMAND and classify_command in traits.py, then review the correlation model in rules.py and the host-scoped host-subagent-swarm-burst rule. The issue describes a cross-session write-then-read detection, but leaves path coverage, operator-versus-agent attribution, and trait-versus-rule design unresolved. Done means those decisions are settled and the detector can distinguish poisoned instruction-file activity without flagging ordinary reads.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

What happens

UNTRUSTED_INPUT_COMMAND matches exactly two things:

r"\bgh\s+(issue|pr)\s+(view|list|diff|comment)|"
r"\bgit\s+(fetch|pull|clone)\b"

That is content arriving from a code forge, which is the threat model in the Agent Data Injection paper the rule was built against. Reading an agent's own instruction or memory file earns nothing:

cat ~/.claude/CLAUDE.md                    -> []
cat AGENTS.md                              -> []
cat .cursorrules                           -> []
cat ~/.claude/projects/x/memory/MEMORY.md  -> []

Empty. Not a weaker trait, no trait. So a read of a poisoned instruction file cannot start the untrusted-input-then-risky-action chain, because nothing marks it as untrusted content.

Why it matters

These files are an instruction channel by design. The agent reads them and treats them as directives, which is the entire point of them. If one is poisoned, it is a prompt injection with a long fuse: it survives the session it was planted in and fires on every later session.

OWASP AST10 names memory files as untrusted content directly, and this project is otherwise covered on AST05.

Same shape as #142. A channel that carries instructions, not classified as one, so the detector is blind to it while looking correct.

The naive fix is wrong

Do not flag every read of CLAUDE.md.

These files are overwhelmingly written by the operator and read constantly. Treating every read as untrusted input would produce a critical on the first thirty seconds of every session, which is exactly the false-positive class 0.7.0 spent a release removing. It would be #44 again with a different filename.

The shape that is actually interesting

Not the read. The write followed by a read.

  • The agent, or content it fetched, modifies an instruction file
  • A later session reads it and acts

That is a two-step sequence across sessions, which is a different correlation window from anything the engine does today: every current rule correlates inside one session. A poisoned memory file is specifically an attack that crosses sessions, so the rule that catches it has to as well.

Worth considering alongside host-subagent-swarm-burst, which is the only existing host-scoped rule and the only precedent for correlating beyond a single session.

Open questions

  • Which paths count. CLAUDE.md, AGENTS.md, .cursorrules, .github/copilot-instructions.md, per-agent memory stores. This list is a maintenance burden and gets stale as agents add conventions.
  • Whether a write by the operator is distinguishable from a write by the agent. If it is not, the rule cannot separate "I edited my own instructions" from "the agent rewrote them", and that distinction is the whole finding.
  • Whether this belongs as a trait, a rule, or both.

Blocked by the freeze

traits.py and rules.py are hashed into the ruleset fingerprint. The dogfood clock restarted 2026-08-30 and closes no earlier than 2026-09-26, so this cannot land before then. #55 is the other change queued behind that, and both should go in one pass so the fingerprint moves once.

Source

Noticed while checking whether an unrelated article on agent memory design touched anything here. It did not, but the topic pointed at this. Verified against classify_command rather than assumed.

Lenguaje dominante
Python
Estrellas
10
Forks
5
Merge medio
9 h 44 min
PR fusionados (30 d)
116

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de blitzcrieg1/agentmetry

Todos los issues de blitzcrieg1/agentmetry

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.