ADR's triage stage (TriageLLM) relies entirely on LLM judgment to catch malicious conversation content — nothing in the pipeline inspects the literal characters for known prompt-injection-obfuscation techniques. Two such techniques are already part of ADR's own threat model:
- Unicode Tag Block "ASCII smuggling" (U+E0000–U+E007F): each ASCII character maps to an invisible codepoint; there's no legitimate use of this range in real text. This is a well-known, already-public technique (documented at embracethered.com, cited in the public
AITech-9.2/AISubtech-9.2.1 AI-security taxonomy). I have a merged reference implementation for detecting it in Cisco's skill-scanner project: github.com/cisco-ai-defense/skill-scanner#94.
- Bidi override/isolate characters (U+202A–U+202E, U+2066–U+2069), used to visually hide or reorder text. ADR's own benchmark already plants this exact payload in
context_providers/source_codes/mcp_servers_1/mcp_connector/mcp_connector.py:37, wired into two real tasks (110, 301, both ground_truth: "malicious") — but nothing catches it deterministically.
Confirmed by reading the code directly: TriageLLM._format_conversation() passes message content through completely unmodified, neither triage prompt mentions Unicode obfuscation as an escalation trigger, and the 17-entry threat taxonomy (threat_repository.yaml) doesn't name it under any technique. The comparison LlamaFirewall baseline in this same benchmark has no equivalent check either.
I already have a fix scoped: a deterministic pre-filter in TriageLLM.analyze() that short-circuits before any LLM call when it fires (zero cost, zero reliance on the LLM noticing hidden characters), 2 new detection_guidance entries under the existing ADR.T0002 technique (not a new top-level ID — keeps the paper-aligned 17-technique count intact), a new benchmark fixture demonstrating Tag Block smuggling end-to-end (the existing fixture only covers the bidi variant), and tests proving both the new fixture and the existing mcp_connector.py fixture are now deterministically caught. Opening this first for visibility — PR to follow.
ADR's triage stage (
TriageLLM) relies entirely on LLM judgment to catch malicious conversation content — nothing in the pipeline inspects the literal characters for known prompt-injection-obfuscation techniques. Two such techniques are already part of ADR's own threat model:AITech-9.2/AISubtech-9.2.1AI-security taxonomy). I have a merged reference implementation for detecting it in Cisco'sskill-scannerproject: github.com/cisco-ai-defense/skill-scanner#94.context_providers/source_codes/mcp_servers_1/mcp_connector/mcp_connector.py:37, wired into two real tasks (110, 301, bothground_truth: "malicious") — but nothing catches it deterministically.Confirmed by reading the code directly:
TriageLLM._format_conversation()passes message content through completely unmodified, neither triage prompt mentions Unicode obfuscation as an escalation trigger, and the 17-entry threat taxonomy (threat_repository.yaml) doesn't name it under any technique. The comparisonLlamaFirewallbaseline in this same benchmark has no equivalent check either.I already have a fix scoped: a deterministic pre-filter in
TriageLLM.analyze()that short-circuits before any LLM call when it fires (zero cost, zero reliance on the LLM noticing hidden characters), 2 newdetection_guidanceentries under the existingADR.T0002technique (not a new top-level ID — keeps the paper-aligned 17-technique count intact), a new benchmark fixture demonstrating Tag Block smuggling end-to-end (the existing fixture only covers the bidi variant), and tests proving both the new fixture and the existingmcp_connector.pyfixture are now deterministically caught. Opening this first for visibility — PR to follow.