# File Backdoor via Bidirectional Unicode and Zero-Width Characters

- **Severity:** High
- **Signature ID:** `5f2c9a13-8d47-4b6e-a0c2-7e91d4f3b8aa`
- **CVEs:** CVE-2021-42574, CVE-2021-42694
- **MITRE ATLAS:** AML.T0051 (LLM Prompt Injection), AML.T0050 (Command and Scripting Interpreter)
- **OWASP:** LLM01 (Prompt Injection), LLM05 (Improper Output Handling)

## Summary

An attacker hides malicious instructions inside invisible Unicode characters (bidirectional text controls or zero-width joiners) embedded in text the AI agent is told to write to a file. A human reviewing the file sees normal-looking code, but the actual bytes saved to disk and later executed contain a different, hidden payload.

## How the attack works

The attacker crafts input - directly or via prompt injection - that includes invisible Unicode control characters such as bidirectional overrides or zero-width joiners, encoded raw, escaped in JSON/source, or as HTML entities. The AI agent passes this content through in a file-write tool call without stripping the hidden characters. The file that lands on disk looks clean to a code reviewer but actually contains reordered or injected logic once read by a compiler, interpreter, or shell. This is the same technique behind the public 'Trojan Source' vulnerability class, now delivered through an AI agent's write action instead of a direct commit.

## Why it matters

An organization can end up with backdoored source code or configuration files that pass visual review, letting an attacker smuggle in malicious logic that executes later - undermining code review as a security control.

## What you can do

- Run automated scans for invisible Unicode control characters (bidi overrides/embeddings/isolates and zero-width joiners) on any file an AI agent writes, before it is committed or executed.
- Configure editors, diff tools, and CI pipelines to render or flag these characters visibly instead of hiding them.
- Restrict AI agents from writing files with non-printable or bidirectional Unicode unless the content is expected (e.g. legitimate localization files with RTL scripts).
- Treat any zero-width character in an otherwise pure-ASCII file, or any explicit LTR/RTL override, as suspicious and requiring manual review.

## Known benign look-alikes

- Localization / i18n resource files (.arb, .json, .properties, .po) that legitimately embed bidi embedding or isolate marks around RTL strings. Mitigated - embedding/isolate marks are only scored when the payload contains no Hebrew/Arabic/Syriac script at all; explicit LTR/RTL OVERRIDES (U+202D/U+202E) are still reported because Unicode UAX#9 best practice never requires an override for ordinary RTL prose.
- Emoji ZWJ sequences (family/profession emoji) and Devanagari, Bengali or Persian text using ZWJ/ZWNJ as real joiners in UI strings or docs. Mitigated - zero-width characters are only scored when the payload is otherwise pure ASCII (no other non-ASCII codepoint survives stripping), so the joiner has nothing legitimate to join.
- Files intentionally starting with a UTF-8 BOM. Mitigated - a leading U+FEFF run is stripped before counting.
- Security test fixtures, linter test corpora and CI checks for Trojan Source that deliberately contain these codepoints. These WILL be reported; the action is report, never block, and the kill chain names the exact file so triage is one glance.
- Minified JavaScript or scraped web content pasted into a file with stray U+200B separators. Mitigated - the zero-width-only path additionally requires a code/script/config target path.

## References

- https://trojansource.codes/
- https://nvd.nist.gov/vuln/detail/CVE-2021-42574
- https://nvd.nist.gov/vuln/detail/CVE-2021-42694
- https://unicode.org/reports/tr36/

---
Source: https://www.netzilo.com/threats/file-backdoor-hidden-unicode
