This tool was created with OpenAI Codex and Claude Code.
A tool for detecting invisible Unicode characters in files, designed to identify potential ASCII smuggling attempts, hidden data encoding, and suspicious Unicode usage patterns.
- π Comprehensive Detection: Scans for Unicode tags, zero-width characters, directional marks, and variation selectors
- π― Smart Analysis: Automatically groups consecutive characters and assesses suspicion levels
- π Multiple Output Formats: CSV (default), JSON, and human-readable text reports
- π’ Unicode Tag Decoding: Automatically decodes Unicode tag sequences to ASCII
- π Compact Structured Reports: One line/object per file with counts, char types, longest runs, and notes
- π Fast Scanning: Skips binary files and excluded directories (configurable)
# Clone the repository
git clone https://github.com/wunderwuzzi23/aid.git
cd aid
# Make the script executable
chmod +x aid
# Run it
./aid --target /path/to/scanRequirements: Python 3.6+
# Scan a directory (writes ./aid-report.csv by default)
./aid --target ./my-project
# Scan with progress indicator
./aid --target ./my-project --verbose
# Output in different formats
./aid --target ./my-project --output report.json --format json
./aid --target ./my-project --output report.txt --format text
# Save CSV and filter critical entries
./aid --target ./my-project --output report.csv
grep ",critical," report.csv--target PATH Target directory to scan (required)
--output PATH Output report file path (default: ./aid-report.<format>)
--format FORMAT Output format: csv (default), json, or text
--verbose Show progress while scanning
--include-cc Also scan for classic control chars (Cc), excluding TAB/LF/CR
--include-confusable-spaces Also scan for confusable/suspicious spaces and fillers (e.g. U+00A0 NBSP)
--include-zs Also scan for Unicode space separators (Zs), excluding ASCII space U+0020
AID automatically assesses the severity of findings:
- π΅ INFO:
longest_consecutive_run < 10andtotal_invisible_code_points < 10 - π‘ MEDIUM:
longest_consecutive_run < 10and10 <= total_invisible_code_points <= 100 - π HIGH:
10 <= longest_consecutive_run < 40, orlongest_consecutive_run < 10withtotal_invisible_code_points > 100 - π΄ CRITICAL:
longest_consecutive_run >= 40
Classification is evaluated in this order:
- If
longest_consecutive_run >= 40, severity iscritical. - Else if
longest_consecutive_run >= 10, severity ishigh. - Else if
total_invisible_code_points > 100, severity ishigh. - Else if
total_invisible_code_points < 10, severity isinfo. - Else severity is
medium.
This means critical is still run-only, and sparse distributions can now rise to high when total invisible volume is very large (>100).
file_path,file_size_bytes,suspicion_level,total_invisible_code_points,unique_invisible_code_points,invisible_chars,longest_consecutive_run,longest_unicode_tag_run,notesKey Columns:
invisible_chars: Character names with counts per filelongest_consecutive_run: Largest consecutive run of invisible code points in the filelongest_unicode_tag_run: Largest consecutive run containing only Unicode Tag code pointsnotes: Decoded Unicode Tag payload text(s), e.g.'hidden text'(empty when no Unicode Tag runs are found)
$ ./aid --target ./skills
Files scanned: 42
β Files with findings: 3
π΅ Info: 2
π΄ Critical: 1
β Total invisible code points: 156
π By category:
Unicode Tags: 142
Zero-Width Chars: 12
Directional Marks: 2
β Report written to aid-report.csv# Include classic control chars (Cc), except TAB/LF/CR
./aid --target ./project --include-cc
# Include confusable/suspicious spaces and fillers (e.g., NBSP, thin space, hangul filler)
./aid --target ./project --include-confusable-spaces
# Include Unicode space separators (Zs), except ASCII space U+0020
./aid --target ./project --include-zs
# Enable both
./aid --target ./project --include-cc --include-zs --include-confusable-spacesDefault mode now uses a strict detection set focused on high-signal smuggling characters.
U+E0000..U+E007F(TAG block)- Decoded to ASCII equivalents in report notes where possible
U+034FCOMBINING GRAPHEME JOINERU+180EMONGOLIAN VOWEL SEPARATORU+200BZERO WIDTH SPACEU+200CZERO WIDTH NON-JOINERU+200DZERO WIDTH JOINERU+2060WORD JOINERU+FEFFZERO WIDTH NO-BREAK SPACE
U+061C,U+200E,U+200FU+202A..U+202EU+2066..U+2069
U+FE00..U+FE0F(VS1..VS16)U+E0100..U+E01EF(VS17..VS256)
U+2061..U+2064(function application/invisible math operators)
U+206A..U+206F
U+00A0NO-BREAK SPACEU+00ADSOFT HYPHENU+2000..U+200A(quad/space variants)U+202FNARROW NO-BREAK SPACEU+205FMEDIUM MATHEMATICAL SPACEU+2800BRAILLE PATTERN BLANKU+3000IDEOGRAPHIC SPACEU+3164HANGUL FILLERU+FFA0HALFWIDTH HANGUL FILLER
- Scans Unicode category
Zs(space separators), excluding ASCIIU+0020 SPACE - Broader and potentially noisier than the curated confusable-space list
- AID does not currently flag every possible Unicode
Cf/Cc/Zscode point. - It focuses on high-risk and frequently abused invisible/smuggling characters.
Ccis only scanned when--include-ccis provided.- Confusable/suspicious spaces and fillers are only scanned when
--include-confusable-spacesis provided. Zsis only scanned when--include-zsis provided.- To avoid overwhelming noise:
--include-ccexcludesTAB (U+0009),LF (U+000A), andCR (U+000D)--include-zsexcludes ASCII spaceU+0020
Edit the EXCLUDED_DIRS array at the top of the script to skip certain directories:
EXCLUDED_DIRS = [
'.git',
'node_modules', # Uncomment to exclude
'.venv', # Add your own
]By default, only .git is excluded. Hidden directories like .curated are scanned.
- Security Auditing: Detect ASCII smuggling attempts in code repositories
- Data Forensics: Find hidden data encoded in invisible characters
- Code Review: Identify suspicious Unicode usage in pull requests
- Compliance: Scan for non-printable characters in text files
- Malware Analysis: Detect steganography and obfuscation techniques
./aid --target ./project --output report.csv
grep ",critical," report.csv./aid --target ./project --output report.json --format json
cat report.json | jq '.files[] | select(.suspicion_level == "critical")'- Recursively scans all files in the target directory
- Skips binary files automatically using MIME type and null-byte detection
- Groups consecutive invisible characters for better analysis
- Decodes Unicode tags to reveal hidden ASCII messages
- Generates report files in CSV, JSON, or text format
- Calculates suspicion levels based on quantity and variety of invisible characters
Contributions are welcome! Please feel free to submit issues or pull requests.
https://embracethered.com/blog/ascii-smuggler.com
MIT License - see LICENSE file for details.
Inspired by the need to detect sophisticated Unicode-based attacks and data hiding techniques.