Join our Newsletter — 33% off our NHI Course
Home› Guides› ASCII Smuggling and Invisible Prompts: Detecting and Stripping…
Guide LLM & GenAI Security

ASCII Smuggling and Invisible Prompts: Detecting and Stripping Hidden Unicode in LLM Inputs

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 8 November 2026 12 min read
On this page

ASCII smuggling hides instructions or data inside text using Unicode characters that render as nothing on screen but are still read by a large language model. The usual carrier is the Unicode Tags block, U+E0000 to U+E007F, whose characters mirror printable ASCII one for one, so any English sentence can be written in a form a human reviewer cannot see. The same trick works in reverse: a model can be told to encode stolen data invisibly inside a link or a reply. This guide explains what the technique is, how the encoding works, why it matters for assistants and agents, and how to detect and strip it in an input pipeline. It is written for engineers building LLM applications and for security teams testing them. It goes deeper on the Unicode mechanics than the Prompt Injection Guide, which covers the wider attack class.

Key takeaways

  • It is a hiding technique, not a new attack class. ASCII smuggling is a way to deliver prompt injection (MITRE ATLAS AML.T0051) and to exfiltrate data, filed by ATLAS under AML.T0068 LLM Prompt Obfuscation.
  • The Tags block is the main carrier. Each tag character is its ASCII counterpart plus 0xE0000, so "A" (U+0041) becomes U+E0041, and the result is invisible in most interfaces.
  • Strip on the way in and the way out. Remove tag characters before text reaches the model and again before model output is rendered, logged or sent onward.
  • One pass is not always enough. AWS showed that in UTF-16 runtimes such as Java, removing characters can let surrogate halves recombine into new tag characters, so repeat until the text stops changing.
  • Stripping reduces risk, it does not end prompt injection. Visible injection, other encodings and hidden HTML still work, so keep least privilege and output controls in place.

What it is

The term ASCII smuggling was popularised by security researcher Johann Rehberger in January 2024, when he published a proof of concept against ChatGPT and a small encoder and decoder tool called ASCII Smuggler. His point was simple: the Unicode Tags block mirrors ASCII, models trained on web text have learnt to read it, and user interfaces show nothing. A paragraph can therefore carry a second, hidden paragraph that only the model sees.

The Unicode Standard (code charts, version 18.0) defines the Tags block as U+E0000 to U+E007F. U+E0001 LANGUAGE TAG is deprecated and the chart states that using tag characters to convey language tags is strongly discouraged. U+E0020 TAG SPACE to U+E007E TAG TILDE mirror the printable ASCII range, and U+E007F CANCEL TAG is a terminator. The block survives because emoji use it: the flag of England is a black flag emoji followed by tag letters and a cancel tag, which is why some flags break when tags are stripped.

"Invisible prompt" is the broader term. It covers any instruction a human cannot see but a model ingests, including zero-width characters, white or zero-size text, hidden HTML and text in image metadata. ATLAS AML.T0068 lists those rendering tricks alongside encodings. This guide concentrates on the Unicode carriers, because they pass through copy and paste, email, chat, documents, code and APIs intact.

How it works

The encoding is arithmetic. Take each printable ASCII character, add 0xE0000 to its code point, and append the result to an innocent visible string. In UTF-8 each tag character takes four bytes; in UTF-16 (Java, JavaScript, .NET strings) each becomes a surrogate pair. Most fonts have no glyph and most renderers treat the characters as ignorable, so the text looks normal in a browser, a mail client or a chat window. A tokenizer still turns them into tokens, and capable models decode them.

CarrierCode pointsWhat it can doHandling
Unicode tag charactersU+E0000 to U+E007FCarry a full hidden ASCII message: instructions in, stolen data outStrip everywhere except approved emoji flag sequences, if those must be kept
Zero-width charactersU+200B, U+200C, U+200D, U+2060, U+FEFFSplit keywords to defeat filters; encode bits as patterns of charactersRemove from model input; keep U+200D only inside emoji sequences if needed
Bidirectional controlsU+202A to U+202E, U+2066 to U+2069Reorder what a human sees versus what a parser reads (Trojan Source, CVE-2021-42574)Flag in code and configuration; remove from prompts
Variation selectorsU+FE00 to U+FE0F, U+E0100 to U+E01EFAttach hidden data to a visible character, often an emojiAllow U+FE0E and U+FE0F after emoji only; strip the rest
Look-alike charactersMany scriptsMake "paypal" and "pаypal" look identical; evade allowlistsConfusable and mixed-script checks; see the Unicode Security guide

