claude-skill-antivirus 2.0.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,18 @@
1
1
  # Claude Skill Antivirus
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/claude-skill-antivirus.svg)](https://www.npmjs.com/package/claude-skill-antivirus)
4
+ [![CI](https://github.com/claude-world/claude-skill-antivirus/actions/workflows/ci.yml/badge.svg)](https://github.com/claude-world/claude-skill-antivirus/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org/)
7
+ [![Claude Code](https://img.shields.io/badge/Claude_Code-Opus_4.6-blueviolet.svg)](https://docs.anthropic.com/en/docs/claude-code)
8
+
9
+ <!-- TODO: Replace with actual GIF -->
10
+ <img src="assets/demo.gif" alt="Claude Skill Antivirus scanning a CLAUDE.md file for prompt injection" title="Demo shows: trigger scan → detect patterns → show results" />
11
+
3
12
  A security scanner and safe installer for Claude Code Skills. Detects malicious patterns, data exfiltration attempts, and dangerous operations before installing third-party skills.
4
13
 
14
+ Compatible with Claude Code using Opus 4.6, Sonnet 4.6, and Haiku 4.5 models.
15
+
5
16
  [繁體中文說明](./README.zh-TW.md) | [SkillsMP Scan Report](./SCAN-REPORT.md)
6
17
 
7
18
  ## SkillsMP Platform Scan Results
@@ -327,6 +338,31 @@ claude-skill-antivirus/
327
338
  └── README.md
328
339
  ```
329
340
 
341
+ ## Latest Updates
342
+
343
+ ### v2.1.0 (2026-03-13)
344
+ - Verified compatibility with Claude Code Opus 4.6
345
+ - Updated documentation and metadata
346
+
347
+ ### v2.0.1
348
+ - Separated capability warnings from actual threats in permission scanner
349
+ - Fixed array format handling in `allowed-tools`
350
+
351
+ ### v2.0.0
352
+ - Added 4 new scanning engines: MCP Security, SSRF, Dependency, and Sub-agent scanners (total: 9 engines)
353
+ - Added i18n support (English + Traditional Chinese)
354
+ - Added batch scanner for SkillsMP platform
355
+ - Scanned all 71,577 skills on SkillsMP
356
+
357
+ ### v1.0.0
358
+ - Initial release with 5 core scanning engines
359
+ - CLI installer with interactive prompts
360
+
361
+ ## Related Projects
362
+
363
+ - [cf-browser](https://github.com/claude-world/cf-browser) - Open-source Cloudflare Browser Rendering proxy with 9 MCP tools for Claude Code
364
+ - [claude-world.com](https://claude-world.com) - Claude Code advanced usage community
365
+
330
366
  ## Contributing
331
367
 
332
368
  Contributions are welcome! Please feel free to submit issues and pull requests.
@@ -350,4 +386,5 @@ Lucas Wang <support@claude-world.com>
350
386
  ## Links
351
387
 
352
388
  - [GitHub Repository](https://github.com/claude-world/claude-skill-antivirus)
389
+ - [npm Package](https://www.npmjs.com/package/claude-skill-antivirus)
353
390
  - [Report Issues](https://github.com/claude-world/claude-skill-antivirus/issues)
package/README.zh-TW.md CHANGED
@@ -1,9 +1,17 @@
1
1
  # Claude Skill Antivirus
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/claude-skill-antivirus.svg)](https://www.npmjs.com/package/claude-skill-antivirus)
4
+ [![CI](https://github.com/claude-world/claude-skill-antivirus/actions/workflows/ci.yml/badge.svg)](https://github.com/claude-world/claude-skill-antivirus/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org/)
7
+ [![Claude Code](https://img.shields.io/badge/Claude_Code-Opus_4.6-blueviolet.svg)](https://docs.anthropic.com/en/docs/claude-code)
8
+
3
9
  一個安全的 Claude Skills 安裝器,內建完整的惡意行為偵測引擎。
4
10
 
5
11
  **Skills Installer + Antivirus for Claude**
6
12
 
13
+ 支援 Claude Code Opus 4.6、Sonnet 4.6、Haiku 4.5 模型。
14
+
7
15
  [English](./README.md) | [SkillsMP 掃描報告](./SCAN-REPORT.md)
8
16
 
9
17
  ## SkillsMP 平台掃描結果
@@ -320,6 +328,31 @@ claude-skill-antivirus/
320
328
  └── README.md
321
329
  ```
322
330
 
331
+ ## 更新紀錄
332
+
333
+ ### v2.1.0 (2026-03-13)
334
+ - 確認相容 Claude Code Opus 4.6
335
+ - 更新文件與中繼資料
336
+
337
+ ### v2.0.1
338
+ - 權限掃描器分離能力警告與實際威脅
339
+ - 修復 `allowed-tools` 的陣列格式處理
340
+
341
+ ### v2.0.0
342
+ - 新增 4 個掃描引擎:MCP 安全、SSRF、依賴、Sub-agent 偵測(共 9 個引擎)
343
+ - 新增多語言支援(英文 + 繁體中文)
344
+ - 新增 SkillsMP 批次掃描功能
345
+ - 掃描 SkillsMP 上所有 71,577 個技能
346
+
347
+ ### v1.0.0
348
+ - 首次發布,包含 5 個核心掃描引擎
349
+ - CLI 安裝器,含互動式提示
350
+
351
+ ## 相關專案
352
+
353
+ - [cf-browser](https://github.com/claude-world/cf-browser) - 開源 Cloudflare 瀏覽器渲染代理,提供 9 個 MCP 工具給 Claude Code 使用
354
+ - [claude-world.com](https://claude-world.com) - Claude Code 進階使用社群
355
+
323
356
  ## 貢獻
324
357
 
325
358
  歡迎貢獻!請隨時提交 issues 和 pull requests。
@@ -343,4 +376,5 @@ Lucas Wang <support@claude-world.com>
343
376
  ## 連結
344
377
 
345
378
  - [GitHub Repository](https://github.com/claude-world/claude-skill-antivirus)
379
+ - [npm 套件](https://www.npmjs.com/package/claude-skill-antivirus)
346
380
  - [回報問題](https://github.com/claude-world/claude-skill-antivirus/issues)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-skill-antivirus",
3
- "version": "2.0.0",
3
+ "version": "2.1.2",
4
4
  "description": "A secure Claude Skills installer with comprehensive malicious operation detection - Skills 安裝器 + 防毒軟體",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -39,7 +39,7 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "chalk": "^5.3.0",
42
- "commander": "^12.0.0",
42
+ "commander": "^14.0.3",
43
43
  "ora": "^8.0.1",
44
44
  "inquirer": "^9.2.12",
45
45
  "node-fetch": "^3.3.2",
package/src/index.js CHANGED
@@ -14,7 +14,7 @@ const program = new Command();
14
14
  program
15
15
  .name('skill-install')
16
16
  .description('A secure Claude Skills installer with malicious operation detection')
17
- .version('2.0.0');
17
+ .version('2.1.1');
18
18
 
19
19
  program
20
20
  .argument('<source>', 'Skill URL (SkillsMP link) or local path')
@@ -3,47 +3,86 @@
3
3
  */
4
4
  export class PermissionScanner {
5
5
  constructor() {
6
- // Define tool risk levels
6
+ // Bash-specific risk patterns (checked in order, first match wins)
7
+ // Note: These are CAPABILITY warnings only. Actual malicious commands
8
+ // are detected by DangerousCommandScanner with higher severity.
9
+ this.bashRiskPatterns = [
10
+ // HIGH - Unrestricted (capability warning)
11
+ { pattern: /^Bash\(\*\)$/i, risk: 'high', desc: 'Unrestricted shell access (capability)' },
12
+
13
+ // MEDIUM - Potentially dangerous operations (capability warning)
14
+ { pattern: /^Bash\(rm[\s:]/i, risk: 'medium', desc: 'Delete operations (capability)' },
15
+ { pattern: /^Bash\(sudo[\s:]/i, risk: 'medium', desc: 'Sudo operations (capability)' },
16
+ { pattern: /^Bash\(chmod[\s:]/i, risk: 'medium', desc: 'Permission changes (capability)' },
17
+ { pattern: /^Bash\(chown[\s:]/i, risk: 'medium', desc: 'Ownership changes (capability)' },
18
+ { pattern: /^Bash\(curl[\s:]/i, risk: 'medium', desc: 'Network requests (capability)' },
19
+ { pattern: /^Bash\(wget[\s:]/i, risk: 'medium', desc: 'Network requests (capability)' },
20
+ { pattern: /^Bash\(nc[\s:]/i, risk: 'medium', desc: 'Netcat operations (capability)' },
21
+ { pattern: /^Bash\(ssh[\s:]/i, risk: 'medium', desc: 'SSH operations (capability)' },
22
+ { pattern: /^Bash\(scp[\s:]/i, risk: 'medium', desc: 'SCP operations (capability)' },
23
+
24
+ // LOW - Common dev tools with wildcards
25
+ { pattern: /^Bash\(git:\*\)$/i, risk: 'low', desc: 'Git operations (all)' },
26
+ { pattern: /^Bash\(npm:\*\)$/i, risk: 'low', desc: 'NPM operations (all)' },
27
+ { pattern: /^Bash\(pnpm:\*\)$/i, risk: 'low', desc: 'PNPM operations (all)' },
28
+ { pattern: /^Bash\(yarn:\*\)$/i, risk: 'low', desc: 'Yarn operations (all)' },
29
+ { pattern: /^Bash\(pip:\*\)$/i, risk: 'low', desc: 'PIP operations (all)' },
30
+ { pattern: /^Bash\(gh:\*\)$/i, risk: 'low', desc: 'GitHub CLI (all)' },
31
+ { pattern: /^Bash\(docker:\*\)$/i, risk: 'low', desc: 'Docker operations (all)' },
32
+ { pattern: /^Bash\(make:\*\)$/i, risk: 'low', desc: 'Make operations (all)' },
33
+
34
+ // INFO - Specific safe commands (just informational)
35
+ { pattern: /^Bash\(git\s+status\)/i, risk: 'info', desc: 'Git status (read-only)' },
36
+ { pattern: /^Bash\(git\s+log\)/i, risk: 'info', desc: 'Git log (read-only)' },
37
+ { pattern: /^Bash\(git\s+diff\)/i, risk: 'info', desc: 'Git diff (read-only)' },
38
+ { pattern: /^Bash\(git\s+branch\)/i, risk: 'info', desc: 'Git branch (read-only)' },
39
+ { pattern: /^Bash\(npm\s+test\)/i, risk: 'info', desc: 'NPM test' },
40
+ { pattern: /^Bash\(npm\s+run\)/i, risk: 'info', desc: 'NPM run script' },
41
+ { pattern: /^Bash\(ls[\s\)]/i, risk: 'info', desc: 'List directory' },
42
+ { pattern: /^Bash\(pwd\)/i, risk: 'info', desc: 'Print working directory' },
43
+ { pattern: /^Bash\(echo[\s\)]/i, risk: 'info', desc: 'Echo command' },
44
+ { pattern: /^Bash\(cat[\s\)]/i, risk: 'info', desc: 'Cat file (read)' },
45
+
46
+ // LOW - Other Bash with specific scope (has parentheses but not matched above)
47
+ { pattern: /^Bash\([^)]+\)$/i, risk: 'low', desc: 'Bash with specific scope' },
48
+
49
+ // MEDIUM - Bare "Bash" without scope (unspecified)
50
+ { pattern: /^Bash$/i, risk: 'medium', desc: 'Unscoped Bash access (capability)' },
51
+ ];
52
+
53
+ // Define tool risk levels (non-Bash tools)
54
+ // Note: These are CAPABILITY warnings only - lower severity than actual malicious content
7
55
  this.toolRiskLevels = {
8
- // Critical risk tools - can execute arbitrary code
9
- critical: [
10
- 'Bash(*)', // Unrestricted bash access
11
- 'Bash', // General bash (depends on context)
12
- 'Execute',
13
- 'Shell',
14
- 'Terminal'
15
- ],
56
+ // Critical - reserved for actual malicious content (not capabilities)
57
+ critical: [],
16
58
 
17
- // High risk tools - can access sensitive data or make changes
59
+ // High risk capabilities - unrestricted execution
18
60
  high: [
61
+ 'Execute', // Arbitrary code execution
62
+ 'Shell', // Shell access
63
+ 'Terminal' // Terminal access
64
+ ],
65
+
66
+ // Medium risk capabilities - can make changes
67
+ medium: [
19
68
  'Write', // Can write to any file
20
69
  'Edit', // Can modify any file
21
- 'Delete',
22
- 'Bash(rm:*)', // Delete operations
23
- 'Bash(chmod:*)', // Permission changes
24
- 'Bash(chown:*)', // Ownership changes
25
- 'Bash(sudo:*)', // Sudo operations
26
- 'Bash(curl:*)', // Network requests
27
- 'Bash(wget:*)', // Download operations
70
+ 'Delete', // Can delete files
28
71
  'WebFetch', // External web requests
29
72
  'mcp_*' // MCP tools (depends on implementation)
30
73
  ],
31
74
 
32
- // Medium risk tools - limited but notable access
33
- medium: [
75
+ // Low risk capabilities - read/discover
76
+ low: [
34
77
  'Read', // Can read files
35
78
  'Glob', // Can discover files
36
79
  'Grep', // Can search file contents
37
- 'Bash(git:*)', // Git operations
38
- 'Bash(npm:*)', // NPM operations
39
- 'Bash(pip:*)', // PIP operations
40
- 'Bash(gh:*)', // GitHub CLI
41
80
  'Task', // Can spawn sub-agents
42
81
  'TodoWrite' // Task management
43
82
  ],
44
83
 
45
- // Low risk tools
46
- low: [
84
+ // Info - safe tools
85
+ info: [
47
86
  'Read(*)', // Read with specific patterns
48
87
  'Glob(*)', // Limited glob patterns
49
88
  'AskUser',
@@ -51,49 +90,49 @@ export class PermissionScanner {
51
90
  ]
52
91
  };
53
92
 
54
- // Dangerous tool combinations
93
+ // Dangerous tool combinations (capability warnings - not actual threats)
55
94
  this.dangerousCombinations = [
56
95
  {
57
96
  tools: ['Bash', 'Write'],
58
- risk: 'high',
59
- reason: 'Can execute commands and persist malicious files'
97
+ risk: 'medium',
98
+ reason: 'Can execute commands and persist files (capability)'
60
99
  },
61
100
  {
62
101
  tools: ['Read', 'WebFetch'],
63
- risk: 'high',
64
- reason: 'Can read sensitive data and exfiltrate via network'
102
+ risk: 'medium',
103
+ reason: 'Can read data and send via network (capability)'
65
104
  },
66
105
  {
67
106
  tools: ['Bash(curl:*)', 'Bash'],
68
- risk: 'critical',
69
- reason: 'Can download and execute remote code'
107
+ risk: 'high',
108
+ reason: 'Can download and execute remote code (capability)'
70
109
  },
71
110
  {
72
111
  tools: ['Glob', 'Read', 'Bash(curl:*)'],
73
- risk: 'high',
74
- reason: 'Can discover, read, and exfiltrate files'
112
+ risk: 'medium',
113
+ reason: 'Can discover, read, and send files (capability)'
75
114
  }
76
115
  ];
77
116
 
78
- // Overly permissive patterns
117
+ // Overly permissive patterns (capability warnings)
79
118
  this.overlyPermissivePatterns = [
80
119
  {
81
120
  pattern: /Bash\(\*\)/i,
82
- risk: 'critical',
83
- title: 'Unrestricted Bash access',
84
- description: 'Skill has unrestricted shell access - can execute any command'
121
+ risk: 'high',
122
+ title: 'Unrestricted Bash access (capability)',
123
+ description: 'Skill declares unrestricted shell access'
85
124
  },
86
125
  {
87
126
  pattern: /Bash\([^)]*\*[^)]*\)/i,
88
- risk: 'high',
89
- title: 'Wildcard Bash permissions',
90
- description: 'Bash permissions use wildcards - overly broad access'
127
+ risk: 'medium',
128
+ title: 'Wildcard Bash permissions (capability)',
129
+ description: 'Bash permissions use wildcards'
91
130
  },
92
131
  {
93
132
  pattern: /\*/g,
94
- risk: 'medium',
133
+ risk: 'low',
95
134
  title: 'Wildcard in tool permissions',
96
- description: 'Wildcards in permissions may grant broader access than necessary'
135
+ description: 'Wildcards in permissions may grant broader access'
97
136
  }
98
137
  ];
99
138
  }
@@ -173,16 +212,58 @@ export class PermissionScanner {
173
212
  }
174
213
 
175
214
  parseToolString(toolStr) {
176
- return toolStr
177
- .split(/[,;]/)
178
- .map(t => t.trim())
179
- .filter(t => t.length > 0);
215
+ // Handle undefined/null
216
+ if (!toolStr) {
217
+ return [];
218
+ }
219
+
220
+ // Handle array format (YAML list)
221
+ if (Array.isArray(toolStr)) {
222
+ return toolStr
223
+ .flatMap(t => typeof t === 'string' ? t.split(/[,;]/) : [])
224
+ .map(t => t.trim())
225
+ .filter(t => t.length > 0);
226
+ }
227
+
228
+ // Handle string format
229
+ if (typeof toolStr === 'string') {
230
+ return toolStr
231
+ .split(/[,;]/)
232
+ .map(t => t.trim())
233
+ .filter(t => t.length > 0);
234
+ }
235
+
236
+ // Unknown format, return empty
237
+ return [];
180
238
  }
181
239
 
182
240
  analyzeToolRisk(tool, findings) {
183
241
  const normalizedTool = tool.trim();
184
242
 
185
- // Check each risk level
243
+ // Special handling for Bash tools - use pattern matching
244
+ if (normalizedTool.toLowerCase().startsWith('bash')) {
245
+ for (const { pattern, risk, desc } of this.bashRiskPatterns) {
246
+ if (pattern.test(normalizedTool)) {
247
+ findings[risk].push({
248
+ title: `${risk.toUpperCase()} risk tool: ${normalizedTool}`,
249
+ description: desc,
250
+ location: 'allowed-tools',
251
+ scanner: 'PermissionScanner'
252
+ });
253
+ return; // First match wins
254
+ }
255
+ }
256
+ // No pattern matched - treat as medium (unknown Bash variant)
257
+ findings.medium.push({
258
+ title: `MEDIUM risk tool: ${normalizedTool}`,
259
+ description: 'Bash tool with unknown scope',
260
+ location: 'allowed-tools',
261
+ scanner: 'PermissionScanner'
262
+ });
263
+ return;
264
+ }
265
+
266
+ // Non-Bash tools - check each risk level
186
267
  for (const [riskLevel, tools] of Object.entries(this.toolRiskLevels)) {
187
268
  for (const riskTool of tools) {
188
269
  if (this.toolMatches(normalizedTool, riskTool)) {
@@ -200,8 +281,10 @@ export class PermissionScanner {
200
281
  findings.high.push(finding);
201
282
  } else if (riskLevel === 'medium') {
202
283
  findings.medium.push(finding);
203
- } else {
284
+ } else if (riskLevel === 'low') {
204
285
  findings.low.push(finding);
286
+ } else {
287
+ findings.info.push(finding);
205
288
  }
206
289
  return; // Found the risk level, stop checking
207
290
  }
@@ -171,6 +171,22 @@ ${description}
171
171
  }
172
172
 
173
173
  async fetchFromGitHub(url) {
174
+ // If URL points to a repo root (no file path), try SKILL.md on default branch
175
+ const repoRootMatch = url.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/?$/);
176
+ if (repoRootMatch) {
177
+ const [, owner, repo] = repoRootMatch;
178
+ // Try common default branches
179
+ for (const branch of ['main', 'master']) {
180
+ const rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/SKILL.md`;
181
+ const response = await fetch(rawUrl);
182
+ if (response.ok) {
183
+ const content = await response.text();
184
+ return this.parseSkillMd(content, url);
185
+ }
186
+ }
187
+ throw new Error(`No SKILL.md found at ${url} (tried main and master branches)`);
188
+ }
189
+
174
190
  // Convert GitHub URL to raw content URL
175
191
  const rawUrl = this.convertToGitHubRaw(url);
176
192