# File Backdoor via Invisible Unicode in Agent File Write

- **Severity:** High
- **Signature ID:** `3f0b9c72-6d54-4a1e-9b83-1c7ad6e5f240`
- **CVEs:** CVE-2021-42574, CVE-2021-42694
- **MITRE ATLAS:** AML.T0051.001 (Indirect)
- **OWASP:** LLM01 (Prompt Injection), LLM04 (Data and Model Poisoning)

## Summary

An attacker hides malicious instructions inside invisible Unicode characters that get written into files an AI agent creates or edits. A human or reviewer looking at the file sees normal, harmless text, but the interpreter or shell reads something different and executes the hidden payload.

## How the attack works

The attacker gets content containing Unicode bidirectional override characters (which can reverse how text displays) or clusters of zero-width characters (invisible spacing/joining marks) into the agent's context, for example through a prompt injection or poisoned input. The agent then writes this content into an executable script, a configuration file, a persistence mechanism, or its own instruction file. Because the special characters are invisible or only change display order, anyone reviewing the file's rendered appearance sees clean, innocuous code. The interpreter, shell, or agent runtime, however, processes the actual bytes, which can contain a different, malicious command or logic. This mirrors the Trojan Source technique (CVE-2021-42574 / CVE-2021-42694) but applied to an AI agent's own workspace, giving the planted backdoor a good chance of surviving code review.

## Why it matters

An attacker can plant a backdoor or malicious logic in a file that looks clean to reviewers, achieving persistence in a system while evading manual and even AI-assisted code review.

## What you can do

- Run a Unicode-aware linter or pre-commit check that flags bidirectional control characters and zero-width character clusters in source, config, and persistence files.
- Configure code review tooling and diff viewers to render or highlight invisible/control Unicode characters rather than silently displaying their visual effect.
- Restrict or sanitize the character set an AI agent is allowed to write into executable, configuration, or instruction files, stripping bidi controls and clustered zero-width characters by default.
- Treat any agent-written file containing these characters as suspicious and manually inspect the raw bytes before deployment, especially for files outside legitimate localisation/i18n content.

## Known benign look-alikes

- Localisation and i18n resource files (.po, .xlf, .strings, .arb, .json) that carry Arabic, Hebrew, Persian, Devanagari, Bengali, Tamil, Thai or Burmese strings with legitimate bidi isolates or ZWNJ - suppressed by filter_natural_language, which requires a run of at least four script characters so a single decoy character cannot silence the rule.
- Emoji ZWJ sequences (family, profession and flag emoji) in README/markdown written by an agent - structurally cannot match; U+200D is excluded from the cluster pattern and the in-token pattern requires ASCII on both sides.
- A stray UTF-8 BOM at the head of a file, or a single zero-width space picked up from scraped web content - a lone invisible character never matches; the cluster pattern needs four and the in-token pattern needs two.
- Trojan Source detectors, Unicode sanitisers and their advisories/test fixtures, which embed the raw or escaped control characters on purpose - suppressed by filter_security_research and filter_test_fixture.
- Source code that legitimately manipulates bidi codepoints (e.g. a text-shaping or terminal-rendering library referencing 0x202E) - can still match sel_bidi_encoded; this is why the rule is report-only.

## References

- https://trojansource.codes/
- https://nvd.nist.gov/vuln/detail/CVE-2021-42574
- https://nvd.nist.gov/vuln/detail/CVE-2021-42694
- https://attack.mitre.org/techniques/T1027/

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