BACK TO BLOG

Font steganography

THEY LIVE, WE SLEEP

In John Carpenter’s 1988 film They Live, the protagonist discovers special sunglasses that reveal hidden messages in advertising. “OBEY” becomes visible behind billboards. “CONSUME” lurks within magazine ads. The world is full of subliminal control - if you know how to see it.

But this subliminal control is not limited to the movies, your browser can do it too! Only when using the right lens can you see the truth of what is in front of your eyes.

THE FONT IS THE KEY

The steganography demo on this site displays “OBEY CONSUME CONFORM” in the HTML source. But when rendered with a custom font, it transforms into something entirely different. The document never changes. Only the rendering does.

This isn’t JavaScript text replacement. This isn’t CSS content injection. The font itself intercepts specific character sequences and substitutes them with different glyphs at render time.

HOW OPENTYPE SUBSTITUTION WORKS

OpenType fonts support a feature called Contextual Alternates (calt). Originally designed for sophisticated typography - connecting cursive letters, providing stylistic variations - it can be repurposed for something more subversive.

The calt feature uses GSUB (Glyph Substitution) rules. These rules can match sequences of characters and replace them with different glyphs:

feature calt {
  sub O B E Y by L I V E;
  sub C O N S U M E by L A U G H;
  sub C O N F O R M by L O V E;
} calt;

When the font renders “OBEY”, it doesn’t display O-B-E-Y. It displays L-I-V-E. The text is transformed at the typography layer, invisible to document parsers, screen readers, or copy-paste operations.

THE DECEPTION LAYER

This creates a fascinating disconnect:

  • What you see: The rendered message
  • What you copy: The carrier text
  • What screen readers announce: The carrier text
  • What search engines index: The carrier text

The visual experience diverges from every other interaction with the text. It’s steganography in its purest form - hiding in plain sight, detectable only by those who know to look.

LEGITIMATE USES

Beyond the obvious “secret message” novelty, this technique has interesting applications:

WATERMARKING

Embed invisible ownership information in text. A publisher could use a font that subtly marks content as belonging to them - visible proof of origin that survives copy-paste.

EASTER EGGS

Hide messages in documentation or marketing copy. Users with the “decoder font” see something different. It’s DRM-free bonus content.

AUTHENTICATION

The font file itself becomes a decryption key. Share the font only with authorized viewers. Without it, they see innocent carrier text.

ARTISTIC EXPRESSION

Create text that transforms based on typographic context. Poetry that reveals hidden meanings. Stories with parallel narratives.

THE DARK SIDE

This technique is also a potential attack vector. A malicious font could:

  • Make terms of service appear favorable while hiding onerous clauses
  • Display prices differently than what’s recorded
  • Show compliance messages while documenting violations

The defense? Be aware that fonts can lie. Copy-paste important text to verify. Use standard fonts for critical documents.

TECHNICAL LIMITATIONS

OpenType substitution has constraints:

  • Same-length requirement: Substitutions work best with equal-length strings
  • No true encryption: Anyone can inspect the font file
  • Font must be loaded: Falls back to carrier text without the font
  • Limited to glyph-level: Can’t inject arbitrary content

These limitations make it steganography rather than encryption. The security is obscurity, not cryptography.

THE IRONY

There’s something delightfully subversive about using a feature designed for beautiful typography to hide messages. Contextual alternates were meant to make fonts more elegant - connecting letters, providing flourishes. Instead, we’re using it for digital graffiti.

The machines see one thing. The humans see another. Just like the sunglasses in They Live.


I HAVE COME HERE TO CHEW BUBBLEGUM AND WRITE FONTS. AND I’M ALL OUT OF BUBBLEGUM.