Skip to content

DaCameraGirl/payload-revealer

Repository files navigation

Payload Revealer — Catches invisible Unicode instructions hidden inside copied Slack, chat, and doc text.

Catches invisible Unicode instructions hidden inside copied text — zero-width characters, bidi overrides, Unicode tags, and other copy/paste artifacts that can smuggle answers or prompt instructions into Slack, docs, chats, or evaluation tasks.

English Español Français Deutsch Português 中文 日本語 한국어 Italiano العربية

Live scanner Source code

deploy-GitHub Pages stack-Python + JS

Languages

Python JavaScript HTML CSS

Stack

Python-analysis GitHub Pages-live

Built by Angela Hudson · DaCameraGirl

# Payload Revealer

CI Release Download

Anti-hidden-answer scanner for copied text.
Built for DFIR analysts, developers, AI output auditing, and anyone vetting pasted Slack/chat/doc content.

Payload Revealer catches invisible Unicode instructions hidden inside copied text, including zero-width characters, bidi overrides, Unicode tags, and other hidden copy/paste artifacts that can smuggle answers or prompt instructions into Slack, docs, chats, or evaluation tasks. It scans text files character-by-character, flags invisible codepoints with risk tags (zero-width, bidi-override, unicode-tag, c0-control, null-byte, and more), and extracts decoded payloads when the hidden data uses supported encodings (zero-width binary streams, bidi reversals, Unicode tag blocks, null-byte chunks, and control sequences).

The Slack Scenario

A copied answer can look normal in Slack while carrying invisible Unicode underneath — hidden instructions like “pick option 3” or “tell them X said Y.” PowerShell and some editors may expose weird characters; Payload Revealer does the systematic version: enumerate every codepoint, report suspicious invisible characters, and decode embedded payloads when possible.

If something pasted suspicious: paste it straight into the live scanner — it runs entirely in your browser tab, nothing is uploaded anywhere.

For scripting or a shareable audit trail, use the CLI instead:

python -m payload_revealer .\suspicious.txt

# For a shareable audit trail:
python -m payload_revealer .\suspicious.txt --format json --output report.json

If the hidden instruction used zero-width Unicode, bidi tricks, Unicode tags, or control characters — and those codepoints survived the paste — this tool is built to catch it.

demo

Quick Download

The live scanner needs nothing installed. Grab the desktop app instead if you want it offline, or working outside a browser:

Download the Windows installer — installs the Payload Revealer desktop app (Electron GUI). No Python required. Drag a file onto the drop zone or click Open File.

The release also includes payload_revealer_engine-*-win64.exe on its own — that's the headless scan engine the desktop app runs underneath. Only grab it separately if you're scripting scans without the GUI; double-clicking it directly just opens an empty console waiting for JSON-RPC input, it isn't a standalone app.

Or use the CLI with Python:

pip install -e .
python -m payload_revealer tests/fixtures/forensic_report.txt

The fixture contains 312 zero-width characters encoding a hidden beacon URL:

beacon://c2-exfil.lan/reg?agent=demo-01

Features

  • Live Browser Scanner — Paste or drop a file at the Pages link and scan instantly, no install, nothing leaves your tab
  • Hidden Formatting Detector — Paste rich text (Ctrl+V from the source) to catch white-on-white, zero-size-font, and display:none instructions hidden in docs, webpages, or Slack messages — no invisible Unicode required
  • Character Count Scanner — Total character count even if content is invisible
  • Invisible Payload Detector — Flags zero-width spaces, Unicode control characters, bidirectional overrides, invisible whitespace, Unicode tags, and other hidden text artifacts
  • Visualizer Panel — Shows hidden content in decoded, readable format
  • Word Count Tracker — Actual word count vs. visible word count
  • Export Option — Save decoded payload as .txt or .json forensic artifact

Installation

git clone https://github.com/DaCameraGirl/payload-revealer.git
cd payload-revealer
npm install
pip install -e .

Usage

Desktop App (Electron)

npm start

CLI Headless Mode

# Quick scan
python -m payload_revealer ./suspicious.txt

# JSON output
python -m payload_revealer ./suspicious.txt --format json

# Save report
python -m payload_revealer ./suspicious.txt --output report.json

# Batch scan a directory
python -m payload_revealer ./suspicious_docs/ --recursive

CLI Options

Flag Description
--format, -f text, json, or txt (default: text)
--output, -o Save report to file
--recursive, -r Recurse into directories
--min-risk Filter findings: critical, high, medium, low, none
--quiet, -q Suppress non-result output
--version Show version

What It Detects

Category Examples Risk
Zero-width spaces U+200B, U+200C, U+200D, U+FEFF Critical
Bidi overrides U+202AU+202E (LRE, RLO, etc.) Critical
Unicode tags U+E0001U+E007F (hidden metadata) Critical
C0/C1 controls U+0000U+001F, U+0080U+009F High
Variation selectors U+FE00U+FE0F, U+E0100U+E01EF Medium
Private Use Areas U+E000U+F8FF, U+F0000U+10FFFF Medium
Invisible whitespace NBSP, en-space, ideographic space Low
Noncharacters U+FFFE, U+FFFF, etc. High

Hidden Formatting

Invisible Unicode isn't the only trick. A shared doc, webpage, or Slack message can hide an instruction in plain sight with white-on-white text, display:none, opacity:0, or a zero-size font — no exotic characters involved, just formatting. That text looks completely normal once it's copied, so a plain-text paste alone can't catch it: the styling that hid it is already gone by the time it lands in a scanner.

The live scanner's "Paste rich text" mode catches this instead. Copy directly from the source (Ctrl+C in the Google Doc, webpage, or Slack message, not a re-typed version) and paste with Ctrl+V into that tab — browsers preserve the source's styling in the clipboard's HTML data, and the scanner reads it directly for text whose color matches its background, is set to invisible, or has been shrunk to nothing.

This is a live-scanner-only feature for now — the Python CLI and desktop app work from saved .txt files, which never carry formatting to begin with.

What It Does Not Detect

This tool is scoped to text, Unicode, and hidden-formatting forensics. It is not a universal steganography detector.

Scenario Why it is out of scope
CSS-transparent text pasted as plain text The live scanner's "Paste rich text" mode catches this if you copy from the original source. But a .txt file, the CLI, or the desktop app only ever see plain text, which has no formatting left to inspect.
Image, PDF, or media steganography No parsers for LSB image stego, PDF object tricks, audio watermarks, or other binary media payloads.

Build from Source

Bundle the Python engine into a single .exe (no Python installation required):

pip install pyinstaller
pyinstaller payload_revealer_engine.spec

The output goes to dist/payload_revealer_engine.exe. Electron auto-detects it and uses it instead of python -m.

Architecture

payload_revealer/
├── index.html              # Pages entry point — live browser scanner
├── assets/                 # Browser scan engine (JS port of the Python engine)
│   ├── js/
│   │   ├── scan-engine.js  # Classifier + payload extractor, runs client-side
│   │   ├── hidden-format-scanner.js  # Detects CSS-hidden text (white-on-white, etc.)
│   │   └── app.js          # UI wiring: paste/drop/rich-paste input, results rendering, export
│   └── css/
│       └── scanner.css
├── payload_revealer/       # Python engine
│   ├── engine/
│   │   ├── sweeper.py      # Core character scanner
│   │   ├── classifier.py   # Unicode category tagging
│   │   ├── payload_extractor.py  # Hidden message reconstruction
│   │   ├── word_counter.py  # Visible vs actual word count
│   │   ├── export_engine.py # JSON/TXT report export
│   │   └── ipc_bridge.py   # JSON-RPC for Electron
│   └── cli/
│       └── reveal.py       # CLI headless mode
├── electron/               # Desktop shell
│   ├── main.js             # Electron main process
│   ├── preload.js          # Secure IPC bridge
│   └── renderer/           # UI
│       ├── index.html
│       ├── style.css
│       └── renderer.js
└── package.json

License

MIT

About

Catches invisible Unicode instructions hidden in copied Slack, chat, and doc text

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors