Abstract

Inspection assumes that seeing is knowing — that if a reviewer looks at a document and it appears clean, it is clean. This piece studies the failure of that assumption. We start with Simmons's 1983 subliminal channel, where a hidden message rides inside a legitimate-looking one and passes the inspector undetected, and generalize it to the many carriers that hide data in plain sight: invisible Unicode, zero-width characters, whitespace, homoglyphs, metadata, and image steganography. We then argue that AI agents are uniquely exposed, because the content a human reviews and the content a model consumes can diverge — a page that reads as ordinary to a person can carry an instruction the model obeys. The defense is to collapse that divergence: canonicalize and strip hidden carriers so the artifact you inspect is exactly the artifact the machine consumes.

Security inspection runs on a comfortable belief: if you look at something and see nothing wrong, there is nothing wrong. But 'looking' is a channel with its own blind spots, and a message can be built so that what a human sees and what a machine reads are two different things. A document can display as an ordinary memo while carrying, in characters your screen never renders, an instruction meant for whatever software will parse it. The payload is not encrypted or obviously suspicious. It is simply invisible to the inspector and perfectly legible to the consumer — hidden in plain sight.

The assumption: unseen means absent

Review, moderation, and approval all rest on one premise: that a competent look reveals what is present. If a reviewer reads a message, an image, or a file and finds nothing hidden, we conclude nothing is hidden. The assumption equates the reviewer's perception with the artifact's actual content.

Gustavus Simmons formalized the failure in 1983 as the subliminal channel, using the image of two prisoners passing notes through a warden. The warden reads every note and will block anything that looks like an escape plan. Simmons showed that the prisoners can embed a hidden message inside otherwise-innocent, even cryptographically-signed, communications, so the warden sees only benign content while the real message passes through. The channel is subliminal precisely because it is undetectable to the inspector by construction.

This class is relational between an inspector and a consumer: the inspector sees a clean artifact, the consumer receives a different one, and the gap is engineered so the inspector cannot perceive it. Nothing the reviewer sees is wrong; the problem is everything they cannot.

🛡️ Countermeasures
  • Stop equating 'the reviewer saw nothing' with 'nothing is there'; treat inspection as a channel with known blind spots.
  • Define the artifact by what the consumer will actually parse, not by what a human renders, and inspect that.
  • Assume a determined sender can hide content the inspector cannot see, and design to strip rather than to spot it.

The subliminal channel: a message inside a message

A subliminal channel hides the existence of a message, not just its content. That distinguishes it from ordinary encryption: an encrypted note looks like a secret and invites scrutiny; a subliminal note looks like nothing at all. The carrier is a legitimate object — a signature, a document, an image — with enough redundancy or unused capacity to hold a second message that does not disturb its innocent appearance.

The power of the technique is that the inspector, doing their job perfectly, is defeated by construction. They can read the whole visible artifact, verify its signature, and check its content, and still miss the payload, because the payload lives in the degrees of freedom the inspection does not examine — the exact bits that were free to vary without changing what the inspector perceives.

The countermeasure is to remove those degrees of freedom. If the artifact is canonicalized to a single normal form that discards unused capacity, the hidden message has nowhere to ride, and what the inspector sees becomes all there is.

A hidden payload rides inside a legitimate-looking carrier and passes an inspector who sees only benign content. Past the warden what the inspector examines Carrier + payload looks benign Inspector sees clean Consumer reads payload Hidden message acts undetected passes review delivers payload executes
A hidden payload rides inside a legitimate-looking carrier and passes an inspector who sees only benign content.
🛡️ Countermeasures
  • Canonicalize artifacts to a single normal form that discards unused capacity, so there are no free bits for a hidden message to occupy.
  • Inspect the consumed representation (the exact bytes the parser or model receives), not the human-rendered view.
  • Prefer stripping hidden-capacity carriers over trying to detect specific payloads, which a well-designed channel evades.

Carriers: where text and data hide messages

The modern subliminal channel rarely needs cryptography; ordinary formats offer abundant hiding places. Text can carry invisible or zero-width Unicode characters, homoglyphs that look identical but encode differently, trailing whitespace, and directionality controls; documents and images carry metadata fields, comments, and — for images and audio — least-significant-bit encodings that change the file imperceptibly. In each case the rendered result looks normal while the underlying bytes carry more.

The security consequence is a reliable split between the human view and the machine view. A reviewer reading rendered text sees a clean paragraph; a parser reading the raw bytes sees additional characters. A moderator viewing an image sees a photo; a model ingesting its pixels or metadata sees an embedded instruction. The inspector and the consumer are looking at genuinely different things.

The countermeasure is normalization: decode to a canonical character set, strip non-rendering and directionality characters, remove metadata, and re-encode media so that hidden capacity is destroyed before anything downstream consumes the artifact.

