Skip to content
amantcodesPublic

About

Privacy-first CLI for scrubbing tracking URLs, invisible Unicode, PII, secrets, and image metadata locally.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

scrub

Strip invisible tracking characters, URL tracking parameters, image metadata (EXIF/GPS/ICC), and PII from text and images — locally, before you paste or upload them anywhere.

No network calls. Ever. Single static-ish binary, no runtime deps.

$ ls -lh target/release/scrub
-rwxr-xr-x 1 root root 1.9M target/release/scrub

Why

Copy-pasted text and screenshots carry more hidden baggage than people realize:

  • Invisible Unicode: zero-width spaces/joiners (\u200B, \u200D), directional-override controls, and variation-selector steganography are used to watermark and trace copied text.
  • Disguised whitespace: non-breaking spaces and other lookalike space characters are sometimes swapped in as a fingerprint.
  • Homoglyphs: Cyrillic/Greek letters that render identically to Latin ones can hide inside otherwise-normal-looking text.
  • URL telemetry: utm_*, fbclid, gclid, si, msclkid, etc. leak cross-platform identity every time you share a link.
  • Image metadata: EXIF (camera make/model), GPS coordinates, and embedded ICC color profiles can fingerprint the exact device that took a screenshot or photo.
  • Leaked secrets: emails, live API keys, JWTs, and internal IPs get pasted into prompts and public repos constantly, by accident.

scrub handles all of it locally in one pass, in milliseconds.

Install / Build

Requires a Rust toolchain (1.74+).

# Core build: text + URL + PII + image scrubbing, no clipboard, no GUI deps
cargo build --release

# Optional: also enable --clip (reads/writes the system clipboard)
cargo build --release --features clip

The binary lands at target/release/scrub.

Usage

# Clean text straight from the system clipboard (requires --features clip build)
scrub --clip

# Pipe text or prompt data through before it hits an LLM tool or a paste
cat sensitive_prompt.txt | scrub | llm-cli

# Also redact emails, API keys, JWTs, and internal IPs
cat sensitive_prompt.txt | scrub --scrub-pii

# Scrub an image before uploading it to a public repo
scrub --image screenshot.png --out clean_screenshot.png

Every run prints a one-line-per-finding summary to stderr (so it never pollutes stdout when you're piping into another tool):

$ echo 'check https://x.com?utm_source=x fbclid=y [email protected]' | scrub --scrub-pii
check https://x.com [email protected]
scrub: stripped 1 URL tracking parameter(s)
scrub: redacted 1 email match(es)

Pass --quiet to suppress that summary entirely.

Flags

Flag Effect
--clip Read from and write back to the system clipboard instead of stdin/stdout
--scrub-pii Redact emails, API keys/tokens, JWTs, and internal IPv4 addresses
--keep-homoglyphs Don't fold lookalike Cyrillic/Greek letters back to ASCII
--keep-url-trackers Don't touch query parameters on URLs
--image <PATH> Scrub a PNG/JPEG's metadata instead of running text mode
--out <PATH> Output path (required with --image; optional in text mode)
--quiet Suppress the stderr summary

What image scrubbing actually strips

No image is decoded or re-encoded — scrub parses the container format directly and drops only the metadata-bearing segments, so pixel data is untouched byte-for-byte and the operation is sub-millisecond even on real photos.

  • PNG: tEXt, zTXt, iTXt (free-text metadata), eXIf (embedded EXIF), tIME (timestamp), iCCP (embedded color profile).
  • JPEG: APP1 (EXIF/GPS/XMP), APP2 (usually an embedded ICC profile), APP13 (Photoshop metadata block), COM (comments).

What PII scrubbing catches

Conservative, local regex matching only — no ML model, no network call:

  • Email addresses
  • JWTs (eyJ...........)
  • API keys/tokens for common formats: OpenAI (sk-), Anthropic (sk-ant-), AWS (AKIA/ASIA), GitHub (ghp_/gho_/github_pat_), Slack (xox*), Google (AIza), GitLab (glpat-), npm (npm_), SendGrid, Stripe.
  • Internal/private IPv4 addresses (RFC1918, loopback, link-local)

Design notes

  • Rust, small dependency tree. Core build only needs regex and clap. Clipboard support (arboard) is feature-gated behind --features clip so the default binary never needs a display server or GUI libs and always builds cleanly in headless CI.
  • No image crate. Metadata stripping is a direct PNG chunk / JPEG marker-segment parser, not a decode-modify-re-encode round trip. This keeps output pixel-identical to the source and keeps the binary tiny.
  • URL cleaning is allowlist-aware, not blind. It only strips a curated list of known tracking parameters and special-cases YouTube's t= (timestamp) so functional query parameters are never touched.

Tests

cargo test --release

20 unit tests cover invisible-character stripping, homoglyph folding, URL tracking-parameter removal (including the YouTube-timestamp edge case), PII redaction for every supported pattern, and PNG/JPEG metadata stripping verified against real files generated with Pillow/piexif.

About

Privacy-first CLI for scrubbing tracking URLs, invisible Unicode, PII, secrets, and image metadata locally.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages