T01 · Skill Instruction Hijacking
- Location
scout.py:36- Finding
Untrusted Project Instructions Are Passed Verbatim to the AI Agent
- Content
View full analysis
Vulnerability Details
File Location:
scout.py:36-37,scout.py:315-318, andscout.py:410-414
Vulnerability Type: Indirect prompt injection through untrusted project files
Risk Level: MediumVulnerable Code
The scanner explicitly prioritizes files commonly used to provide instructions to AI agents:
python PRIORITY_FILES = [ "README.md", "README.rst", "README.txt", "readme.md", "CLAUDE.md", ".claude/CLAUDE.md", "package.json", "pyproject.toml", "setup.py", "setup.cfg", "Cargo.toml", "go.mod", "go.sum", "pom.xml", "build.gradle", "build.gradle.kts", "composer.json", "Gemfile", "docker-compose.yml", "docker-compose.yaml", "Dockerfile", "Makefile", "justfile", "Taskfile.yml", ".env.example", ".env.sample", ".env.template", "requirements.txt", "requirements-dev.txt", "Pipfile", "uv.lock", "tsconfig.json", "jsconfig.json", "vite.config.ts", "vite.config.js", "next.config.js", "next.config.ts", "webpack.config.js", "angular.json", "nuxt.config.ts", ]It reads those attacker-controlled files without applying a trust-boundary transformation:
python # Read priority files for name in PRIORITY_FILES: candidate = root / name if candidate.exists() and candidate.is_file(): result["priority_files"][name] = read_file(candidate, max_lines=100)Their contents are then placed verbatim into output intended for the agent:
python # Priority files if data["priority_files"]: lines.append("KEY FILES") lines.append("-" * 40) for name, content in data["priority_files"].items(): lines.append(f"\n### {name}") lines.append(content) lines.append("")Technical Analysis
The project scanner crosses a trust boundary: text controlled by the owner of a scanned repository is copied into a report consumed by an AI agent. The copied text is not merely metadata; it can contain arbitrary natural-language instructions.
CLAUDE.mdand `.claud ...[truncated 2565 chars]- Remediation
View remediation
Remediation Suggestions
- Remove
CLAUDE.mdand.claude/CLAUDE.mdfrom the default priority-file list. Only inspect them after explicit user consent, and never treat their contents as operating instructions. - Replace raw file inclusion with structured fact extraction. Return only relevant metadata such as project description, dependency names, and documented run commands.
- Clearly delimit all repository-derived text as untrusted content. Add an explicit Skill-level instruction that the agent must never follow commands or behavioral directives found in scanner output.
- Use JSON fields with provenance labels such as
source_file,content_type, anduntrusted_textinstead of concatenating raw prose into a conversational report. - Apply conservative length limits and, where raw excerpts are necessary, quote or encode them so they are visibly data rather than agent instructions.
- Require confirmation before the agent acts on commands discovered in a scanned repository. Commands should be described to the user, not automatically executed.
- Add adversarial tests containing prompt-injection payloads in
README.md,CLAUDE.md, nested documentation, and configuration files. Verify that these payloads cannot redirect the agent or trigger tools. - Preserve provenance in the rendered report so every excerpt is clearly attributed to an untrusted repository file.
- Remove