The human-rendered view looks clean while the raw bytes the machine reads carry a hidden payload. Two views of one file HUMAN VIEW MACHINE VIEW Human sees clean text / image Looks safe review passes Machine reads raw bytes Hidden payload invisible carrier perceived parsed
The human-rendered view looks clean while the raw bytes the machine reads carry a hidden payload.
🛡️ Countermeasures
  • Normalize text to a canonical form and strip zero-width, invisible, directionality, and confusable characters before use.
  • Remove metadata and re-encode images and audio to destroy steganographic capacity before a model or parser consumes them.
  • Flag and quarantine content whose raw bytes differ meaningfully from its rendered appearance for human re-review.

The AI angle: an instruction only the model sees

Agents make the human-versus-machine split dangerous, because the machine acts. A web page, an email, a document, or an image passed to a model can contain an instruction that is invisible to the person who approved the content but fully legible to the model that reads the raw text or pixels. The reviewer signs off on an ordinary-looking file; the model, consuming what the reviewer could not see, follows the hidden directive.

The carriers map directly onto the workload. Zero-width and invisible characters smuggle a prompt into text a moderator reads as clean; homoglyphs disguise a command; white-on-white or off-canvas text hides in a rendered document; and a vision model can read an instruction steganographically embedded in an image that looks like an ordinary picture. None of it trips a human review, because human review is exactly the channel it was built to evade.

The countermeasures are the normalization ones applied at the model's front door: strip and canonicalize all incoming text, re-encode incoming media to destroy hidden capacity, and — because stripping is never perfect — treat any content a model consumes as untrusted data rather than instruction, so a smuggled directive has no authority even if it survives.

The goal is reached by hiding a directive in a carrier the human reviewer cannot see but the model reads. Smuggling an instruction to the model Make the model obey unseen by human review vs input Hide in a carrier invisible / image Passes human review looks clean Model reads & acts follows directive
The goal is reached by hiding a directive in a carrier the human reviewer cannot see but the model reads.
🛡️ Countermeasures
  • Strip and canonicalize all incoming text (remove zero-width, invisible, directionality, and confusable characters) before it reaches the model.
  • Re-encode incoming images and audio to destroy steganographic capacity, and screen for text hidden by rendering tricks.
  • Treat all model-consumed content as untrusted data, not instruction, so a surviving hidden directive carries no authority.

Why 'looks clean' is not 'is clean'

It is tempting to trust a careful human review. The subliminal channel is defined by defeating exactly that. A channel is only subliminal if the inspector cannot perceive it, so a well-built one is undetectable by the very inspection you would rely on; adding more careful human reviewers does not help, because they share the same perceptual blind spots the channel targets. The inspection channel and the consumption channel are different by nature, and the attacker lives in the difference.

So the honest position is that you cannot look your way to safety here. What closes the gap is not better perception but transformation: reduce the artifact to a canonical form that both the inspector and the consumer see identically, so there is no hidden capacity and no divergence for a payload to inhabit. Detection helps at the margins, but elimination of the hiding places is the durable move.

Framed that way, the problem becomes an equivalence goal: make the inspected artifact and the consumed artifact provably the same object.

⚠️
You cannot review away a subliminal channel. A channel is subliminal only if inspection cannot see it; more careful reviewers share the same blind spots, so safety comes from stripping hiding places, not from looking harder.
🛡️ Countermeasures
  • Aim for equivalence: transform artifacts so the inspected and consumed representations are provably identical, with no hidden capacity.
  • Rely on elimination (canonicalization and stripping) over detection, using steganalysis only as a supplementary signal.
  • Re-evaluate when a new format or carrier enters the pipeline, since each adds fresh hiding places to remove.

Finding and stripping hidden carriers

Because the attack is a divergence between rendered and raw content, you can hunt it by comparing the two. Canonicalize an artifact to its visible normal form, then diff that against the raw bytes; a meaningful difference — extra characters, non-rendering code points, unexpected metadata, statistical anomalies in an image — flags a possible carrier. The pipeline then strips or re-encodes so the consumed artifact matches the inspected one.

For an agent, the same discipline runs at ingestion: normalize incoming text and re-encode incoming media before the model reads them, and log any content whose raw form differed from its rendered form for review. The useful signal is simple and adversarial: does what the model will read match what a person would see?

The harness stays strictly defensive: it normalizes and inspects your own incoming content and plants your own benign markers to confirm stripping works; it never builds a covert channel to smuggle data into someone else's system.

Canonicalize the visible form, diff it against the raw bytes, and strip or re-encode any hidden carrier before use. Render, compare, strip Canonical view what a human sees Diff vs raw bytes what a machine reads Strip / re-encode destroy capacity Quarantine on mismatch
Canonicalize the visible form, diff it against the raw bytes, and strip or re-encode any hidden carrier before use.
🛡️ Countermeasures
  • Diff the canonical rendered form against the raw bytes at ingestion and quarantine any meaningful divergence for review.
  • Strip non-rendering characters and re-encode media so the consumed artifact matches the inspected one, then log what was removed.
  • Threats to validity: a diff catches the carriers you canonicalize for — combine it with treating consumed content as untrusted so a missed payload still lacks authority.

The discipline: inspect what the machine consumes

Every countermeasure here is one refusal: do not trust that a clean-looking artifact is clean. Make the inspected artifact identical to the consumed one — canonicalize, strip hidden carriers, re-encode media — so there is no divergence for a subliminal message to exploit, and treat whatever a machine consumes as untrusted data so a surviving payload has no authority.

