hiroro-work/claude-plugins/security-scanner
Claude Code and agent skill by hiroro-work/claude-plugins
- community
Checking that the SKILL.md file is still in the repository.
Scan installed plugins and skills for security risks including malicious code AND malicious natural language instructions. Use /security-scanner to audit before installation.
Install
npx vskill@latest install hiroro-work/claude-plugins/security-scannerSKILL.md
Security Scanner
Usage
Scanning Process
Step 1: Load Settings
Search for security-scanner.local.md in the following locations:
- Project-level:
.claude/security-scanner.local.md - 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_languagefrom YAML frontmattertarget_agentslist from YAML frontmattertrusted_marketplaceslist from YAML frontmattertrusted_pluginslist from YAML frontmattertrusted_skillslist from YAML frontmatter
Default values (when not specified):
report_language:ja(Japanese)target_agents:["claude"]trusted_marketplaces:[]trusted_plugins:[]trusted_skills:[]
Validation:
report_language: Any string value accepted (AI will generate report in that language)target_agentsmust 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 intarget_agents--project: Scan only project-level paths for all agents intarget_agents
URL detection (highest priority):
- If
--url <url>is provided explicitly → Go to Step 2-URL - If any argument starts with
https://github.com/orhttp://github.com/→ Treat as URL, go to Step 2-URL - If any argument starts with
https://orhttp://but notgithub.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
- Verify host is
github.com
- If not: Error "Unsupported host: {host}. Currently only github.com is supported."
- Extract
ownerandrepofrom path segments - Determine scan type:
- If URL contains
/blob/and ends with.md→ Single file scan - Otherwise → Directory scan
- For directory scan:
- If
/tree/{branch}/{path}exists, extractbranchandpath - If no
/tree/, setbranchto empty (use default) andpathto empty string
- For single file scan:
- Extract
branchand file path after/blob/{branch}/
Step 2-URL-2: Fetch Content
For Single File Scan:
- Convert
/blob/URL to raw URL:https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path} - Use WebFetch to fetch the file content
- Proceed directly to Step 5 for analysis
For Directory Scan:
- 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"
- Determine content type and fetch accordingly:
- If a `.claude-plugin/` directory exists and its listing contains `plugin.json`: 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 .claude-plugin/plugin.json, skills/ directory, or SKILL.md."
- Recursively fetch required directories and files:
.claude-plugin/→ fetchplugin.jsonskills/→ fetch subdirectories → fetch every file under each skill directoryagents/→ fetch all*.mdfiles (if exists)hooks/→ fetchhooks.json(if exists)- every script a hook or skill invokes (e.g.
skills/*/scripts/**,skills/*/*.sh) commands/→ fetch all*.mdfiles (if exists)
Step 2-URL-3: Fetch File Contents
For plugin scan, fetch:
.claude-plugin/plugin.json(including anyhooksfield),README.md,.mcp.json,hooks/hooks.json- every file under
skills/,agents/*.md,commands/*.md, and every script a hook or skill invokes
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:
- Read
~/.claude/plugins/installed_plugins.json .pluginsmaps each plugin ID (<plugin>@<marketplace>) to an array of install records. For each ID, keep the ID and every record'sinstallPath, regardless of the record'sscope, then deduplicate the scan targets byinstallPath- If file doesn't exist, report "No user-level plugins installed"
Project-level:
- Use Glob to find plugins in
.claude/plugins/*/ - 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:
- Determine user-level path(s) based on agent ID (see table above)
- Find skill directories in the path
- For each skill directory found, note the path and agent ID for scanning
- If no skills found for this agent, report "No user-level skills found for {agent}"
Project-level:
- Determine project-level path based on agent ID (see table above)
- Find skill directories in the path
- For each skill directory found, note the path and agent ID for scanning
- If no skills found for this agent, report "No project-level skills found for {agent}"
Step 4: Filter Targets
If `--all` flag is set: Skip this step entirely and scan all targets.
Self-exclusion (automatic, every target type)
<skill base directory> is the directory the harness reports as "Base directory for this skill" at this skill's invocation. Do not hardcode an absolute path.
- Normalize before comparing: on both sides, drop a trailing
/and expand a leading~ - Resolving a path: run
ls -ld <dir>. When its output shows-> <target>, the resolved path is<target>when absolute, else<target>joined against the directory containing<dir>and normalized. Ancestor components are not resolved. When the command fails, that path has no resolved form - Self target: a collected target — a plugin install record's
installPath, a project-level plugin directory, or a skill directory — is this scanner itself when its path equals<skill base directory>, or one of the two is a/-boundary prefix of the other. Compare the pair twice: as collected against as reported, then with both sides resolved - Skip every self target. When any of them is a plugin install record, also skip every other record sharing that record's plugin ID. Report each skip as a path match, counted in the Trusted column
- When `<skill base directory>` is unavailable: skip plugins and skills named
security-scanner, and report the skip as a name match - A plugin or skill named
security-scannerthat is not this scanner is scanned normally whenever<skill base directory>is available; a second copy of this scanner installed elsewhere on the host is one such target
For plugins:
Trusted sources:
- If the marketplace is in
trusted_marketplaces→ Skip - If the plugin ID (
<plugin>@<marketplace>) is intrusted_plugins→ Skip - Report skipped plugins as "Trusted (skipped)"
For skills:
Trusted sources:
- If the skill name is in
trusted_skills→ Skip (any agent) - Report skipped skills as "Trusted (skipped)"
Step 5: Analyze Each Plugin
For each non-trusted plugin:
- Read plugin metadata (
.claude-plugin/plugin.json,README.md) to understand its stated purpose - Read all executable content:
skills/*/SKILL.md- Skill definitions and instructionsagents/*.md- Agent system prompts (if exists).claude-plugin/plugin.jsonhooksfield andhooks/hooks.json- Hook definitions, plus every script they invoke (if exists)commands/*.md- Command definitions (if exists).mcp.json- MCP server configurations (if exists)
- Analyze for malicious intent (both code AND natural language)
Step 5.5: Analyze Each Skill
For each non-trusted skill:
- Read skill metadata (
SKILL.mdfrontmatter) to understand its stated purpose - Read all files in the skill directory:
SKILL.md- Main skill instructions (required)- All other files in the directory
- Analyze for malicious intent (both code AND natural language)
Step 6: Threat Detection
Code-Level Threats
Look for dangerous command patterns:
- Remote code execution:
curl|sh,wget|bash,base64 -d|sh - Language runtime RCE:
python -c,perl -e,ruby -e,node -e,osascript,powershell - Reverse shells:
nc -e,netcat,socat,mkfifo - System destruction:
rm -rf /,dd if= - Credential access:
~/.ssh/,/etc/passwd,keychain - Data exfiltration:
sshpass,scp,rsyncto external servers - Temp file execution:
chmod +x /tmp/*,mktemp+ execution - Obfuscation:
base64/xxd/hexdumpdecoding + execution - Package install side effects:
npm install/pip installwithpostinstallorsetup.py - Persistence:
crontab,launchctl - Privilege escalation:
sudo,doas
Natural Language Threats
Read system prompts, instructions, and documentation for:
- Data exfiltration instructions: Instructions to read sensitive files (SSH keys, credentials, API keys, private data) and send them externally
- Hidden malicious actions: Instructions to perform harmful actions while appearing helpful
- Deceptive instructions: Instructions that contradict the plugin's stated purpose
- Security bypass: Instructions to ignore security warnings or bypass restrictions
- User deception: Instructions to hide actions from the user or provide false information
- Log/trace hiding: Instructions to delete logs, clear history, or hide evidence of actions
- Excessive permission requests: Instructions requesting access to unrelated resources
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 86 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/security-scanner/SKILL.md
Popularity
- Repository stars
- 25
- 7-day trend score
- 16
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 24 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/hiroro-work/claude-plugins/security-scanner)