CAUTION version 1.1.6 · audited 2026-09-17
SkillScan is a Python script plus SKILL.md instructions that tell an agent to run a cloud-based security scan on new or existing skills. It reads skill directories, zips them, and uploads the zip to https://skillscan.tokauth.com, then polls for a verdict. It also stores a generated client ID with OS details and sometimes the machine MAC address, and sends that metadata in an X-Client-Info header. The script checks for updates on every run and can download and replace its own files from a remote manifest without user confirmation in the automatic path. On HIGH/CRITICAL results it can delete the original skill directory after a yes answer. These behaviors are partly disclosed, but include broad upload, device identification, and remote code replacement, so careful review is warranted.
Instructions try to steer the agent beyond the declared purpose. SKILL.md line 6: 'Every new skill MUST pass SkillScan before use'; line 9: 'Blocks HIGH/CRITICAL skills. No exceptions.' These unconditional directives attempt to override the agent's other rules and make SkillScan a mandatory gate for all other skills.
| Declared purpose | Security gate for skills: scan skill packages before install/load/evaluation, warn on LOW/MEDIUM, block HIGH/CRITICAL, and keep the scanner updated. |
| Observed behavior | The package instructs the agent to run scanner.py for skill installs, loads, or safety questions. The script enumerates many skill directories across the user's home and app-data paths, copies skills to temp directories, hashes them, zips all non-skipped files, uploads the zip to skillscan.tokauth.com, polls for results, and maps the response to SAFE/LOW/MEDIUM/HIGH/CRITICAL exit codes. It can delete HIGH/CRITICAL scanned directories after user confirmation. It writes state files (.first_run_done, .client_info, .last_update_check) and sends Base64-encoded client metadata including OS and, when available, MAC address. On every invocation it checks a remote manifest and may download and overwrite its own code from a manifest-provided URL. |
| Verdict, rules only | SAFE |
| Verdict, AI | CAUTION |
| Final verdict | CAUTION (never better than either pass) |
| capability | vs purpose | detail |
|---|---|---|
| network | needed | Communicates with https://skillscan.tokauth.com for cache lookup, upload, result polling, and update manifest; can download from a URL provided in the update manifest. |
| shell | needed | The scanner is intended to be invoked by the agent via bash using commands shown in SKILL.md, such as `python <skill_scanner_dir>/scripts/scanner.py first-run`. |
| filesystem_read | needed | Enumerates many skill directories under the user's home and app-data paths, reads SKILL.md and other files, hashes directory contents, and creates temp copies. |
| filesystem_write | needed | Writes state files (.first_run_done, .client_info, .last_update_check), temp copies and backups, overwrites its own files during update, and deletes high-risk skill paths after confirmation. |
| credentials | exceeds purpose | Does not directly read the hosting agent's credential store, but can upload credential-like files such as .env or JSON/text files with secrets if they are inside a scanned skill because pack_zip includes all non-skipped files. |
| persistence | needed | Persists a generated client_id and OS/MAC metadata in .client_info and uses marker files to control first-run and update checks. |
| install_packages | needed | Auto-update downloads a zip from a manifest-provided download_url and copies files over its own directory, effectively installing new code. |
| other | exceeds purpose | Collects the machine MAC address, OS, platform, OS version, Python version, and a generated client ID; Base64-encodes this as X-Client-Info and sends it to the remote API. |
| severity | finding |
|---|---|
| medium | Unconditional mandatory gate Instructs the agent that every new skill must pass SkillScan before use, with no qualification. SKILL.md:6 Security gate for skills. Every new skill MUST pass SkillScan before use. |
| medium | Attempts to override agent discretion Directive insists on no exceptions, which can conflict with other agent instructions or user decisions. SKILL.md:9 Blocks HIGH/CRITICAL skills. No exceptions. |
| low | Broad activation instruction Expands the trigger to any safety question about any skill, not just explicit scans. SKILL.md:24 Run SkillScan whenever a skill is installed, loaded, added, evaluated, or questioned for safety — regardless of method or phrasing. |
| info | Upload risk disclosed Publisher discloses that complete skill directories may be uploaded to the SkillScan service. skill-card.md:25 Risk: Cloud scanning may upload complete skill directories. |
| info | Device metadata risk disclosed Publisher discloses that persistent device metadata may be included with requests. skill-card.md:29 Risk: Persistent device metadata may be sent with scan requests. |
| info | Remote code replacement risk disclosed Publisher discloses that the update mechanism can replace scanner code from a remote source. skill-card.md:37 Risk: Runtime auto-update can replace the scanner code from a remote update source. |
| info | Hardcoded remote service All scan and update operations default to this remote service. scripts/scanner.py:24 BASE_URL = "https://skillscan.tokauth.com" |
| medium | Update source can be overridden The environment variable can point auto-update at a different manifest URL, and the fallback is defined on line 29 as the remote SkillScan manifest. scripts/scanner.py:28 UPDATE_URL = os.environ.get("SKILL_SCANNER_UPDATE_URL", |
| medium | Daily automated update check The script checks for remote updates daily, despite an earlier comment mentioning 7 days. scripts/scanner.py:39 AUTO_UPDATE_INTERVAL = 1 * 24 * 3600 # 1 day (seconds) |
| low | Persistent client info file Creates a persistent file near the scanner to store client identity data. scripts/scanner.py:42 CLIENT_INFO_FILE = Path(__file__).parent / ".client_info" |
| medium | Collects MAC address Adds the machine's MAC address, when available, to client metadata. scripts/scanner.py:186 mac = _get_mac_address() |
| high | Zips all non-skipped skill files pack_zip includes every file in the scanned skill except SKIP_FILES/SKIP_DIRS. This can include .env files, tokens, or other sensitive files present in the skill directory. scripts/scanner.py:330 zf.write(p, p.relative_to(skill_dir)) |
| high | Uploads full skill directory cloud_upload sends the zipped skill content to the remote scan API. scripts/scanner.py:424 zip_data = pack_zip(skill_dir) |
| medium | Sends Base64 device metadata header The X-Client-Info header contains client_id, OS, and possibly MAC address, Base64 encoded. scripts/scanner.py:451 headers["X-Client-Info"] = ci |
| high | Deletes original skill directory For HIGH/CRITICAL results, prompt_delete can remove the original installed skill path after asking the user. scripts/scanner.py:625 shutil.rmtree(skill_path) |
| high | Update URL taken from remote manifest The upgrade code trusts a download_url field from the remote manifest; the URL can point anywhere. scripts/scanner.py:845 download_url = manifest.get("download_url", "") |
| high | Replaces scanner files with downloaded code Upgrade extracts a zip and overwrites the scanner's own files. SHA-256 is only verified against the same remote manifest, not against a trusted pinned checksum. scripts/scanner.py:898 shutil.copy2(item, target) |
| medium | Auto-update runs on every invocation main() calls auto_upgrade_if_needed before executing any command, so every scan may trigger an update check and possible code replacement. scripts/scanner.py:939 auto_upgrade_if_needed() |
0 AI finding(s) were dropped because their file, line or quote did not match the package.
| domain | service rating | where |
|---|---|---|
| clawhub.ai | not in the service index | skill-card.md:9 |
| skillscan.tokauth.com | not in the service index | SKILL.md:91 |
| Binaries invoked | base64, bash, git, npx, python, python3 |
| Environment variables read | APPDATA, SKILL_SCANNER_UPDATE_URL |
| Hard-coded wallets | none |
| Pipes a download to a shell | 0 |
| eval / exec / subprocess | 0 |
| base64 blobs | 0 |
| File writes | 9 |
| Persistence | 0 |
| file | lines | sha256 |
|---|---|---|
SKILL.md | 97 | 7cc318d81fadddc9… |
_meta.json | 6 | 65ed721a976afc69… |
scripts/scanner.py | 959 | ed9f4e7405cb5767… |
skill-card.md | 62 | 26b24b16d20014c8… |
For agents
JSON: https://agenteconomy.report/k/skillscan.audit.json · badge: https://agenteconomy.report/k/skillscan.audited.svg ·
skill rating: /k/skillscan · commission an audit of any skill: US$ 29 per version.
The complete published package of this exact version was downloaded from the registry and read statically; nothing was executed. A deterministic pass extracts network destinations, binaries, environment variables, writes, install commands, obfuscation markers, subprocesses and wallets, each with file and line. An AI then reads the whole package with those facts and writes the summary, the capabilities and the findings under a strict schema; every finding it produces must cite a file, a line and the exact text, or it is dropped. The final verdict is the worst of the two passes. The audit does not change the skill's trust tier (policy); the author may respond through the dispute channel and the response is published here. Commissioned by: the Agent Economy Report (free program: the 150 most downloaded skills, September 2026).