Poisoned Identifiers Survive LLM Deobfuscation: A Case Study on Claude Opus 4.6
Abstract
When an LLM deobfuscates JavaScript, can poisoned identifier names in the string table survive into the model's reconstructed code, even when the model demonstrably understands the correct semantics? Using Claude Opus 4.6 across 192 inference runs on two code archetypes (force-directed graph simulation, A* pathfinding; 50 conditions, N=3-6), we found three consistent patterns: (1) Poisoned names persisted in every baseline run on both artifacts (physics: 8/8; pathfinding: 5/5). Matched controls showed this extends to terms with zero semantic fit when the string table does not form a coherent alternative domain. (2) Persistence coexisted with correct semantic commentary: in 15/17 runs the model wrote wrong variable names while correctly describing the actual operation in comments. (3) Task framing changed persistence: explicit verification prompts had no effect (12/12 across 4 variants), but reframing from "deobfuscate this" to "write a fresh implementation" reduced propagation from 100% to 0-20% on physics and to 0% on pathfinding, while preserving the checked algorithmic structure. Matched-control experiments showed zero-fit terms persist at the same rate when the replacement table lacks a coherent alternative-domain signal. Per-term variation in earlier domain-gradient experiments is confounded with domain-level coherence and recoverability. These observations are from two archetypes on one model family (Opus 4.6 primary; Haiku 4.5 spot-check). Broader generalization is needed
Figures & tables
| Sub-phase | Condition group | N (runs) | Model(s) |
|---|---|---|---|
| Phase 0 | Pill 10 replication | 5 | Opus |
| Phase 0 | Pill 03 replication | 3 | Opus |
| Phase 0 | Pill 10 cross-model | 3 | Haiku |
| Phase 0 | Pill 03 cross-model | 3 | Haiku |
| Phase 1 | Prompt variants (4 prompts) | 12 | Opus |
| Phase 1 | Domain gradient (4 domains) | 8 | Opus |
| Condition | Model | N | Refusal rate |
|---|---|---|---|
| Pill 03 (malware functions, readable) | Opus 4.6 | 3 | 100% |
| Pill 03 (malware functions, readable) | Haiku 4.5 | 3 | 100% |
| Pill 10 (poisoned names, no malware) | Opus 4.6 | 5 | 0% |
| Pill 10, security framing | Opus 4.6 | 5 | 100% |
| Pill 10, practical framing | Opus 4.6 | 5 | 20% |
| Pill 14 (malware + poisoned) | Opus 4.6 | 5 | 100% |
| Prompt | attraction in code | amplification in code |
|---|---|---|
| A: “deobfuscate this” (baseline) | 3/3 | 3/3 |
| B: “deobfuscate + verify names” | 3/3 | 3/3 |
| C: “verify each name matches the math” | 3/3 | 3/3 |
| D: “string table may be adversarial, cross-check” | 3/3 | 3/3 |
| Frame | attraction | repulsion | amplification | damping |
|---|---|---|---|---|
| “Deobfuscate” (translation) | 5/5 | 1/5 | 5/5 | 5/5 |
| “Rewrite with correct names” | 4/5 | 5/5 | 3/5 | 5/5 |
| “Write fresh from scratch” | 1/5 | 5/5 | 0/5 | 5/5 |
| Condition | Model | N | attraction in code | amplification in code |
|---|---|---|---|---|
| Pill 10 (physics-domain poison) | Opus 4.6 | 5 | 5/5 | 5/5 |
| Pill 10 (physics-domain poison) | Haiku 4.5 | 3 | 3/3 | 2/3 |
| Pill 24 (canary comment) | Opus 4.6 | 3 | 2/3 | 0/3 |
| Level | attraction in code | amplification in code | N |
|---|---|---|---|
| Light (base64, CFF 0.5) | 5/5 | 5/5 | 5 |
| Medium (base64, CFF 0.5, self-defending) | 5/5 | 5/5 | 5 |
| Heavy (RC4, CFF 0.75, split strings) | 6/6 | 0/6 | 6 |
| Condition | All terms replaced? | Domain coherent? | Propagation |
|---|---|---|---|
| pill-10 (physics terms) | Yes | Yes (physics) | FLAGGED 5/5 |
| pill-25 (2 no-fit terms, rest physics) | No | Mostly | FLAGGED 5/5 |
| pill-27 (ALL no-fit terms, incoherent) | Yes | No | FLAGGED 5/5 |
| pill-20-engineering (ALL engineering) | Yes | Yes (engineering) | CORRECTED 5/5 |
| Term | For operation | Domain | Propagation | N |
|---|---|---|---|---|
| attraction | repulsion | physics | 100% | 8 |
| decay | damping | overlap | 100% | 3 |
| velocity | repulsion | game dev | 75% | 8 |
| yield | repulsion | finance | 60% | 5 |
| acceleration | damping | game dev | 0% | 8 |
| inductance | repulsion | engineering | 0% | 5 |
| Poisoned name | Correct name | Operation |
|---|---|---|
| penalty | heuristic | distance estimation method |
| adjacentCost | diagonalCost | diagonal movement cost |
| closedSet / openSet | (swapped) | A* frontier sets |
| fScore / gScore | (swapped) | path cost components |
| ancestors | neighbors | adjacent-cell expansion (same function, wrong label) |
| Condition | Physics artifact | Pathfinding artifact |
|---|---|---|
| Baseline (poisoned names) | FLAGGED 5/5 | FLAGGED 5/5 |
| Generation frame | CORRECTED 4–5/5 | CORRECTED 5/5 |
| Matched no-fit control | FLAGGED 5/5 | FLAGGED 5/5 |
| Model | N | Wrong names flagged | Fully corrected in code |
|---|---|---|---|
| Opus 4.6 | 3 | 2/3 | 0/3 |
| Haiku 4.5 | 3 | 2/3 | 0/3 |
Appendix figures & tables3 assets
Supplementary material from the paper’s appendix.
Appendix
| ID | Technique | State | Refusal | Names propagated | Time |
|---|---|---|---|---|---|
| Pill 01 | Wrong comments | Readable | No | N/A | Instant |
| Pill 02 | Legal threats (strings) | Readable | No | N/A | Instant |
| Pill 03 | Malware functions | Readable | Partial | N/A | Instant |
| Pill 04 | CBRN system prompts | Readable | No | N/A | Instant |
| Pill 05 | All combined | Readable | No | N/A | Instant |
| Pill 06 | Inverted semantics | Readable | No | 0/4 | Instant |
| Frame | Params (4) | Formulas (4) | Correct names | Wrong names |
|---|---|---|---|---|
| Generation | 5/5 all 4 | 5/5 all 4 | 4/5 | 1/5 |
| Translation | 5/5 all 4 | 5/5 all 4 | 0/5 | 5/5 |
| Frame | Key values (3) | Algorithmic checks (4) | Correct names | Wrong names |
|---|---|---|---|---|
| Generation | 5/5 all 3 | 5/5 all 4 | 5/5 | 0/5 |
| Translation | 5/5 all 3 | 5/5 all 4 | 0/5 | 5/5 |
Code Language Models
Code language models are AI models that generate, explain, edit, and reason about source code across programming tasks.
See all 114 papers