Skip to main content

StegGuard

StegGuard: Uncovering Hidden Data

Find what is hiding in plain sight.

Python 3.12+ License: Apache-2.0 Runtime dependencies: 0

StegGuard is a local-first toolkit for finding, decoding, and safely removing hidden content from files. It looks beyond ordinary metadata and scans for invisible Unicode, whitespace channels, homoglyphs, suspicious media structures, watermark signals, fingerprints, and Content Credentials.

It runs on the Python standard library, stays offline by default, and explains what it found in JSON and HTML reports you can actually hand to another person.

StegGuard is alpha software. Treat its findings as investigative evidence, not as an infallible verdict.

See it work

The repository includes a deterministic, harmless demo. It hides the word DEMO in zero-width characters, detects and decodes it, writes a sanitized copy, verifies the result, and analyzes a synthetic PNG for watermark and provenance signals.

python3 demo/run_demo.py

Expected ending:

Demo completed successfully
Decoded hidden text: DEMO
Original preserved: True
Reports: .../demo-output/reports
Summary: .../demo-output/summary.json

The demo makes no network requests and contains no executable or malicious payload. Open demo-output/reports/detect.html after the run to inspect the report. See the demo guide for every generated artifact.

Why StegGuard exists

Hidden content is rarely one neat payload in one neat format. It can be a zero-width message in a prompt, a Cyrillic character in a source file, trailing spaces in a document, bytes after a media container, a private PNG chunk, or a provenance claim that exists but has never been cryptographically validated.

Most tools handle one of those cases. StegGuard gives them a shared workflow:

untrusted file -> detect -> inspect -> decode -> sanitize a copy -> verify

The original stays untouched unless you explicitly authorize an in-place replacement.

Install

When a release is available on PyPI:

python3 -m pip install stegguard

From source:

git clone https://github.com/stegguard/stegguard.git
cd stegguard
python3 -m pip install -e .

StegGuard requires Python 3.12 or newer and has no mandatory runtime dependencies.

For wider image-format decoding through the explicitly tested Pillow path:

python3 -m pip install "stegguard[images]"

The supported Python range is 3.12 through 3.14. CI is configured for Linux, macOS, and Windows; hosted results are required before those targets are described as verified. Architecture details and current evidence are in docs/platform-support.md.

Quick start

Scan one file:

stegguard detect suspicious.py

Scan a repository and save both report formats:

stegguard detect ./repo -r --json findings.json --html report.html

Decode recognized text-carried channels without modifying the source:

stegguard decode suspicious.txt

Write a sanitized copy and receive hashes, change counts, and a unified diff:

stegguard sanitize suspicious.txt

Analyze watermark and provenance signals:

stegguard watermark image.png --json watermark.json --html watermark.html

Validate Content Credentials with the official c2patool executable:

stegguard watermark image.png --c2pa-tool c2patool --html provenance.html

Commands

Command What it does
stegguard detect Scans files or directories for hidden-content signals
stegguard decode Extracts recognized text-carried payloads without changing the input
stegguard sanitize Writes a safer copy and reports every change
stegguard watermark Analyzes watermark, fingerprint, and provenance evidence

Run stegguard COMMAND --help for command-specific options.

For detect, exit status 0 means a completed clean scan, 1 means a completed scan with findings, and 2 means invalid input or an incomplete scan. The complete compatibility contract is in docs/compatibility.md.

What it detects

Text and source files

  • Zero-width and invisible Unicode characters
  • Bidirectional controls and suspicious formatting characters
  • Cyrillic and Greek homoglyphs
  • Trailing-space and tab channels, including SNOW-style patterns
  • Mixed and encoded line-ending patterns
  • Repeated punctuation, spacing, and layout intervals

Images, audio, and structured media

  • Pixel-level LSB anomalies as a distinct detection category
  • Transform and block-correlation signals in decodable lossless images
  • Phase, echo, spectral, spread-spectrum, and silence-interval statistics in PCM WAV audio
  • PNG metadata, private chunks, and appended data
  • JPEG EXIF, XMP, and IPTC indicators
  • RIFF trailing data, ISO BMFF private boxes, and PSD structures
  • Pluggable analyzers for compressed codecs, keyed schemes, and video

Documents and containers

  • PDF embedded files and active or hidden structures
  • DOCX, PPTX, XLSX, ZIP, and compatible archive members
  • Nested media and archives with bounded member and decompression limits
  • SVG and HTML comments, hidden styles, and external references

Watermarks and provenance

  • Metadata, structural, text-pattern, and layout evidence
  • Robust image, audio, and video signal families
  • Device, camera, printer, encoder, and codec fingerprints
  • Embedded and sidecar C2PA manifests
  • Content Credentials validated through c2patool
  • External manifest references with opt-in, bounded HTTPS retrieval
  • Pluggable AI text-watermark verifiers

Detection categories remain separate in the output. An LSB anomaly is not reported as a robust watermark, and the presence of a C2PA manifest is not reported as cryptographic validation.

Sanitization is deliberately cautious

