Skip to main content

security-scanner

Scan installed plugins and skills for security risks including malicious code AND malicious natural language instructions. Use /security-scanner to audit before installation.

Source facts

Repository
lev-os/agents
Last source activity
March 13, 2026 at 16:05
Detected SKILL.md language
English
Stars
22
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
security-scanner
description
Scan installed plugins and skills for security risks including malicious code AND malicious natural language instructions. Use /security-scanner to audit before installation.
allowed-tools
Read, Glob, Grep, WebFetch, Bash(ls *)
# Security Scanner Analyzes Claude Code plugins and skills for malicious content using AI semantic analysis. ## Usage ```text /security-scanner # Scan all (plugins + skills) /security-scanner --user # Scan user-level only (~/.claude/) /security-scanner --project # Scan project-level only (.claude/) /security-scanner --all # Scan ALL (ignore trusted sources and self-exclusion) /security-scanner <url> # Scan from GitHub URL (public repos only) /security-scanner --url <url> # Same as above (explicit form) ``` ### URL Format (--url option) Supports GitHub URLs: ```text https://github.com/owner/repo https://github.com/owner/repo/tree/main/path/to/plugin ``` **Note**: Only public repositories are supported. Branch specified in URL is used (defaults to repository's default branch if not specified). ## Scan Targets ### Plugins (Claude Code only) Plugins are a Claude Code specific concept. Scan locations are fixed: - **User-level**: `~/.claude/plugins/` (shared across all projects) - **Project-level**: `.claude/plugins/` (project-specific) ### Skills (Multi-agent support) Skills are scanned based on the `target_agents` setting in configuration. If not configured, only `claude` is scanned (backward compatible). | Agent ID | Project Level | User Level | |----------|---------------|------------| | claude | `.claude/skills/` | `~/.claude/skills/` | | codex | `.codex/skills/` | `~/.codex/skills/` | | gemini | `.gemini/skills/` | `~/.gemini/skills/` | | agents | `.agents/skills/` | `~/.config/agents/skills/` AND `~/.agents/skills/` | **Note**: For Skills.sh/Amp (`agents`), the user-level path checks both `~/.config/agents/skills/` and `~/.agents/skills/`. **Symlink note**: For Skills.sh, the skill body is in `.agents/skills/` and other agent directories contain symlinks. Configure `target_agents` appropriately to avoid redundant scanning (e.g., use only `agents` instead of all agents). ## Configuration Users can configure target agents and trusted sources in `security-scanner.local.md`: - Project-level: `.claude/security-scanner.local.md` (takes precedence) - User-level: `~/.claude/security-scanner.local.md` If both files exist, **project-level settings take precedence**. ```markdown --- # Report language (default: ja) # Examples: ja, en, zh, ko, fr, de, etc. report_language: ja # Target agents to scan (default: claude only) # Valid values: claude, codex, gemini, agents target_agents: - claude - codex - gemini - agents # Trusted sources (skipped during scanning) trusted_marketplaces: - claude-plugins-official # Skip all plugins from this marketplace - hiropon-plugins trusted_plugins: - plugin-dev@claude-plugins-official # Skip specific plugin - frontend-design@claude-code-plugins trusted_skills: - my-skill # Skip specific skill by name (all agents) --- ``` ### Report Language - `report_language`: Language for the security report output - Any language code is accepted (e.g., `ja`, `en`, `zh`, `ko`, `fr`, `de`) - Default: `ja` (Japanese) ### Target Agents - `target_agents`: List of agent IDs to scan skills for - If not specified or empty, defaults to `["claude"]` for backward compatibility - Valid agent IDs: `claude`, `codex`, `gemini`, `agents` ### Trusted Sources **Trusted sources are skipped during scanning.** - `trusted_marketplaces`: Skip all plugins from these marketplaces - `trusted_plugins`: Skip specific plugins (format: `plugin-name@marketplace`) - `trusted_skills`: Skip specific skills by name (applies to all agents) To add/remove settings, edit `security-scanner.local.md` in `.claude/` (project-level) or `~/.claude/` (user-level). ## Scanning Process ### Step 1: Load Settings Search for `security-scanner.local.md` in the following locations: 1. **Project-level**: `.claude/security-scanner.local.md` 2. **User-level**: `~/.claude/security-scanner.local.md` **Priority rules:** - If both files exist, use project-level settings only (project-level takes precedence) - If only one file exists, use that file - If neither file exists, proceed with default settings **From the selected file, extract:** - `report_language` from YAML frontmatter (default: `ja`) - `target_agents` list from YAML frontmatter (default: `["claude"]`) - `trusted_marketplaces` list from YAML frontmatter - `trusted_plugins` list from YAML frontmatter - `trusted_skills` list from YAML frontmatter **Default values (when not specified):** - `report_language`: `ja` (Japanese) - `target_agents`: `["claude"]` (backward compatible - only scan Claude Code skills) - `trusted_marketplaces`: `[]` - `trusted_plugins`: `[]` - `trusted_skills`: `[]` **Validation:** - `report_language`: Any string value accepted (AI will generate report in that language) - `target_agents` must contain only valid agent IDs: `claude`, `codex`, `gemini`, `agents` - Invalid agent IDs are ignored with a warning **Error handling:** - If file exists but has invalid YAML syntax, warn the user and proceed with default settings (do not fail the scan) ### Step 2: Determine Scope Check arguments to determine what to scan: **Location filters:** - No location flag: Scan both user-level and project-level for all configured agents - `--user`: Scan only user-level paths for all agents in `target_agents` (e.g., `~/.claude/`, `~/.codex/`, etc.) - `--project`: Scan only project-level paths for all agents in `target_agents` (e.g., `.claude/`, `.codex/`, etc.) **URL detection (highest priority):** 1. If `--url <url>` is provided explicitly → Go to Step 2-URL 2. If any argument starts with `https://github.com/` or `http://github.com/` → Treat as URL, go to Step 2-URL 3. If any argument starts with `https://` or `http://` but not `github.com` → Error: "Unsupported host: {host}. Currently only github.com is supported." **Special modes (if no URL):** - `--all`: Scan everything (skip Step 4 filtering entirely) --- ### Step 2-URL: GitHub URL Scan If URL is provided (via `--url` or auto-detected), follow this process instead of Steps 3-4. #### Step 2-URL-1: Parse URL Parse the GitHub URL to extract owner, repo, branch, path, and determine scan type: **URL Patterns**: - Directory: `https://github.com/{owner}/{repo}[/tree/{branch}/{path}]` - Single file: `https://github.com/{owner}/{repo}/blob/{branch}/{path}.md` 1. Verify host is `github.com` - If not: Error "Unsupported host: {host}. Currently only github.com is supported." 2. Extract `owner` and `repo` from path segments 3. Determine scan type: - If URL contains `/blob/` and ends with `.md` → **Single file scan** - Otherwise → **Directory scan** 4. For directory scan: - If `/tree/{branch}/{path}` exists, extract `branch` and `path` - If no `/tree/`, set `branch` to empty (use default) and `path` to empty string 5. For single file scan: - Extract `branch` and file path after `/blob/{branch}/` **Examples**: - `https://github.com/hiroro-work/claude-plugins` → Directory scan, branch="", path="" - `https://github.com/hiroro-work/claude-plugins/tree/main/plugins/ask-claude` → Directory scan (plugin), branch="main", path="plugins/ask-claude" - `https://github.com/hiroro-work/claude-plugins/tree/main/.claude/skills/my-skill` → Directory scan (skill), branch="main", path=".claude/skills/my-skill" - `https://github.com/owner/repo/blob/main/skills/my-skill/SKILL.md` → Single file scan, branch="main" #### Step 2-URL-2: Fetch Content **For Single File Scan:** 1. Convert `/blob/` URL to raw URL: `https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path}` 2. Use WebFetch to fetch the file content 3. Proceed directly to **Step 5** for analysis **For Directory Scan:** 1. Fetch directory: `https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={branch}` - If branch is empty, omit `?ref=` parameter (uses default branch) - Use WebFetch with prompt: "Extract the JSON array of files. For each item, return: name, type (file/dir), download_url" 2. Determine content type and fetch accordingly: - **If `plugin.json` exists**: Full plugin scan (fetch all plugin files) - **If `skills/` exists**: Skill scan (fetch skill directories) - **If `SKILL.md` exists**: Single skill directory scan (fetch all files in directory) - **If none of the above**: Error "No scannable content found. Expected plugin.json, skills/ directory, or SKILL.md." 3. Recursively fetch required directories: - `skills/` → fetch subdirectories → fetch `SKILL.md` files - `agents/` → fetch all `*.md` files (if exists) - `hooks/` → fetch all `*.md` files (if exists) - `commands/` → fetch all `*.md` files (if exists) #### Step 2-URL-3: Fetch File Contents **For plugin scan**, fetch: - `plugin.json`, `README.md`, `.mcp.json` - `skills/*/SKILL.md`, `agents/*.md`, `hooks/*.md`, `commands/*.md` **For skill directory scan** (skills/ or single skill), fetch: - All files in the skill directory Use WebFetch with prompt: "Return the raw file content exactly as-is" #### Step 2-URL-4: Error Handling - 404: Repository or path not found - 403/401: Private repo (not supported) or rate limit exceeded - Other errors: Report the error message After fetching all files, proceed to **Step 5** for analysis. --- ### Step 3: Get Scan Targets Based on scope determined in Step 2 and `target_agents` from Step 1, collect targets: **For plugins (Claude Code only):** *User-level:* 1. Read `~/.claude/plugins/installed_plugins.json` 2. Extract plugin name (e.g., `ask-claude@hiropon-plugins`) and `installPath` 3. If file doesn't exist, report "No user-level plugins installed" *Project-level:* 1. Use Glob to find plugins in `.claude/plugins/*/` 2. If no plugins found, report "No project-level plugins found" **For skills (based on target_agents):** For each agent in `target_agents` list, collect skills from the corresponding directories: **Agent path mapping:** | Agent | Project Level | User Level | |-------|---------------|------------| | claude | `.claude/skills/*/` | `~/.claude/skills/*/` | | codex | `.codex/skills/*/` | `~/.codex/skills/*/` | | gemini | `.gemini/skills/*/` | `~/.gemini/skills/*/` | | agents | `.agents/skills/*/` | `~/.config/agents/skills/*/` AND `~/.agents/skills/*/` | **For each agent in target_agents:** *User-level:* 1. Determine user-level path(s) based on agent ID (see table above) 2. For `agents`: Check both `~/.config/agents/skills/*/` and `~/.agents/skills/*/` 3. Find skill directories in the path 4. For each skill directory found, note the path and agent ID for scanning 5. If no skills found for this agent, report "No user-level skills found for {agent}" *Project-level:* 1. Determine project-level path based on agent ID (see table above) 2. Find skill directories in the path 3. For each skill directory found, note the path and agent ID for scanning 4. If no skills found for this agent, report "No project-level skills found for {agent}" ### Step 4: Filter Targets
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub