Only the latest release receives security fixes.
Do not open a public GitHub issue for security vulnerabilities.
Report privately via GitHub's Security Advisories feature. Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
You will receive a response within 72 hours. If confirmed, a fix will be released as soon as possible.
In scope:
monitor.py,statusline.py,shared.py,update.py,pulse.pycheck-requirements.ps1,check-requirements.sh- Setup documentation under
docs/ - CI workflows under
.github/workflows/
Out of scope:
- Claude Code CLI itself — report to anthropics/claude-code
- Python standard library — report to python.org/security
- GitHub Actions runners and the GitHub platform — report to GitHub
- Third-party packages pinned in
.github/workflows/requirements-bandit.txt— report upstream to the respective maintainers
CC AIO MON reads session data from Claude Code via stdin and writes snapshots to a local temp directory. The update.py --apply command invokes git pull --ff-only as a subprocess only when explicitly requested. The pulse.py module performs outbound HTTPS requests to Anthropic's public status endpoints (see below) — no credentials, no API keys, no user data are transmitted.
Outbound network (pulse.py):
GET https://status.claude.com/api/v2/summary.json— public status page JSON (every 30 s)GET https://api.anthropic.com/v1/messages— unauthenticated liveness probe; expects 401/405 (every 30 s)- Request body: none. Headers:
User-Agent: cc-aio-mon-pulse/<version>only (tracksmonitor.VERSION; currently1.9.1). - Response size capped at 512 KB; socket timeouts 4–5 s.
- Opt-out: set
CC_AIO_MON_NO_PULSE=1to disable the background worker entirely.
- statusLine JSON input (stdin) — size-capped (1 MB), parse-error bounded.
- Session IDs — regex-validated (
^[a-zA-Z0-9_\-]{1,128}$), reserved names (rls,stats,pulse) blocked. - transcript_path (statusline JSON) — containment-checked: must be regular file inside
~/.claude/projects/, symlinks rejected. (added 2026-04) - Transcript content (read-only,
~/.claude/projects/) — per-file 50 MB cap, model IDs sanitized before terminal render. (added 2026-04) - File I/O — confined to
$TMPDIR/claude-aio-monitor/(writes) and~/.claude/projects/(reads). Atomic writes viaNamedTemporaryFile+os.replace. - Subprocess — git only.
shell=False, list args,GIT_TERMINAL_PROMPT=0, bounded timeouts, minimal env whitelist (added 2026-04). Never uses--no-verify/--force. - Network — Pulse:
status.claude.com+api.anthropic.comHTTPS GET, no auth, bounded size (512 KB) + timeout (5 s). Update: git fetch origin main (HTTPS or SSH, configurable by user's git remote).
Opt-out env vars: CC_AIO_MON_NO_PULSE=1, CC_AIO_MON_NO_UPDATE_CHECK=1.
Key protections:
- Session ID validated against
[a-zA-Z0-9_-]{1,128}— prevents path traversal - All JSON fields sanitized before terminal output — prevents escape injection
- Atomic writes via
NamedTemporaryFile+os.replace()— prevents partial reads - File size limits on all reads (1 MB JSON, 2 MB JSONL, 10 MB cross-session, 512 KB pulse response, 1 MB
pulse.jsonl) — prevents memory exhaustion - Symlink and NTFS junction rejection on temp data directory —
lstat()+S_ISDIRverification withFILE_ATTRIBUTE_REPARSE_POINTcheck on Windows. Defends against TOCTOU races between mkdir and validation. - Temp directory created with
0o700permissions where supported update.pyguards: dirty tree, wrong branch, detached HEAD, divergence, downgrade, Python version mismatchpulse.pyusesurllib.request.urlopenwith default CA verification (nossl._create_unverified_context); errors are caught by specific type, never broadly suppressed in probe logic