By default, this command:

stegguard sanitize suspicious.txt

writes suspicious.sanitized.txt. It will not overwrite an existing output and it reports:

  • SHA-256 hashes before and after
  • A unified text diff
  • Counts for every normalization
  • Whether the original was preserved
  • Provenance status before and after
  • Whether a content change invalidated provenance

Overwriting the original requires both flags:

stegguard sanitize suspicious.txt --in-place --confirm

Unsupported binary formats are copied byte-for-byte and marked NO_OP_UNSUPPORTED. StegGuard does not push binary data through a text cleaner and hope for the best.

Reports built for review

JSON findings are machine-readable, JSON-compatible, and designed for downstream tools. HTML reports include:

  • Executive severity and provenance summaries
  • Per-file evidence with locations and confidence
  • Nested container findings
  • Signer, source type, manifest location, and validation errors
  • C2PA actions, timestamps, edits, and ingredients
  • Clear disclaimers around authorship and missing watermarks

Valid provenance is informational. Tampered or untrusted provenance raises the reported risk.

Machine-readable reports carry schema_version. The supported schema is packaged at stegguard/schemas/report-v1.schema.json and its evolution policy is documented in docs/compatibility.md.

Python API

The core workflows are also available as Python functions:

from stegguard import analyze_file, decode_file, sanitize_file, scan_file

detection = analyze_file("suspicious.txt")
decoded = decode_file("suspicious.txt")
sanitized = sanitize_file("suspicious.txt")
watermarks = scan_file("image.png")

Each function returns JSON-compatible data.

Trust and network model

StegGuard does not make unsolicited network requests. Remote C2PA manifests are disabled unless --allow-remote-manifests is supplied. When enabled, retrieval is HTTPS-only, rejects redirects and non-global addresses, and enforces timeout and response-size limits.

C2PA states are explicit: VALID, TAMPERED, UNTRUSTED_SIGNER, MISSING, UNSUPPORTED, or NOT_CHECKED. If cryptographic validation did not happen, StegGuard says so.

Scans have configurable limits for input bytes, decompression, image pixels, archive members, nesting depth, elapsed time, and retained findings. See docs/resource-limits.md before processing uploads or running StegGuard as a service.

Current limitations

  • c2patool is optional and installed separately. Without a validator, an embedded C2PA claim remains NOT_CHECKED.
  • Keyed and proprietary watermark schemes require their corresponding analyzer.
  • Generic robust-media statistics are leads, not cryptographic proof.
  • Video and compressed-codec analysis require a configured analyzer. Missing analysis is reported as NOT_CHECKED, not clean.
  • No official Anthropic text-watermark verifier is bundled. StegGuard does not replace one with a home-grown guess.
  • Valid provenance means an asset passed the configured validation. It does not prove authorship. A missing mark does not prove human authorship either.

Development

git clone https://github.com/stegguard/stegguard.git
cd stegguard
uv run pytest
uv run pytest --cov=stegguard --cov-report=term-missing
uv run ruff check stegguard tests demo scripts benchmarks

The project intentionally keeps its runtime dependency-free. Tests may use development dependencies declared in pyproject.toml. Contributor setup, fixture safety, review expectations, and all local gates are in CONTRIBUTING.md.

Contributing

Bug reports, new fixtures, detector improvements, and careful false-positive reports are welcome. Please include a minimal reproducible sample generated at test time. Do not commit suspicious payloads, credentials, or generated reports.

Open an issue or pull request at github.com/stegguard/stegguard.

Project policies: security, support, governance, releases, detection quality, and changelog.

License

StegGuard is licensed under Apache License 2.0. See LICENSE and NOTICE.

Metadata

Release files for stegguard 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stegguard 0.4.0
File Size Uploaded Provenance Actions
stegguard-0.4.0.tar.gz 118.1 kB With provenance Details for stegguard-0.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for stegguard 0.4.0
File Interpreter ABI Platform Actions
stegguard-0.4.0-py3-none-any.whl Python 3 none any Details for stegguard-0.4.0-py3-none-any.whl

Total release size: 200.0 kB

Release files / stegguard-0.4.0.tar.gz

Download URL stegguard-0.4.0.tar.gz
Size 118.1 kB
Tags Source
SHA-256 checksum
How to use checksums
10df44cac3c98bb7eb38d9fa7b0e1cd062e27d913c7dc8cca7b55f706f80d50b
BLAKE2b-256 checksum
How to use checksums
abfa7c6271e324479d3849f52b19c058267a5ec9b584aa9c3d9ef58c24442030
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / stegguard-0.4.0-py3-none-any.whl

Download URL stegguard-0.4.0-py3-none-any.whl
Size 82.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2d079c9b409edc3a3b13404028f2eb7e1e9cbfec7d7434cce2cb3eb24c69d1a5
BLAKE2b-256 checksum
How to use checksums
c9360bdb24ade89b10ad86afc6f63ad0fb6bab5a2a7bd0f8f10b198b7490e9e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for stegguard 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for stegguard-0.4.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page