Two attack directions follow from this.

  • Inbound (hidden instructions): an attacker plants tag text in content the model will read: an email, a shared document, a web page, a ticket, a code comment or a tool description. When a user asks the assistant to summarise it, the model follows the hidden instruction. The AWS Security Blog example is an email assistant told, invisibly, to delete the inbox. This is indirect prompt injection (AML.T0051.001) with a better disguise.
  • Outbound (hidden data): an injected instruction tells the model to encode sensitive data as tag characters, often inside a hyperlink. Rehberger's August 2024 disclosure against Microsoft 365 Copilot chained automatic tool invocation (searching the user's mail) with a rendered link whose invisible part carried sales figures and an MFA code to an attacker's server when clicked. ATLAS records the pieces as AML.T0086 Exfiltration via AI Agent Tool Invocation and AML.T0077 LLM Response Rendering. He reported the issue in January 2024; by July the reproduction no longer worked, and Microsoft did not publish details of the fix.

Human review does not help much. The same research notes that a person can approve, copy or forward text that looks clean, so a human in the loop can pass the hidden payload along.

Why it matters

Most LLM defences assume someone can see the malicious text: a reviewer reading a document, a moderator scanning a prompt log, a developer reading a pull request. Invisible carriers break that assumption in four places.

  • Agents with tools: an assistant that can send mail, call APIs or browse turns a hidden instruction into an action under the user's identity or a service account. Excessive agency (OWASP LLM06) is what makes the hiding worth the effort.
  • Logs and audit: many log viewers render tag characters as nothing, so an investigator reading the stored prompt sees a benign request. Store a raw or escaped copy.
  • Code and supply chain: the GlassWorm campaign hid malicious JavaScript in VS Code extensions using invisible Unicode, so the code looked like blank lines to reviewers and to static analysis. AI coding assistants read the same files and comments. See the GlassWorm VS Code Extension Worm Guide.
  • Keyword guardrails: filters that match words like "ignore previous instructions" miss text written in tags or split with zero-width joiners. Microsoft's Prompt Shields documentation lists encoding attacks as a category, but its page does not describe invisible characters specifically, so test your own guardrail rather than assume coverage.

Detecting and stripping hidden Unicode

Put a normalisation step at every boundary where untrusted text enters or leaves the model. OWASP ASVS 5.0 requirement V1.1.1 asks that input is decoded into a canonical form once, before validation; apply the same principle to Unicode.

  1. Inventory the entry points. User prompts, retrieved documents (RAG), email and calendar connectors, web fetch tools, MCP tool descriptions and outputs, file uploads, and system prompts loaded from repositories.
  2. Log before you block. For two weeks, count tag, zero-width, bidi and variation selector code points per source without changing the text. This shows legitimate use (flags, Indic scripts that need U+200C and U+200D, Arabic and Hebrew bidi) and avoids breaking real users.
  3. Strip tag characters by default. Remove U+E0000 to U+E007F. In Python, which works on code points, a single pass that also drops lone surrogates (U+D800 to U+DFFF) is sufficient according to AWS. In Java and other UTF-16 runtimes, repeat the removal until the string no longer changes and remove orphaned surrogates.
  4. Apply a context policy to the rest. Remove zero-width and bidi controls from prompts and tool arguments; keep U+200C and U+200D only where the language or emoji sequence needs them. Decide whether flag emoji matter enough to allowlist the exact tag sequences.
  5. Record what was removed. Log source, count and a decoded preview (tags minus 0xE0000) to the security log, not to the model. A document with 400 hidden ASCII characters is an incident signal, not noise.
  6. Sanitise output too. Strip the same code points from model responses before rendering, especially inside URLs and Markdown links, and block auto-rendered images and links to unapproved domains (OWASP LLM05). See the OWASP LLM05 Improper Output Handling Guide.
  7. Test and keep a rollback. Add tag-encoded and zero-width test strings to the red team suite and CI, run in log-only mode on a pilot, then enforce. Keep the filter behind a feature flag so a false positive on a language can be turned off per source in minutes.

Block or sanitise? Sanitising (removing characters, then processing) keeps the user experience and is the right default for documents and mail. Blocking (rejecting the request) suits high-risk agent actions and API inputs where no legitimate caller sends tag characters. AWS notes that Amazon Bedrock Guardrails denied topics can block, but not sanitise, tag characters, which is why it pairs them with a separate sanitiser. Small teams can start with a single shared sanitiser library; larger organisations should enforce it centrally in an AI gateway so every application inherits it. See the AI Guardrails and AI Firewalls Guide.

Measure it: track (1) the share of LLM entry points behind the sanitiser, (2) hidden characters removed per 10,000 requests by source, (3) documents or emails with more than a threshold of tag characters, (4) red team pass rate for invisible payloads, inbound and outbound, and (5) false positive reports per language after enforcement.

Common misconceptions

  • "If I cannot see it, the model ignores it." Models read tokens, not pixels. Tag characters tokenise, and current models decode them.
  • "Unicode normalisation (NFC or NFKC) removes them." Normalisation forms do not delete tag or zero-width characters; you need an explicit removal step.
  • "A guardrail product handles it." Some do, some block rather than clean, and some match only visible text. Prove it with tag-encoded test cases before relying on it.
  • "Human approval stops it." The approver sees clean text and can forward the hidden payload. Display a warning or escaped view when hidden characters are present.
  • "The vendor fixed it." Fixes such as the Copilot change addressed specific rendering paths. The underlying prompt injection risk remains, as the researcher noted, so your own application needs its own control.

Common failures in practice: sanitising user prompts but not retrieved documents or tool output; stripping once in a UTF-16 runtime; logging the rendered prompt so investigators see nothing; stripping zero-width joiners globally and breaking Indic and emoji text, which then gets the filter switched off; and allowing the model to emit links to any domain.

FrameworkReferenceRelevance
MITRE ATLASAML.T0068 LLM Prompt ObfuscationThe hiding technique itself
MITRE ATLASAML.T0051.001 Indirect prompt injectionInbound delivery through documents, mail and web content
MITRE ATLASAML.T0086, AML.T0077, AML.T0057Exfiltration through tool calls, rendered links and data leakage
MITRE ATT&CK v20T1027 Obfuscated Files or InformationSame idea in conventional malware and code (GlassWorm)
OWASP Top 10 for LLM Applications 2025LLM01 Prompt Injection, LLM05 Improper Output Handling, LLM06 Excessive AgencyRisk categories the technique feeds
NIST SP 800-53 Rev. 5SI-10 Information Input Validation, SI-15 Information Output Filtering, SI-4 System MonitoringSanitiser, output filter and logging of removals
NIST CSF 2.0ID.RA-01Record invisible-character exposure as a vulnerability in each LLM asset
OWASP ASVS 5.0V1.1.1Decode to a canonical form once, before validation

Neighbouring topics: homoglyph and mixed-script attacks (look-alike characters), Trojan Source bidi reordering in code (CVE-2021-42574, with the homoglyph variant CVE-2021-42694), hidden HTML and CSS text in web pages, and image-borne instructions for multimodal models. Testing approaches are in the AI Red Teaming Guide.

Where identity fits: the damage from a hidden instruction is bounded by what the agent's identity can do. Give assistants scoped, short-lived credentials, separate read and write tools, and require confirmation for actions that send data out. A tag-encoded instruction that reaches an agent with read-only access to one mailbox is an annoyance; the same instruction reaching an agent with a broad API key is a breach.

Practitioner checklist

  • List every path by which untrusted text reaches a model, including tool descriptions and tool output.
  • Run a log-only census of tag, zero-width, bidi and variation selector code points per source.
  • Strip U+E0000 to U+E007F on input and output; loop until stable in UTF-16 runtimes and remove lone surrogates.
  • Apply a per-context policy for zero-width joiners and bidi controls rather than a blanket ban.
  • Store raw or escaped prompts in security logs and alert on documents with large hidden payloads.
  • Restrict rendered links and images in model output to approved domains.
  • Add inbound and outbound invisible payload cases to red team and CI tests.
  • Scope agent credentials so a hidden instruction cannot reach sensitive actions without confirmation.

Standards and references

Related NHI Mgmt Group resources: Prompt Injection Guide · Unicode Security · LLM Security Guide · AI Guardrails and AI Firewalls Guide · MCP Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 8 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org