The reusable artifact is an assumption-ledger entry: the unstated assumption is that what a reviewer cannot see is not there; the reason it fails is that carriers hold hidden capacity and the inspection channel differs from the consumption channel; the tell is any divergence between the rendered and raw forms of an artifact; and the assumption-free control is canonicalization, carrier-stripping, and consuming untrusted content as data only. Carry that entry to any content boundary — a moderation queue or a model's input — and ask the one question this class demands.

Ask it wherever something is reviewed before a machine acts on it: is what I inspected exactly what the machine will consume? Where the answer is 'not quite', a subliminal channel has room to live — invisible to you, obeyed by the machine.

🛡️ Countermeasures
  • Adopt one rule per content boundary — canonicalize, strip, and treat consumed content as data — and record how each artifact is normalized.
  • Instrument ingestion to log rendered-versus-raw divergences so hidden carriers become visible events.
  • Audit the model's input path specifically: is incoming text and media stripped of hidden capacity before the model reads it?

Key takeaways

  • A subliminal channel hides a message inside a legitimate-looking carrier so it passes an inspector who sees only benign content — undetectable by inspection by design.
  • The broken assumption is that what a reviewer cannot see is not there; the inspection channel and the consumption channel differ, and the payload lives in the gap.
  • Ordinary formats offer the hiding places: invisible and zero-width Unicode, homoglyphs, whitespace, metadata, and image or audio steganography.
  • Agents are uniquely exposed because the machine acts: a hidden instruction invisible to a human reviewer can be fully legible to the model that reads the raw text or pixels.
  • You cannot review your way out — more careful reviewers share the same blind spots — so defense strips hiding places and makes the inspected artifact identical to the consumed one.
  • Defend by canonicalizing, diffing rendered against raw, stripping and re-encoding carriers, and treating all consumed content as untrusted data with no authority.

Practitioner Toolkit

Copy-paste, strictly defensive artifacts you can use today. Nothing here attacks a real system.

Subliminal-carrier review checklistchecklist

Run this at every content boundary a machine will consume.

  • Define the artifact by the bytes the consumer parses, not by the human-rendered view.
  • Canonicalize text and strip zero-width, invisible, directionality, and confusable characters.
  • Remove metadata and re-encode images and audio to destroy steganographic capacity.
  • Diff the rendered form against the raw bytes and quarantine meaningful divergences.
  • Treat all model-consumed content as untrusted data, not instruction.
  • Log what was stripped so hidden carriers become auditable events.
🔒Ingestion-normalization rulepolicy

A drop-in gate for content entering a model.

def ingest(content):
    clean = strip_hidden(normalize(content))   # remove invisible/zero-width, metadata
    if rendered(content) != rendered(clean):
        quarantine(content, reason="hidden carrier removed")
    if raw_differs(content, rendered(content)):
        flag_for_review(content)                # raw carries more than it shows
    return as_untrusted_data(clean)             # never as instruction
Normalize and strip, compare rendered vs raw, then consume only as data.
🧪Rendered-vs-raw diff probeharness

Reveals hidden carriers in your own incoming content.

def carrier_probe(content):
    seen = canonical_visible_form(content)   # what a person perceives
    read = raw_consumed_bytes(content)        # what the parser/model gets
    if meaningful_diff(seen, read):
        alert("hidden carrier detected", diff(seen, read))
# Inspect your own incoming content; never build a covert channel into others'.
Compare what a human would see to what the machine reads; a divergence is a hidden carrier.
🚀Minimum viable defense — do these firstquickstart

The highest-leverage steps before deeper hardening.

  • Strip zero-width, invisible, and confusable characters from all incoming text.
  • Remove metadata and re-encode incoming images and audio.
  • Diff rendered against raw and quarantine divergences.
  • Treat everything a model consumes as untrusted data, never as instruction.

Glossary

Subliminal channel
A hidden channel that conceals the existence of a message inside a legitimate-looking carrier, undetectable to an inspector by design.
Steganography
Hiding the existence of a message within an innocent-looking object, as opposed to hiding only its content.
Carrier
The legitimate object — text, document, image, signature — whose unused capacity holds a hidden message.
Zero-width / invisible characters
Code points that do not render visibly but remain in the bytes a parser or model reads.
Homoglyph
A character that looks identical to another but encodes differently, usable to disguise hidden content.
Canonicalization
Reducing an artifact to a single normal form that discards unused capacity, removing hiding places.
Rendered vs raw divergence
The difference between what a human sees rendered and what a machine reads in the raw bytes — the tell for a hidden carrier.

References

  1. Simmons, The Prisoners' Problem and the Subliminal Channel (CRYPTO 1983)
  2. Petitcolas, Anderson & Kuhn, Information Hiding — A Survey (Proceedings of the IEEE, 1999)
  3. Unicode Technical Report #36: Unicode Security Considerations
  4. MITRE ATLAS (Adversarial Threat Landscape for AI Systems)
  5. OWASP Top 10 for Large Language Model Applications
  6. NIST AI Risk Management Framework (AI RMF 1.0)