Cloud-backed security analysis for agent skills.
Agent skills are executable code plus natural-language instructions that run with your agent's privileges. A single malicious or careless skill can exfiltrate secrets, open a reverse shell, mine cryptocurrency, phone home, or hide a delayed trigger. Bitdefender Agent Skill Scanner audits a skill before you trust it.
It walks every file in a target skill, extracts security indicators, runs 71 behavioral detectors across 16 threat categories, recursively unpacks nested archives, hashes everything, and sends the extracted metadata to Bitdefender's analysis backend, which returns an LLM-generated security report with a risk level, a summary, and per-file findings.
A scan that returns no findings means no known threat patterns were detected — not that the skill is safe.
16 behavioral categories / 71 patterns:
| Category | Examples |
|---|---|
| Code execution | eval/exec, dynamic __import__, JS Function(), PowerShell Invoke-Expression |
| Subprocess usage | shell=True, os.system, os.popen |
| Obfuscation | base64-decode-then-exec, hex decoding, chr() construction, known encoded payloads |
| Network | requests/httpx/urllib, raw sockets, fetch(), connections to raw IPs |
| File operations | writes, deletions, bulk shutil ops, destructive rm -rf |
| Crypto-mining | xmrig/stratum/mining-pool indicators |
| Reverse shells | /dev/tcp, nc -e, bash -i >&, pty.spawn |
| Download-and-execute | curl … | sh, pip/npm install from URL, npx without approval |
| Credential access | bulk environment-variable harvesting |
| System persistence | cron, systemd, launchd, Windows registry run-keys |
| Privilege escalation | sudo, dangerous chmod, chown root, writes to system paths |
| Path traversal | ../../.., URL-encoded traversal |
| Telemetry | analytics/tracking SDKs, sendBeacon, phone-home |
| Symlink attacks | ln -s, os.symlink, Node fs.symlink |
| Time bombs | date/timestamp-comparison triggers, delayed execution |
| Stealth directives | natural-language exfiltration, covert-action, and hidden-memory instructions |
18 indicator types are extracted from every text file: URLs, IPv4 addresses, data/javascript: URIs, emails, base64 blobs (decoded and inspected), percent-encoded URLs, environment-variable references, 25 dangerous shell commands, sensitive file paths, suspicious imports, private/loopback IPs, crypto-wallet addresses, known secret env-var names, paste-service domains, DNS-exfiltration patterns, and invisible Unicode characters.
Structural checks: hidden dotfiles, package install-hooks (preinstall/postinstall, setup.py cmdclass), file hashing (SHA-256 + MD5), and a normalized skill-level hash used for report caching.
- Layered analysis — local indicator extraction feeds a server-side LLM that produces the report.
- Deep archive inspection — recursively unpacks
.zip,.tar.gz/.tgz,.tar.bz2/.tbz2,.tar,.7z, and.rarup to 10 levels deep, with limits of 500 MB uncompressed and 10,000 entries per archive. Symlinks are skipped, never followed. - Prose-aware — natural-language threats hidden in
SKILL.mdinstructions (stealth exfiltration, covert actions, keyword/counter triggers) are first-class detections. - Semantic embeddings — computes local sentence embeddings (
sentence-transformers/all-MiniLM-L6-v2, ONNX) to support analysis; can be disabled. - Privacy-respecting default — in scan mode, only hashes, extracted indicators, and metadata are transmitted; your file contents are never uploaded. Full-archive upload happens only in the explicit, opt-in submit mode.
- Flexible targets — scan a directory, an installed skill by name, a
.zip, or a URL.
This is an agent skill. Place it in one of your skills directories and install its dependencies:
pip install -r requirements.txtDependencies: requests, pyyaml, py7zr, rarfile, light-embed, tokenizers, numpy. Optional pieces degrade gracefully — py7zr/rarfile are only needed for .7z/.rar targets, and light-embed/tokenizers/numpy only for embeddings.
.rarextraction also requires a systemunrar/unarbinary on yourPATH(a requirement of therarfilelibrary).
Ask your agent in plain language — "scan the foo skill for security risks" — and it will run the scanner and present the report. You can also invoke the script directly.
python3 scripts/scan_skill.py <target>Example output:
# Skill Scan: my-skill
- **Severity:** CLEAN
- **Scan Date:** 2026-06-15
No security findings detected.
Uploads the complete skill archive for deeper backend analysis. Asynchronous: submit now, then re-run scan mode later to retrieve the report.
python3 scripts/scan_skill.py <target> --mode submit| Target | Behavior |
|---|---|
| Directory path | Scanned directly as the skill root. |
| Skill name | Resolved via ./skills/<name>/, then ~/.openclaw/skills/<name>/, then any extraDirs in ~/.openclaw/openclaw.json. |
.zip archive |
Extracted to a temp directory, then scanned. |
| URL | Sent to the backend for scanning (scan mode only). |
| Option | Description |
|---|---|
--mode scan|submit |
Operation mode (default: scan). |
--output, -o <file> |
Write raw JSON artifacts to a file instead of stdout (scan mode). |
--server <url> |
Override the analysis server base URL. |
--no-embeddings |
Skip local embedding computation. |
--no-update |
Skip the automatic client update check. |
When you ask in plain language, the skill holds the agent to a fixed contract:
- Scan mode is the default — a casual request never uploads your files.
- Submit is opt-in only — the agent won't upload the full archive unless you explicitly ask.
- The agent relays, it doesn't judge — it presents the backend's report and adds no analysis of its own.
- Errors are surfaced as-is — on failure (server unreachable, analysis failed) you get the specific reason.
- Sessions reset after a self-update — if the client updated on launch, the agent asks you to start a fresh session so the new version runs.
- Resolve the target into a skill root (extracting a zip to a temp dir if needed).
- Pack & hash the skill into a normalized archive and compute its skill-level SHA-256.
- Cache check — ask the server whether a report already exists for that hash; if so, return it immediately.
- Collect & enrich — walk every file, hash it, recurse into archives, and run all 18 indicator extractors and 71 behavioral patterns over text content.
- Embed — compute local semantic embeddings (unless disabled).
- Submit metadata — send hashes, indicators, counts, metadata, and embeddings to the backend. No file contents in scan mode.
- Report — the backend returns a risk level, summary, and findings, rendered as Markdown.
| Mode | Transmitted |
|---|---|
| Scan (default) | File hashes (SHA-256/MD5), extracted indicators and pattern matches, file metadata (path, size, MIME), finding counts, SKILL.md frontmatter, dependency metadata, and local embeddings. Raw file contents are not transmitted. |
| Submit (opt-in) | The complete skill archive is uploaded for deep analysis. |
By default, on every run the client contacts the server and — if a newer version exists — downloads it, overwrites its own files in place, and re-executes. One practical implication: the exact client code that runs may change between invocations. To keep the client static, run with --no-update. If an update is applied mid-session, start a new session so the new version loads.
By using Bitdefender Agent Skill Scanner, you confirm that you are over 16 years old and you have read and agreed to Bitdefender's End User License Agreement and Privacy Policy.