Package Hallucination Attacks on Coding Agents through Prompt Injection in Rule Files
Organizations: Duke University
Abstract
Modern agentic coding frameworks increasingly rely on community-shared rule files (e.g., AGENTS.md or .cursorrules) to guide autonomous code generation, yet the security risks of this pipeline remain underexplored. To bridge this gap, we introduce the package hallucination attack, where an attacker injects malicious prompts into benign rule files to induce coding agents to replace legitimate dependencies with attacker-controlled packages. To obtain effective malicious prompts injected into rule files, we propose PackHallu, an evolutionary optimization framework that iteratively rewrites these injected prompts using trajectory-level feedback and LLM-guided mutations. Evaluations across multiple benchmarks, LLMs, and agent frameworks show that PackHallu achieves high attack success rates and strong transferability across diverse models and agent combinations. Our findings demonstrate that coding agents are vulnerable to package hallucination attacks, highlighting the urgent need for stronger security safeguards in autonomous coding systems.
Figures & tables
| Name | Task Type | #Victim Packages | #Victim Tasks |
| BigCodeBench | Code Generation from Scratch | 5 | 981 |
| DS-1000 | Code Generation from Scratch | 4 | 772 |
| RefactorBench | Multi-File Refactoring | 5 | 43 |
| Package | Attack | Qwen2.5-Coder-7B | Qwen3-Coder-30B | Devstral-Small-2-24B | GLM4.7-Flash-30B | Gemma4-31B | |||||
| SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | ||
| Pandas | Combined Attack | 11.48 | 5.26 | 1.28 | 1.28 | 14.86 | 12.86 | 20.22 | 10.98 | 23.60 | 23.60 |
| Repeat Attack | 24.59 | 13.16 | 1.28 | 1.28 | 8.11 | 7.14 | 19.10 | 13.41 | 29.21 | 29.21 | |
| GCG | 11.48 | 0.00 | 6.41 | 6.41 | 4.05 | 2.86 | 4.49 | 3.66 | 6.74 | 6.74 | |
| ObliInjection | 9.84 | 2.63 | 2.56 | 2.56 | 0.00 | 0.00 | 12.36 | 10.98 | 19.10 | 19.10 | |
| TAP | 55.74 | 18.42 | 34.62 | 26.92 | 44.59 | 40.00 | 87.64 | 86.59 | 33.71 | 32.58 | |
| Attack | Attention Prop. | SASR | DASR |
| Combined Attack | 0.24 | 32.50 | 32.50 |
| Repeat Attack | 0.26 | 17.50 | 17.50 |
| GCG | 0.32 | 22.50 | 22.50 |
| ObliInjection | 0.33 | 0.00 | 0.00 |
| TAP | 0.32 | 55.00 | 52.50 |
| PackHallu | 0.68 | 97.50 | 97.50 |
| Backbone LLM | Pandas | Numpy | Matplotlib | Scipy | Seaborn | |||||
| SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | |
| Qwen2.5-Coder-7B | 27.87 | 7.89 | 45.61 | 26.47 | 30.16 | 13.51 | 22.73 | 10.00 | 50.00 | 22.22 |
| Qwen3-Coder-30B | 98.72 | 89.74 | 24.68 | 23.68 | 96.88 | 86.32 | 93.18 | 86.36 | 97.50 | 97.50 |
| Devstral-Small-2-24B | 55.41 | 52.86 | 25.40 | 15.87 | 72.29 | 65.00 | 64.71 | 58.82 | 73.33 | 72.41 |
| GLM4.7-Flash-30B | 92.13 | 84.15 | 67.12 | 41.67 | 90.43 | 86.36 | 92.50 | 85.00 | 97.30 | 94.59 |
| Gemma4-31B | 87.64 | 86.52 | 75.00 | 60.53 | 100.00 | 100.00 | 86.11 | 83.33 | 88.10 | 85.71 |
| Agent Framework | Pandas | Numpy | Matplotlib | Scipy | Seaborn | |||||
| SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | |
| OpenHands | 98.72 | 89.74 | 81.82 | 68.42 | 96.88 | 86.32 | 93.18 | 86.36 | 97.50 | 97.50 |
| OpenCode | 84.78 | 78.26 | 15.85 | 16.05 | 77.55 | 50.00 | 50.00 | 41.30 | 73.17 | 72.50 |
| Aider | 50.00 | 40.00 | 94.64 | 85.45 | 98.25 | 45.10 | 77.14 | 63.64 | 68.97 | 62.96 |
| Pi Coding Agent | 95.79 | 90.59 | 90.59 | 72.29 | 96.94 | 46.15 | 97.73 | 92.86 | 97.87 | 87.80 |
| Cline | 88.10 | 85.54 | 42.67 | 36.00 | 86.52 | 65.91 | 76.74 | 73.81 | 81.82 | 72.73 |
| Agent | Backbone | Pandas | Numpy | Matplotlib | Scipy | Seaborn | |||||
| SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | ||
| OpenCode | DeepSeek-V4-Flash | 83.87 | 50.54 | 75.32 | 28.57 | 93.94 | 55.67 | 77.50 | 62.50 | 82.50 | 47.50 |
| Claude Code | Claude Sonnet 4.6 | 58.95 | 57.89 | 31.03 | 31.03 | 41.00 | 40.00 | 37.70 | 34.43 | 52.17 | 52.17 |
| Cursor | Auto | 98.00 | 98.00 | 79.17 | 76.84 | 93.00 | 91.84 | 69.35 | 66.13 | 81.48 | 81.48 |
| Cursor | Composer 2.5 | 95.65 | 93.48 | 85.00 | 82.50 | 92.00 | 90.82 | 81.40 | 79.07 | 87.18 | 87.18 |
| Dataset | SASR | DASR |
| BigCodeBench | 79.29 | 67.68 |
| DS-1000 | 53.33 | 45.00 |
| RefactorBench | 18.60 | 16.28 |
| Location | Pandas | Numpy | Matplotlib | Scipy | Seaborn | |||||
| SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | SASR | DASR | |
| Beginning | 83.87 | 50.54 | 75.32 | 28.57 | 93.94 | 55.67 | 77.50 | 62.50 | 82.50 | 47.50 |
| Middle | 73.12 | 52.69 | 70.13 | 38.96 | 91.92 | 65.98 | 75.00 | 42.50 | 60.00 | 32.50 |
| End | 75.27 | 40.86 | 75.32 | 25.97 | 85.86 | 57.73 | 80.00 | 70.00 | 70.00 | 50.00 |
| Init | SASR | DASR |
| Default | 97.50 | 97.50 |
| Variant 1 | 97.50 | 95.00 |
| Variant 2 | 100.00 | 97.50 |
| Variant 3 | 95.00 | 95.00 |
| Variant 4 | 100.00 | 95.00 |
| Variant | SASR | DASR |
| PackHallu | 83.87 | 50.54 |
| w/o Trajectory-Level Signal | 56.99 | 24.73 |
| w/o Self-Attributed Critique | 62.37 | 47.31 |
| w/o Strategy Proposal | 63.44 | 46.24 |
| Hyperparameter | Setting | SASR | DASR |
| Number of rounds | 75.27 | 38.71 | |
| 83.87 | 50.54 | ||
| 84.95 | 49.46 | ||
| Top- selection | 43.01 | 21.51 | |
| 83.87 | 50.54 | ||
| 80.65 | 51.61 |
| Detector | FNR | FPR |
| ProtectAI-DeBERTa | 100.00 | 3.00 |
| PromptGuard | 46.00 | 5.00 |
| DataSentinel | 49.00 | 16.00 |
| PromptArmor | 20.00 | 34.00 |
| PIShield | 21.00 | 11.00 |
Appendix figures & tables21 assets
Supplementary material from the paper’s appendix.
Appendix
| Hyperparameter | Symbol | Value |
| Number of rounds | 20 | |
| Top- selection | 5 | |
| Offsprings per prompt | 3 | |
| Number of surrogate tasks | 10 | |
| Sampling temperature | 0.7 |
| ID | Name | Description | Count | Proportion (%) |
| S1 | Policy-Cited Compliance | Cites the malicious prompt as justification, surfacing it as legitimating authority. | 22 | 25.3 |
| S2 | Silent Compliance | Uses numpy_hl without any acknowledgment. | 2 | 2.3 |
| S3 | Recognized-but-Complied | Recognizes this attack, yet complies anyway by deferring to the mandated migration policy. | 3 | 3.4 |
| F1 | Suspicion-Based Refusal | Refuses on prompt-internal red flags. | 16 | 18.4 |
| F2 | Empirical Recovery | Complies first, reverting to numpy after the import fails at runtime. | 33 | 37.9 |
| F3 | Silent Refusal | Uses numpy and ignores CLAUDE.md entirely, leaving no trace of deliberation. | 11 | 12.6 |
| Package | #Surrogate | #Victim | #Total |
| pandas | 85 | 341 | 426 |
| numpy | 67 | 267 | 334 |
| matplotlib | 62 | 247 | 309 |
| scipy | 17 | 68 | 85 |
| seaborn | 14 | 58 | 72 |
| Package | pandas | numpy | matplotlib | scipy |
| #Victim | 291 | 200 | 155 | 106 |
| Package | kombu | twisted | urllib3 | asgiref | werkzeug |
| #Victim | 11 | 10 | 9 | 7 | 6 |
| # | Component | #Tokens | %Tokens |
| 1 | Agent operational policies | 2,602 | 18.8 |
| 2 | Rule File Context 1: Benign developer guidelines ( AGENTS.md ) | 336 | 2.4 |
| 3 | Rule File Context 2: Injected Prompt ( AGENTS.md ) | 139 | 1.0 |
| 4 | Available-skills catalog | 4,009 | 29.0 |
| 5 | Workspace and environment context | 54 | 0.4 |
| 6 | Tool interface specifications | 4,441 | 32.1 |
| Agent Framework | Version | Timeout | Mode | Rule File |
| OpenHands | 1.16.1 | 600 s | SDK driver ( cli_mode=False ) | AGENTS.md (auto) |
| OpenCode | 1.14.37 | 600 s | --dangerously-skip-permissions | AGENTS.md (auto) |
| Aider | 0.86.2 | 600 s | --yes-always --no-git | CONVENTIONS.md ( --read ) |
| Pi Coding Agent | 0.74.1 | 600 s | -p --no-session --offline | AGENTS.md (auto) |
| Cline | 3.0.13 | 600 s | --auto-approve true | .clinerules/policy.md (auto) |
| Kilo Code | 7.3.0 | 600 s | run --auto | AGENTS.md (auto) |
| Backbone LLM | Access | Scale | Identifier |
| Qwen3-Coder-30B | Local Ollama | 30.5B (Q4_K_M) | qwen3-coder-30b |
| Qwen2.5-Coder-7B | Local Ollama | 7.62B (Q4_K_M) | qwen2.5-coder:7b |
| Devstral-Small-2-24B | Local Ollama | 24B (Q4_K_M) | devstral-small-2:24b |
| GLM4.7-Flash-30B | Local Ollama | 29.9B (Q8_0) | glm-4.7-flash:q8_0 |
| Gemma4-31B | Local Ollama | 31.3B (Q4_K_M) | gemma4:31b |
| Nemotron-3-Super | OpenRouter API | 120B-A12B | nvidia/nemotron-3-super-120b-a12b |