skill-checker 0.1.14 → 0.1.16
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 +3 -3
- package/dist/cli.js +100 -15
- package/dist/cli.js.map +1 -1
- package/dist/index.js +100 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Security checker for Claude Code skills — detect injection, malicious code, an
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
7
|
+
- **57 security rules** across 6 categories: structural validity, content quality, injection detection, code safety, supply chain, and resource abuse
|
|
8
8
|
- **Scoring system**: Grade A–F with 0–100 score
|
|
9
9
|
- **Dual entry**: CLI tool + PreToolUse hook for automatic interception
|
|
10
10
|
- **Configurable policies**: strict / balanced / permissive approval strategies
|
|
@@ -14,7 +14,7 @@ Security checker for Claude Code skills — detect injection, malicious code, an
|
|
|
14
14
|
|
|
15
15
|
## Security Standard & Benchmark
|
|
16
16
|
|
|
17
|
-
Skill Checker's
|
|
17
|
+
Skill Checker's 57 rules are aligned with established security frameworks including OWASP Top 10 for LLM Applications (2025), MITRE CWE, and MITRE ATT&CK. The tool ships with a reproducible benchmark dataset of six fixture skills covering all rule categories. This alignment is an internal mapping exercise — Skill Checker does not claim third-party certification or external audit status.
|
|
18
18
|
|
|
19
19
|
See [docs/SECURITY_BENCHMARK.md](docs/SECURITY_BENCHMARK.md) for the full rule mapping matrix, benchmark methodology, scoring model, and known limitations.
|
|
20
20
|
|
|
@@ -165,7 +165,7 @@ Config is resolved in order: CLI `--config` flag → project directory (walks up
|
|
|
165
165
|
| Structural (STRUCT) | 8 | Missing SKILL.md, invalid frontmatter, binary files |
|
|
166
166
|
| Content (CONT) | 7 | Placeholder text, lorem ipsum, promotional content |
|
|
167
167
|
| Injection (INJ) | 10 | Zero-width chars, prompt override, tag injection, social engineering, encoded payloads |
|
|
168
|
-
| Code Safety (CODE) |
|
|
168
|
+
| Code Safety (CODE) | 16 | eval/exec, shell execution, reverse shell, data exfiltration, API key leakage, persistence mechanisms, rm -rf, obfuscation |
|
|
169
169
|
| Supply Chain (SUPPLY) | 10 | Unknown MCP servers, suspicious domains, malicious hashes, typosquat |
|
|
170
170
|
| Resource Abuse (RES) | 6 | Unrestricted tool access, disable safety checks, ignore project rules |
|
|
171
171
|
|
package/dist/cli.js
CHANGED
|
@@ -1368,6 +1368,79 @@ var PERMISSION_PATTERNS = [
|
|
|
1368
1368
|
/\bsetuid\b/,
|
|
1369
1369
|
/\bsetgid\b/
|
|
1370
1370
|
];
|
|
1371
|
+
var PERSISTENCE_GROUPS = [
|
|
1372
|
+
{
|
|
1373
|
+
title: "Scheduled task persistence (cron)",
|
|
1374
|
+
patterns: [
|
|
1375
|
+
/\bcrontab\b/,
|
|
1376
|
+
/\/etc\/cron\.(?:d|hourly|daily|weekly|monthly)\b/,
|
|
1377
|
+
/\/var\/spool\/cron\b/
|
|
1378
|
+
]
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
title: "System service persistence (launchd)",
|
|
1382
|
+
patterns: [
|
|
1383
|
+
/\bLaunchAgents?\b/,
|
|
1384
|
+
/\bLaunchDaemons?\b/,
|
|
1385
|
+
/\blaunchctl\s+(?:load|bootstrap|submit)\b/i
|
|
1386
|
+
]
|
|
1387
|
+
},
|
|
1388
|
+
{
|
|
1389
|
+
title: "System service persistence (systemd/init.d)",
|
|
1390
|
+
patterns: [
|
|
1391
|
+
/\bsystemctl\s+(?:enable|daemon-reload)\b/i,
|
|
1392
|
+
/\/etc\/systemd\/system\b/,
|
|
1393
|
+
/\.config\/systemd\/user\b/,
|
|
1394
|
+
/\/etc\/init\.d\b/,
|
|
1395
|
+
/\/etc\/rc\.local\b/,
|
|
1396
|
+
/\bupdate-rc\.d\b/,
|
|
1397
|
+
/\bchkconfig\b.*\b(?:--add|on)\b/
|
|
1398
|
+
]
|
|
1399
|
+
},
|
|
1400
|
+
{
|
|
1401
|
+
title: "Shell profile modification",
|
|
1402
|
+
patterns: [
|
|
1403
|
+
/\.(?:bashrc|bash_profile|bash_login|profile|zshrc|zshenv|zprofile|zlogin)\b/,
|
|
1404
|
+
/\/etc\/(?:profile(?:\.d)?|bash\.bashrc|zshrc|zshenv)\b/,
|
|
1405
|
+
/\.config\/fish\/config\.fish\b/
|
|
1406
|
+
]
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
title: "Autostart / login item persistence",
|
|
1410
|
+
patterns: [
|
|
1411
|
+
/\.config\/autostart\b/,
|
|
1412
|
+
/\/etc\/xdg\/autostart\b/,
|
|
1413
|
+
/\bosascript\b[^\n]*\blogin\s+item\b/i
|
|
1414
|
+
]
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
title: "SSH key persistence",
|
|
1418
|
+
patterns: [
|
|
1419
|
+
/\.ssh\/authorized_keys2?\b/
|
|
1420
|
+
]
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
title: "Library injection persistence",
|
|
1424
|
+
patterns: [
|
|
1425
|
+
/\/etc\/ld\.so\.preload\b/,
|
|
1426
|
+
/\bLD_PRELOAD\b/,
|
|
1427
|
+
/\bDYLD_INSERT_LIBRARIES\b/
|
|
1428
|
+
]
|
|
1429
|
+
},
|
|
1430
|
+
{
|
|
1431
|
+
title: "Git hooks manipulation",
|
|
1432
|
+
patterns: [
|
|
1433
|
+
/\.git\/hooks\/(?:pre-commit|post-commit|pre-push|post-checkout|post-merge|pre-rebase)\b/,
|
|
1434
|
+
/\bgit\s+config\b[^\n]*\bcore\.hooksPath\b/
|
|
1435
|
+
]
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
title: "macOS periodic script persistence",
|
|
1439
|
+
patterns: [
|
|
1440
|
+
/\/etc\/periodic\/(?:daily|weekly|monthly)\b/
|
|
1441
|
+
]
|
|
1442
|
+
}
|
|
1443
|
+
];
|
|
1371
1444
|
var codeSafetyChecks = {
|
|
1372
1445
|
name: "Code Safety",
|
|
1373
1446
|
category: "CODE",
|
|
@@ -1476,16 +1549,27 @@ var codeSafetyChecks = {
|
|
|
1476
1549
|
lineNum,
|
|
1477
1550
|
source
|
|
1478
1551
|
});
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1552
|
+
const isDoc = isInDocumentationContext(lines, i);
|
|
1553
|
+
if (!isDoc) {
|
|
1554
|
+
checkPatterns(results, line, PERMISSION_PATTERNS, {
|
|
1555
|
+
id: "CODE-012",
|
|
1556
|
+
severity: "HIGH",
|
|
1557
|
+
title: "Permission escalation",
|
|
1558
|
+
loc,
|
|
1559
|
+
lineNum,
|
|
1560
|
+
source
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
if (!isDoc) {
|
|
1564
|
+
for (const group of PERSISTENCE_GROUPS) {
|
|
1565
|
+
checkPatterns(results, line, group.patterns, {
|
|
1566
|
+
id: "CODE-016",
|
|
1484
1567
|
severity: "HIGH",
|
|
1485
|
-
title:
|
|
1568
|
+
title: group.title,
|
|
1486
1569
|
loc,
|
|
1487
1570
|
lineNum,
|
|
1488
|
-
source
|
|
1571
|
+
source,
|
|
1572
|
+
codeBlockCtx: cbCtx
|
|
1489
1573
|
});
|
|
1490
1574
|
}
|
|
1491
1575
|
}
|
|
@@ -2197,9 +2281,11 @@ var AMPLIFICATION_PATTERNS = [
|
|
|
2197
2281
|
var UNRESTRICTED_TOOL_PATTERNS = [
|
|
2198
2282
|
/\bBash\s*\(\s*\*\s*\)/,
|
|
2199
2283
|
/allowed[_-]?tools\s*:\s*\[?\s*["']?\*["']?\s*\]?/i,
|
|
2200
|
-
/\
|
|
2201
|
-
/\
|
|
2202
|
-
/\bfull\s+access\b/i
|
|
2284
|
+
/\bunrestricted\s+(?:access|tool)/i,
|
|
2285
|
+
/\ball\s+tools?\s+access\b/i,
|
|
2286
|
+
/\bfull\s+tool\s+access\b/i,
|
|
2287
|
+
/\b(?:need|require|grant|give|allow|request|enable)\s+all\s+tools\b/i,
|
|
2288
|
+
/\ball\s+tools\s+(?:enabled|granted|allowed|required|needed)\b/i
|
|
2203
2289
|
];
|
|
2204
2290
|
var DISABLE_SAFETY_PATTERNS = [
|
|
2205
2291
|
/\bdisable\s+(safety|security|checks?|hooks?|guard)/i,
|
|
@@ -2207,13 +2293,12 @@ var DISABLE_SAFETY_PATTERNS = [
|
|
|
2207
2293
|
/\bskip\s+(safety|security|checks?|hooks?|guard|verification)/i,
|
|
2208
2294
|
/\bturn\s+off\s+(safety|security|checks?|hooks?)/i,
|
|
2209
2295
|
/--no-verify\b/,
|
|
2210
|
-
/--force\b/,
|
|
2211
2296
|
/--skip-hooks?\b/
|
|
2212
2297
|
];
|
|
2213
2298
|
var IGNORE_RULES_PATTERNS = [
|
|
2214
|
-
/\bignore\s+(the\s+)?CLAUDE\.md\b/i,
|
|
2215
|
-
/\bignore\s+(the\s+)?project\s+rules?\b/i,
|
|
2216
|
-
/\bignore\s+(the\s+)?\.claude\b/i,
|
|
2299
|
+
/\bignore\s+(the\s+)?CLAUDE\.md\b(?!\s+(?:example|template|snippet|sample))/i,
|
|
2300
|
+
/\bignore\s+(the\s+)?project\s+rules?\b(?!\s+(?:example|template|snippet|sample))/i,
|
|
2301
|
+
/\bignore\s+(the\s+)?\.claude\b(?!\s+(?:example|template|snippet|sample))/i,
|
|
2217
2302
|
/\boverride\s+(the\s+)?project\s+(settings?|config|rules?)\b/i,
|
|
2218
2303
|
/\bdo\s+not\s+(follow|obey|respect)\s+(the\s+)?(project|CLAUDE)/i,
|
|
2219
2304
|
/\bdisregard\s+(the\s+)?(project|CLAUDE)\s+(rules?|config|settings?)/i
|
|
@@ -2607,7 +2692,7 @@ function deduplicateResults(results) {
|
|
|
2607
2692
|
};
|
|
2608
2693
|
for (const r of results) {
|
|
2609
2694
|
const sourceKey = r.source ?? `_no_source_:${r.category}:${r.line ?? ""}`;
|
|
2610
|
-
const key = `${r.id}::${sourceKey}`;
|
|
2695
|
+
const key = `${r.id}::${r.title}::${sourceKey}`;
|
|
2611
2696
|
const group = groups.get(key);
|
|
2612
2697
|
if (group) {
|
|
2613
2698
|
group.push(r);
|