agent-security-scanner-mcp 3.17.1 → 3.18.0
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 +2 -2
- package/analyzer.py +3 -0
- package/package.json +1 -1
- package/rules/semantic-security.yaml +679 -0
- package/src/tools/scan-security.js +33 -4
- package/src/tools/scan-skill.js +14 -2
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Continue reading below for full version documentation →
|
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
|
-
> **New in v3.11.0:** ClawHub ecosystem security scanning — scanned all
|
|
65
|
+
> **New in v3.11.0:** ClawHub ecosystem security scanning — scanned all 16,532 ClawHub skills and found 46% have critical vulnerabilities. New `scan-clawhub` CLI for batch scanning, 40+ prompt injection patterns, jailbreak detection (DAN mode, dev mode), data exfiltration checks. [See ClawHub Security Dashboard](https://www.proof-layer.com/dashboard).
|
|
66
66
|
>
|
|
67
67
|
> **Also in v3.10.0:** ClawProof OpenClaw plugin — 6-layer deep skill scanner (`scan_skill`) with ClawHavoc malware signatures (27 rules, 121 patterns covering reverse shells, crypto miners, info stealers, C2 beacons, and OpenClaw-specific attacks), package supply chain verification, and rug pull detection.
|
|
68
68
|
>
|
|
@@ -150,7 +150,7 @@ clawproof scan ./SKILL.md
|
|
|
150
150
|
- **30.5%** are completely safe (Grade A)
|
|
151
151
|
- **4,129** prompt injection patterns detected
|
|
152
152
|
|
|
153
|
-
See [ClawHub Security
|
|
153
|
+
See [ClawHub Security Dashboard](https://www.proof-layer.com/dashboard) for interactive exploration of all 16,532 skills with searchable security grades and detailed findings.
|
|
154
154
|
|
|
155
155
|
**Detection Capabilities:**
|
|
156
156
|
- Prompt Injection (15 patterns): "ignore previous instructions", role manipulation
|
package/analyzer.py
CHANGED
|
@@ -45,6 +45,9 @@ try:
|
|
|
45
45
|
except ImportError:
|
|
46
46
|
HAS_TAINT_ANALYZER = False
|
|
47
47
|
|
|
48
|
+
# Semantic analyzer flag (JavaScript-based, optional)
|
|
49
|
+
HAS_SEMANTIC_ANALYZER = True # Implemented in src/semantic-analyzer.js
|
|
50
|
+
|
|
48
51
|
# Import the original regex-based rules (always available)
|
|
49
52
|
from rules import get_rules_for_language
|
|
50
53
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-security-scanner-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0",
|
|
4
4
|
"mcpName": "io.github.sinewaveai/agent-security-scanner-mcp",
|
|
5
5
|
"description": "Security scanner MCP server for AI coding agents. Prompt injection firewall, package hallucination detection (4.3M+ packages), 1000+ vulnerability rules with AST & taint analysis, auto-fix. For Claude Code, Cursor, Windsurf, Cline, OpenClaw.",
|
|
6
6
|
"main": "index.js",
|
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
# Semantic Security Rules
|
|
2
|
+
# Requires Code Property Graph (CPG) analysis via semantic-analyzer.js
|
|
3
|
+
# Detects logic-level vulnerabilities that AST+regex miss
|
|
4
|
+
|
|
5
|
+
- id: semantic.unreachable-code
|
|
6
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp, csharp, rust]
|
|
7
|
+
severity: WARNING
|
|
8
|
+
message: "Unreachable code detected - this code will never execute"
|
|
9
|
+
metadata:
|
|
10
|
+
category: dead-code
|
|
11
|
+
cwe: "CWE-561"
|
|
12
|
+
owasp: "A06:2021 - Vulnerable and Outdated Components"
|
|
13
|
+
confidence: high
|
|
14
|
+
impact: low
|
|
15
|
+
description: "Code that can never be executed wastes resources and may indicate logic errors"
|
|
16
|
+
remediation: "Remove unreachable code or fix the control flow"
|
|
17
|
+
|
|
18
|
+
- id: semantic.missing-auth-check
|
|
19
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
20
|
+
severity: ERROR
|
|
21
|
+
message: "Sensitive operation executed without authentication check"
|
|
22
|
+
metadata:
|
|
23
|
+
category: auth-bypass
|
|
24
|
+
cwe: "CWE-306"
|
|
25
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
26
|
+
confidence: medium
|
|
27
|
+
impact: critical
|
|
28
|
+
description: "Sensitive operations (database writes, file access, command execution) must be protected by authentication checks"
|
|
29
|
+
remediation: "Add authentication/authorization check before sensitive operation"
|
|
30
|
+
|
|
31
|
+
- id: semantic.missing-authz-check
|
|
32
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
33
|
+
severity: ERROR
|
|
34
|
+
message: "Data access without authorization check - potential IDOR vulnerability"
|
|
35
|
+
metadata:
|
|
36
|
+
category: auth-bypass
|
|
37
|
+
cwe: "CWE-639"
|
|
38
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
39
|
+
confidence: medium
|
|
40
|
+
impact: critical
|
|
41
|
+
description: "Direct object references (accessing resources by ID) without ownership verification enables IDOR attacks"
|
|
42
|
+
remediation: "Verify user owns/has access to the resource before returning it"
|
|
43
|
+
|
|
44
|
+
- id: semantic.race-condition
|
|
45
|
+
languages: [javascript, typescript, python, java, go, c, cpp, csharp, rust]
|
|
46
|
+
severity: WARNING
|
|
47
|
+
message: "Potential race condition - concurrent access without synchronization"
|
|
48
|
+
metadata:
|
|
49
|
+
category: concurrency
|
|
50
|
+
cwe: "CWE-362"
|
|
51
|
+
owasp: "A04:2021 - Insecure Design"
|
|
52
|
+
confidence: low
|
|
53
|
+
impact: medium
|
|
54
|
+
description: "Shared state accessed from multiple execution paths without proper locking can lead to race conditions"
|
|
55
|
+
remediation: "Use locks, mutexes, or atomic operations to protect shared state"
|
|
56
|
+
|
|
57
|
+
- id: semantic.toctou
|
|
58
|
+
languages: [javascript, typescript, python, java, go, c, cpp, ruby, php]
|
|
59
|
+
severity: ERROR
|
|
60
|
+
message: "TOCTOU vulnerability - file state may change between check and use"
|
|
61
|
+
metadata:
|
|
62
|
+
category: race-condition
|
|
63
|
+
cwe: "CWE-367"
|
|
64
|
+
owasp: "A04:2021 - Insecure Design"
|
|
65
|
+
confidence: medium
|
|
66
|
+
impact: high
|
|
67
|
+
description: "Time-of-check-time-of-use: file/resource state checked then used, allowing attacker to modify state between operations"
|
|
68
|
+
remediation: "Use atomic operations or file descriptors instead of check-then-use"
|
|
69
|
+
|
|
70
|
+
- id: semantic.logic-contradiction
|
|
71
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp, csharp, rust]
|
|
72
|
+
severity: WARNING
|
|
73
|
+
message: "Logic contradiction detected - condition conflicts with earlier condition"
|
|
74
|
+
metadata:
|
|
75
|
+
category: logic-error
|
|
76
|
+
cwe: "CWE-570"
|
|
77
|
+
owasp: "A04:2021 - Insecure Design"
|
|
78
|
+
confidence: high
|
|
79
|
+
impact: low
|
|
80
|
+
description: "Contradictory conditions indicate logic errors and create unreachable code paths"
|
|
81
|
+
remediation: "Review and fix the logic flow"
|
|
82
|
+
|
|
83
|
+
- id: semantic.use-after-free
|
|
84
|
+
languages: [c, cpp, rust]
|
|
85
|
+
severity: ERROR
|
|
86
|
+
message: "Use-after-free detected - variable used after being freed"
|
|
87
|
+
metadata:
|
|
88
|
+
category: memory-safety
|
|
89
|
+
cwe: "CWE-416"
|
|
90
|
+
owasp: "A06:2021 - Vulnerable and Outdated Components"
|
|
91
|
+
confidence: high
|
|
92
|
+
impact: critical
|
|
93
|
+
description: "Using memory after it has been freed can lead to crashes or arbitrary code execution"
|
|
94
|
+
remediation: "Set pointer to NULL after free, or use smart pointers (C++ unique_ptr/shared_ptr)"
|
|
95
|
+
|
|
96
|
+
- id: semantic.double-free
|
|
97
|
+
languages: [c, cpp]
|
|
98
|
+
severity: ERROR
|
|
99
|
+
message: "Double free detected - memory freed twice"
|
|
100
|
+
metadata:
|
|
101
|
+
category: memory-safety
|
|
102
|
+
cwe: "CWE-415"
|
|
103
|
+
owasp: "A06:2021 - Vulnerable and Outdated Components"
|
|
104
|
+
confidence: high
|
|
105
|
+
impact: critical
|
|
106
|
+
description: "Freeing the same memory twice can corrupt memory allocator state and enable exploits"
|
|
107
|
+
remediation: "Set pointer to NULL after free to prevent double-free"
|
|
108
|
+
|
|
109
|
+
- id: semantic.null-dereference
|
|
110
|
+
languages: [javascript, typescript, python, java, go, c, cpp, csharp, rust]
|
|
111
|
+
severity: WARNING
|
|
112
|
+
message: "Potential null pointer dereference"
|
|
113
|
+
metadata:
|
|
114
|
+
category: null-safety
|
|
115
|
+
cwe: "CWE-476"
|
|
116
|
+
owasp: "A06:2021 - Vulnerable and Outdated Components"
|
|
117
|
+
confidence: low
|
|
118
|
+
impact: medium
|
|
119
|
+
description: "Dereferencing a null pointer causes crashes or unpredictable behavior"
|
|
120
|
+
remediation: "Add null check before dereference"
|
|
121
|
+
|
|
122
|
+
- id: semantic.dead-store
|
|
123
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp, csharp, rust]
|
|
124
|
+
severity: INFO
|
|
125
|
+
message: "Dead store - assignment to variable never used"
|
|
126
|
+
metadata:
|
|
127
|
+
category: optimization
|
|
128
|
+
cwe: "CWE-563"
|
|
129
|
+
owasp: "A06:2021 - Vulnerable and Outdated Components"
|
|
130
|
+
confidence: high
|
|
131
|
+
impact: negligible
|
|
132
|
+
description: "Assignments that are never used waste resources and may indicate incomplete code"
|
|
133
|
+
remediation: "Remove the unused assignment or use the variable"
|
|
134
|
+
|
|
135
|
+
- id: semantic.infinite-loop
|
|
136
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp, csharp, rust]
|
|
137
|
+
severity: ERROR
|
|
138
|
+
message: "Infinite loop detected - loop has no exit condition"
|
|
139
|
+
metadata:
|
|
140
|
+
category: denial-of-service
|
|
141
|
+
cwe: "CWE-835"
|
|
142
|
+
owasp: "A04:2021 - Insecure Design"
|
|
143
|
+
confidence: medium
|
|
144
|
+
impact: high
|
|
145
|
+
description: "Loops without exit conditions cause hangs and resource exhaustion"
|
|
146
|
+
remediation: "Add break condition, timeout, or iteration limit"
|
|
147
|
+
|
|
148
|
+
- id: semantic.missing-null-check
|
|
149
|
+
languages: [javascript, typescript, python, java, go, c, cpp, csharp]
|
|
150
|
+
severity: WARNING
|
|
151
|
+
message: "Missing null check before dereference"
|
|
152
|
+
metadata:
|
|
153
|
+
category: null-safety
|
|
154
|
+
cwe: "CWE-476"
|
|
155
|
+
owasp: "A04:2021 - Insecure Design"
|
|
156
|
+
confidence: medium
|
|
157
|
+
impact: medium
|
|
158
|
+
description: "Variables that can be null must be checked before access"
|
|
159
|
+
remediation: "Add null/undefined check before using variable"
|
|
160
|
+
|
|
161
|
+
- id: semantic.missing-bounds-check
|
|
162
|
+
languages: [javascript, typescript, python, java, go, c, cpp, csharp, rust]
|
|
163
|
+
severity: ERROR
|
|
164
|
+
message: "Missing array bounds check - potential buffer overflow"
|
|
165
|
+
metadata:
|
|
166
|
+
category: buffer-overflow
|
|
167
|
+
cwe: "CWE-119"
|
|
168
|
+
owasp: "A03:2021 - Injection"
|
|
169
|
+
confidence: medium
|
|
170
|
+
impact: critical
|
|
171
|
+
description: "Array access without bounds checking can lead to buffer overflows"
|
|
172
|
+
remediation: "Validate array index is within bounds before access"
|
|
173
|
+
|
|
174
|
+
- id: semantic.unvalidated-redirect
|
|
175
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
176
|
+
severity: ERROR
|
|
177
|
+
message: "Unvalidated redirect - redirect destination not validated"
|
|
178
|
+
metadata:
|
|
179
|
+
category: redirect
|
|
180
|
+
cwe: "CWE-601"
|
|
181
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
182
|
+
confidence: high
|
|
183
|
+
impact: medium
|
|
184
|
+
description: "Redirecting to user-controlled URLs without validation enables phishing attacks"
|
|
185
|
+
remediation: "Whitelist allowed redirect destinations or validate URL"
|
|
186
|
+
|
|
187
|
+
- id: semantic.path-traversal
|
|
188
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp]
|
|
189
|
+
severity: ERROR
|
|
190
|
+
message: "Path traversal vulnerability - user input used in file path without validation"
|
|
191
|
+
metadata:
|
|
192
|
+
category: path-traversal
|
|
193
|
+
cwe: "CWE-22"
|
|
194
|
+
owasp: "A03:2021 - Injection"
|
|
195
|
+
confidence: high
|
|
196
|
+
impact: critical
|
|
197
|
+
description: "User-controlled file paths without validation allow reading arbitrary files"
|
|
198
|
+
remediation: "Use path.basename() or validate path is within allowed directory"
|
|
199
|
+
|
|
200
|
+
- id: semantic.ssrf
|
|
201
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
202
|
+
severity: ERROR
|
|
203
|
+
message: "SSRF vulnerability - user input used in HTTP request without validation"
|
|
204
|
+
metadata:
|
|
205
|
+
category: ssrf
|
|
206
|
+
cwe: "CWE-918"
|
|
207
|
+
owasp: "A10:2021 - Server-Side Request Forgery"
|
|
208
|
+
confidence: high
|
|
209
|
+
impact: critical
|
|
210
|
+
description: "User-controlled URLs in HTTP requests allow attackers to probe internal networks"
|
|
211
|
+
remediation: "Whitelist allowed domains/IPs or validate URL scheme and host"
|
|
212
|
+
|
|
213
|
+
- id: semantic.xxe
|
|
214
|
+
languages: [java, csharp, php, python]
|
|
215
|
+
severity: ERROR
|
|
216
|
+
message: "XXE vulnerability - XML parsing without disabling external entities"
|
|
217
|
+
metadata:
|
|
218
|
+
category: xxe
|
|
219
|
+
cwe: "CWE-611"
|
|
220
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
221
|
+
confidence: high
|
|
222
|
+
impact: critical
|
|
223
|
+
description: "XML External Entity attacks allow reading files and SSRF"
|
|
224
|
+
remediation: "Disable external entity processing in XML parser"
|
|
225
|
+
|
|
226
|
+
- id: semantic.ldap-injection
|
|
227
|
+
languages: [java, python, csharp, php]
|
|
228
|
+
severity: ERROR
|
|
229
|
+
message: "LDAP injection - user input in LDAP query without sanitization"
|
|
230
|
+
metadata:
|
|
231
|
+
category: injection
|
|
232
|
+
cwe: "CWE-90"
|
|
233
|
+
owasp: "A03:2021 - Injection"
|
|
234
|
+
confidence: high
|
|
235
|
+
impact: high
|
|
236
|
+
description: "User input in LDAP queries without sanitization allows LDAP injection"
|
|
237
|
+
remediation: "Use parameterized LDAP queries or escape special characters"
|
|
238
|
+
|
|
239
|
+
- id: semantic.xpath-injection
|
|
240
|
+
languages: [java, python, csharp, php, javascript]
|
|
241
|
+
severity: ERROR
|
|
242
|
+
message: "XPath injection - user input in XPath query without sanitization"
|
|
243
|
+
metadata:
|
|
244
|
+
category: injection
|
|
245
|
+
cwe: "CWE-643"
|
|
246
|
+
owasp: "A03:2021 - Injection"
|
|
247
|
+
confidence: high
|
|
248
|
+
impact: high
|
|
249
|
+
description: "User input in XPath queries without sanitization allows data extraction"
|
|
250
|
+
remediation: "Use parameterized XPath or escape special characters"
|
|
251
|
+
|
|
252
|
+
- id: semantic.os-command-injection
|
|
253
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp]
|
|
254
|
+
severity: ERROR
|
|
255
|
+
message: "Command injection - user input in shell command without sanitization"
|
|
256
|
+
metadata:
|
|
257
|
+
category: command-injection
|
|
258
|
+
cwe: "CWE-78"
|
|
259
|
+
owasp: "A03:2021 - Injection"
|
|
260
|
+
confidence: high
|
|
261
|
+
impact: critical
|
|
262
|
+
description: "User input in shell commands without sanitization allows arbitrary command execution"
|
|
263
|
+
remediation: "Use safe APIs (execFile not exec) or validate/escape input"
|
|
264
|
+
|
|
265
|
+
- id: semantic.insecure-deserialization
|
|
266
|
+
languages: [java, python, php, ruby, csharp]
|
|
267
|
+
severity: ERROR
|
|
268
|
+
message: "Insecure deserialization - deserializing untrusted data"
|
|
269
|
+
metadata:
|
|
270
|
+
category: deserialization
|
|
271
|
+
cwe: "CWE-502"
|
|
272
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
273
|
+
confidence: high
|
|
274
|
+
impact: critical
|
|
275
|
+
description: "Deserializing untrusted data can lead to remote code execution"
|
|
276
|
+
remediation: "Validate data before deserialization or use safe formats (JSON)"
|
|
277
|
+
|
|
278
|
+
- id: semantic.weak-random
|
|
279
|
+
languages: [javascript, typescript, python, java, go, c, cpp, csharp]
|
|
280
|
+
severity: WARNING
|
|
281
|
+
message: "Weak random number generator used for security-sensitive operation"
|
|
282
|
+
metadata:
|
|
283
|
+
category: crypto
|
|
284
|
+
cwe: "CWE-338"
|
|
285
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
286
|
+
confidence: high
|
|
287
|
+
impact: medium
|
|
288
|
+
description: "Non-cryptographic RNGs are predictable and unsuitable for security"
|
|
289
|
+
remediation: "Use cryptographic RNG (crypto.randomBytes, secrets module)"
|
|
290
|
+
|
|
291
|
+
- id: semantic.hardcoded-secret
|
|
292
|
+
languages: [javascript, typescript, python, java, go, php, ruby, c, cpp, csharp]
|
|
293
|
+
severity: ERROR
|
|
294
|
+
message: "Hardcoded secret detected in source code"
|
|
295
|
+
metadata:
|
|
296
|
+
category: secrets
|
|
297
|
+
cwe: "CWE-798"
|
|
298
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
299
|
+
confidence: high
|
|
300
|
+
impact: critical
|
|
301
|
+
description: "Secrets in source code are visible to anyone with repository access"
|
|
302
|
+
remediation: "Use environment variables or secret management services"
|
|
303
|
+
|
|
304
|
+
- id: semantic.weak-crypto-algorithm
|
|
305
|
+
languages: [javascript, typescript, python, java, go, c, cpp, csharp]
|
|
306
|
+
severity: ERROR
|
|
307
|
+
message: "Weak cryptographic algorithm used (MD5, SHA1, DES)"
|
|
308
|
+
metadata:
|
|
309
|
+
category: crypto
|
|
310
|
+
cwe: "CWE-327"
|
|
311
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
312
|
+
confidence: high
|
|
313
|
+
impact: high
|
|
314
|
+
description: "Weak algorithms are vulnerable to collision and brute-force attacks"
|
|
315
|
+
remediation: "Use SHA-256, SHA-3, or bcrypt/scrypt/argon2 for hashing"
|
|
316
|
+
|
|
317
|
+
- id: semantic.missing-csrf-protection
|
|
318
|
+
languages: [javascript, typescript, python, java, php, ruby, csharp]
|
|
319
|
+
severity: ERROR
|
|
320
|
+
message: "State-changing operation without CSRF protection"
|
|
321
|
+
metadata:
|
|
322
|
+
category: csrf
|
|
323
|
+
cwe: "CWE-352"
|
|
324
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
325
|
+
confidence: medium
|
|
326
|
+
impact: high
|
|
327
|
+
description: "POST/PUT/DELETE without CSRF tokens allow attackers to perform actions as victim"
|
|
328
|
+
remediation: "Add CSRF token validation or use SameSite cookies"
|
|
329
|
+
|
|
330
|
+
- id: semantic.missing-rate-limiting
|
|
331
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
332
|
+
severity: WARNING
|
|
333
|
+
message: "Sensitive endpoint without rate limiting"
|
|
334
|
+
metadata:
|
|
335
|
+
category: denial-of-service
|
|
336
|
+
cwe: "CWE-770"
|
|
337
|
+
owasp: "A04:2021 - Insecure Design"
|
|
338
|
+
confidence: low
|
|
339
|
+
impact: medium
|
|
340
|
+
description: "Endpoints without rate limiting are vulnerable to brute-force and DoS attacks"
|
|
341
|
+
remediation: "Add rate limiting middleware (express-rate-limit, flask-limiter)"
|
|
342
|
+
|
|
343
|
+
- id: semantic.missing-input-validation
|
|
344
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
345
|
+
severity: WARNING
|
|
346
|
+
message: "User input used without validation"
|
|
347
|
+
metadata:
|
|
348
|
+
category: input-validation
|
|
349
|
+
cwe: "CWE-20"
|
|
350
|
+
owasp: "A03:2021 - Injection"
|
|
351
|
+
confidence: low
|
|
352
|
+
impact: medium
|
|
353
|
+
description: "All user input must be validated before use"
|
|
354
|
+
remediation: "Add validation (joi, validator, zod) or sanitization"
|
|
355
|
+
|
|
356
|
+
- id: semantic.missing-output-encoding
|
|
357
|
+
languages: [javascript, typescript, python, java, php, ruby]
|
|
358
|
+
severity: ERROR
|
|
359
|
+
message: "User input rendered without encoding - XSS vulnerability"
|
|
360
|
+
metadata:
|
|
361
|
+
category: xss
|
|
362
|
+
cwe: "CWE-79"
|
|
363
|
+
owasp: "A03:2021 - Injection"
|
|
364
|
+
confidence: high
|
|
365
|
+
impact: high
|
|
366
|
+
description: "User-controlled data in HTML output without encoding enables XSS attacks"
|
|
367
|
+
remediation: "Use template engines with auto-escaping or escape manually"
|
|
368
|
+
|
|
369
|
+
- id: semantic.insecure-cookie
|
|
370
|
+
languages: [javascript, typescript, python, java, php, ruby, csharp]
|
|
371
|
+
severity: WARNING
|
|
372
|
+
message: "Cookie set without Secure/HttpOnly/SameSite flags"
|
|
373
|
+
metadata:
|
|
374
|
+
category: session
|
|
375
|
+
cwe: "CWE-614"
|
|
376
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
377
|
+
confidence: high
|
|
378
|
+
impact: medium
|
|
379
|
+
description: "Cookies without security flags are vulnerable to interception and CSRF"
|
|
380
|
+
remediation: "Set Secure, HttpOnly, and SameSite=Strict flags"
|
|
381
|
+
|
|
382
|
+
- id: semantic.sql-injection
|
|
383
|
+
languages: [javascript, typescript, python, java, php, ruby, go, csharp]
|
|
384
|
+
severity: ERROR
|
|
385
|
+
message: "SQL injection - user input in SQL query without parameterization"
|
|
386
|
+
metadata:
|
|
387
|
+
category: sql-injection
|
|
388
|
+
cwe: "CWE-89"
|
|
389
|
+
owasp: "A03:2021 - Injection"
|
|
390
|
+
confidence: high
|
|
391
|
+
impact: critical
|
|
392
|
+
description: "User input in SQL queries without parameterization allows data theft and manipulation"
|
|
393
|
+
remediation: "Use parameterized queries or ORM methods"
|
|
394
|
+
|
|
395
|
+
- id: semantic.nosql-injection
|
|
396
|
+
languages: [javascript, typescript, python, java, php, ruby]
|
|
397
|
+
severity: ERROR
|
|
398
|
+
message: "NoSQL injection - user input in database query without sanitization"
|
|
399
|
+
metadata:
|
|
400
|
+
category: nosql-injection
|
|
401
|
+
cwe: "CWE-943"
|
|
402
|
+
owasp: "A03:2021 - Injection"
|
|
403
|
+
confidence: high
|
|
404
|
+
impact: high
|
|
405
|
+
description: "User input in NoSQL queries without sanitization allows unauthorized data access"
|
|
406
|
+
remediation: "Validate/sanitize input or use safe query builders"
|
|
407
|
+
|
|
408
|
+
- id: semantic.prototype-pollution
|
|
409
|
+
languages: [javascript, typescript]
|
|
410
|
+
severity: ERROR
|
|
411
|
+
message: "Prototype pollution vulnerability - user input modifies object prototype"
|
|
412
|
+
metadata:
|
|
413
|
+
category: prototype-pollution
|
|
414
|
+
cwe: "CWE-1321"
|
|
415
|
+
owasp: "A03:2021 - Injection"
|
|
416
|
+
confidence: high
|
|
417
|
+
impact: high
|
|
418
|
+
description: "Modifying Object.prototype allows attackers to inject properties into all objects"
|
|
419
|
+
remediation: "Use Map instead of objects, or Object.create(null)"
|
|
420
|
+
|
|
421
|
+
- id: semantic.regex-dos
|
|
422
|
+
languages: [javascript, typescript, python, java, go, php, ruby]
|
|
423
|
+
severity: WARNING
|
|
424
|
+
message: "ReDoS vulnerability - regex with exponential backtracking"
|
|
425
|
+
metadata:
|
|
426
|
+
category: denial-of-service
|
|
427
|
+
cwe: "CWE-1333"
|
|
428
|
+
owasp: "A04:2021 - Insecure Design"
|
|
429
|
+
confidence: medium
|
|
430
|
+
impact: medium
|
|
431
|
+
description: "Complex regexes with nested quantifiers cause exponential processing time"
|
|
432
|
+
remediation: "Simplify regex or add timeout"
|
|
433
|
+
|
|
434
|
+
- id: semantic.xml-bomb
|
|
435
|
+
languages: [java, python, csharp, php]
|
|
436
|
+
severity: ERROR
|
|
437
|
+
message: "XML bomb vulnerability - entity expansion without limits"
|
|
438
|
+
metadata:
|
|
439
|
+
category: denial-of-service
|
|
440
|
+
cwe: "CWE-776"
|
|
441
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
442
|
+
confidence: high
|
|
443
|
+
impact: high
|
|
444
|
+
description: "Unlimited entity expansion can exhaust memory and CPU"
|
|
445
|
+
remediation: "Limit entity expansion or disable entity processing"
|
|
446
|
+
|
|
447
|
+
- id: semantic.open-redirect-via-referer
|
|
448
|
+
languages: [javascript, typescript, python, java, php, ruby]
|
|
449
|
+
severity: WARNING
|
|
450
|
+
message: "Open redirect via Referer header - untrusted header used for redirect"
|
|
451
|
+
metadata:
|
|
452
|
+
category: redirect
|
|
453
|
+
cwe: "CWE-601"
|
|
454
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
455
|
+
confidence: medium
|
|
456
|
+
impact: medium
|
|
457
|
+
description: "Referer header is user-controlled and should not be trusted for redirects"
|
|
458
|
+
remediation: "Whitelist allowed redirect URLs or use signed tokens"
|
|
459
|
+
|
|
460
|
+
- id: semantic.server-side-template-injection
|
|
461
|
+
languages: [python, java, php, ruby, javascript]
|
|
462
|
+
severity: ERROR
|
|
463
|
+
message: "Server-side template injection - user input in template without escaping"
|
|
464
|
+
metadata:
|
|
465
|
+
category: injection
|
|
466
|
+
cwe: "CWE-94"
|
|
467
|
+
owasp: "A03:2021 - Injection"
|
|
468
|
+
confidence: high
|
|
469
|
+
impact: critical
|
|
470
|
+
description: "User input in templates without escaping allows code execution"
|
|
471
|
+
remediation: "Use safe template rendering or escape user input"
|
|
472
|
+
|
|
473
|
+
- id: semantic.jwt-none-algorithm
|
|
474
|
+
languages: [javascript, typescript, python, java, php, ruby]
|
|
475
|
+
severity: ERROR
|
|
476
|
+
message: "JWT 'none' algorithm accepted - signature verification bypassed"
|
|
477
|
+
metadata:
|
|
478
|
+
category: crypto
|
|
479
|
+
cwe: "CWE-347"
|
|
480
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
481
|
+
confidence: high
|
|
482
|
+
impact: critical
|
|
483
|
+
description: "Accepting 'none' algorithm allows attackers to forge JWTs"
|
|
484
|
+
remediation: "Explicitly reject 'none' algorithm or use algorithm whitelist"
|
|
485
|
+
|
|
486
|
+
- id: semantic.missing-encryption-at-rest
|
|
487
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
488
|
+
severity: WARNING
|
|
489
|
+
message: "Sensitive data stored without encryption"
|
|
490
|
+
metadata:
|
|
491
|
+
category: crypto
|
|
492
|
+
cwe: "CWE-311"
|
|
493
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
494
|
+
confidence: low
|
|
495
|
+
impact: high
|
|
496
|
+
description: "Sensitive data (passwords, tokens, PII) must be encrypted at rest"
|
|
497
|
+
remediation: "Encrypt sensitive data before storage"
|
|
498
|
+
|
|
499
|
+
- id: semantic.missing-encryption-in-transit
|
|
500
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
501
|
+
severity: ERROR
|
|
502
|
+
message: "Sensitive data transmitted without encryption"
|
|
503
|
+
metadata:
|
|
504
|
+
category: crypto
|
|
505
|
+
cwe: "CWE-319"
|
|
506
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
507
|
+
confidence: medium
|
|
508
|
+
impact: critical
|
|
509
|
+
description: "Unencrypted transmission of sensitive data allows interception"
|
|
510
|
+
remediation: "Use HTTPS/TLS for all sensitive data transmission"
|
|
511
|
+
|
|
512
|
+
- id: semantic.insufficient-logging
|
|
513
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
514
|
+
severity: WARNING
|
|
515
|
+
message: "Security-sensitive operation without logging"
|
|
516
|
+
metadata:
|
|
517
|
+
category: logging
|
|
518
|
+
cwe: "CWE-778"
|
|
519
|
+
owasp: "A09:2021 - Security Logging and Monitoring Failures"
|
|
520
|
+
confidence: low
|
|
521
|
+
impact: low
|
|
522
|
+
description: "Failed auth, access violations, and privilege changes should be logged"
|
|
523
|
+
remediation: "Add security event logging"
|
|
524
|
+
|
|
525
|
+
- id: semantic.sensitive-data-in-logs
|
|
526
|
+
languages: [javascript, typescript, python, java, go, php, ruby, csharp]
|
|
527
|
+
severity: WARNING
|
|
528
|
+
message: "Sensitive data logged - potential information disclosure"
|
|
529
|
+
metadata:
|
|
530
|
+
category: logging
|
|
531
|
+
cwe: "CWE-532"
|
|
532
|
+
owasp: "A09:2021 - Security Logging and Monitoring Failures"
|
|
533
|
+
confidence: medium
|
|
534
|
+
impact: medium
|
|
535
|
+
description: "Passwords, tokens, and PII should not be logged"
|
|
536
|
+
remediation: "Redact or omit sensitive data from logs"
|
|
537
|
+
|
|
538
|
+
- id: semantic.insecure-random-filename
|
|
539
|
+
languages: [javascript, typescript, python, java, go, php, ruby]
|
|
540
|
+
severity: WARNING
|
|
541
|
+
message: "Predictable filename used for temporary/uploaded file"
|
|
542
|
+
metadata:
|
|
543
|
+
category: file-upload
|
|
544
|
+
cwe: "CWE-330"
|
|
545
|
+
owasp: "A04:2021 - Insecure Design"
|
|
546
|
+
confidence: medium
|
|
547
|
+
impact: medium
|
|
548
|
+
description: "Predictable filenames allow attackers to overwrite files or guess upload locations"
|
|
549
|
+
remediation: "Use cryptographic random for filenames (crypto.randomUUID, secrets.token_hex)"
|
|
550
|
+
|
|
551
|
+
- id: semantic.path-injection-via-zip
|
|
552
|
+
languages: [javascript, typescript, python, java, go, php, ruby]
|
|
553
|
+
severity: ERROR
|
|
554
|
+
message: "Zip slip vulnerability - archive extraction without path validation"
|
|
555
|
+
metadata:
|
|
556
|
+
category: path-traversal
|
|
557
|
+
cwe: "CWE-22"
|
|
558
|
+
owasp: "A03:2021 - Injection"
|
|
559
|
+
confidence: high
|
|
560
|
+
impact: critical
|
|
561
|
+
description: "Malicious archives with '../' in filenames can write outside extraction directory"
|
|
562
|
+
remediation: "Validate extracted paths are within target directory"
|
|
563
|
+
|
|
564
|
+
- id: semantic.mass-assignment
|
|
565
|
+
languages: [javascript, typescript, python, ruby, php, java]
|
|
566
|
+
severity: ERROR
|
|
567
|
+
message: "Mass assignment vulnerability - user input directly assigned to model"
|
|
568
|
+
metadata:
|
|
569
|
+
category: mass-assignment
|
|
570
|
+
cwe: "CWE-915"
|
|
571
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
572
|
+
confidence: high
|
|
573
|
+
impact: high
|
|
574
|
+
description: "Allowing users to set all model fields enables privilege escalation"
|
|
575
|
+
remediation: "Whitelist allowed fields or use explicit assignment"
|
|
576
|
+
|
|
577
|
+
- id: semantic.session-fixation
|
|
578
|
+
languages: [javascript, typescript, python, java, php, ruby]
|
|
579
|
+
severity: ERROR
|
|
580
|
+
message: "Session fixation vulnerability - session ID not regenerated after login"
|
|
581
|
+
metadata:
|
|
582
|
+
category: session
|
|
583
|
+
cwe: "CWE-384"
|
|
584
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
585
|
+
confidence: high
|
|
586
|
+
impact: high
|
|
587
|
+
description: "Reusing session IDs after authentication allows session hijacking"
|
|
588
|
+
remediation: "Regenerate session ID on login/privilege change"
|
|
589
|
+
|
|
590
|
+
- id: semantic.insufficient-password-hash-iterations
|
|
591
|
+
languages: [javascript, typescript, python, java, php, ruby]
|
|
592
|
+
severity: WARNING
|
|
593
|
+
message: "Insufficient bcrypt/scrypt work factor - vulnerable to brute force"
|
|
594
|
+
metadata:
|
|
595
|
+
category: crypto
|
|
596
|
+
cwe: "CWE-916"
|
|
597
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
598
|
+
confidence: high
|
|
599
|
+
impact: medium
|
|
600
|
+
description: "Low iteration counts make password hashes vulnerable to brute-force"
|
|
601
|
+
remediation: "Use bcrypt cost 12+, scrypt N=32768+, or argon2id"
|
|
602
|
+
|
|
603
|
+
- id: semantic.timing-attack
|
|
604
|
+
languages: [javascript, typescript, python, java, go, c, cpp]
|
|
605
|
+
severity: WARNING
|
|
606
|
+
message: "Timing attack vulnerability - non-constant-time comparison of secrets"
|
|
607
|
+
metadata:
|
|
608
|
+
category: crypto
|
|
609
|
+
cwe: "CWE-208"
|
|
610
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
611
|
+
confidence: medium
|
|
612
|
+
impact: medium
|
|
613
|
+
description: "Variable-time string comparison reveals information about secret values"
|
|
614
|
+
remediation: "Use constant-time comparison (crypto.timingSafeEqual, secrets.compare_digest)"
|
|
615
|
+
|
|
616
|
+
- id: semantic.integer-overflow
|
|
617
|
+
languages: [c, cpp, java, go, rust]
|
|
618
|
+
severity: ERROR
|
|
619
|
+
message: "Potential integer overflow in arithmetic operation"
|
|
620
|
+
metadata:
|
|
621
|
+
category: integer-overflow
|
|
622
|
+
cwe: "CWE-190"
|
|
623
|
+
owasp: "A04:2021 - Insecure Design"
|
|
624
|
+
confidence: low
|
|
625
|
+
impact: high
|
|
626
|
+
description: "Integer overflow can cause unexpected behavior or security vulnerabilities"
|
|
627
|
+
remediation: "Check for overflow before arithmetic or use safe math libraries"
|
|
628
|
+
|
|
629
|
+
- id: semantic.buffer-overflow
|
|
630
|
+
languages: [c, cpp]
|
|
631
|
+
severity: ERROR
|
|
632
|
+
message: "Potential buffer overflow - unsafe buffer operation"
|
|
633
|
+
metadata:
|
|
634
|
+
category: buffer-overflow
|
|
635
|
+
cwe: "CWE-120"
|
|
636
|
+
owasp: "A04:2021 - Insecure Design"
|
|
637
|
+
confidence: medium
|
|
638
|
+
impact: critical
|
|
639
|
+
description: "Buffer overflows allow arbitrary code execution"
|
|
640
|
+
remediation: "Use safe functions (strncpy not strcpy, snprintf not sprintf)"
|
|
641
|
+
|
|
642
|
+
- id: semantic.format-string
|
|
643
|
+
languages: [c, cpp]
|
|
644
|
+
severity: ERROR
|
|
645
|
+
message: "Format string vulnerability - user input in format string"
|
|
646
|
+
metadata:
|
|
647
|
+
category: format-string
|
|
648
|
+
cwe: "CWE-134"
|
|
649
|
+
owasp: "A03:2021 - Injection"
|
|
650
|
+
confidence: high
|
|
651
|
+
impact: critical
|
|
652
|
+
description: "User-controlled format strings allow arbitrary read/write"
|
|
653
|
+
remediation: "Use static format strings, never pass user input as format"
|
|
654
|
+
|
|
655
|
+
- id: semantic.unchecked-return-value
|
|
656
|
+
languages: [c, cpp, go, rust]
|
|
657
|
+
severity: WARNING
|
|
658
|
+
message: "Unchecked return value from security-sensitive function"
|
|
659
|
+
metadata:
|
|
660
|
+
category: error-handling
|
|
661
|
+
cwe: "CWE-252"
|
|
662
|
+
owasp: "A04:2021 - Insecure Design"
|
|
663
|
+
confidence: medium
|
|
664
|
+
impact: medium
|
|
665
|
+
description: "Ignoring error returns from security functions can lead to vulnerabilities"
|
|
666
|
+
remediation: "Check return values and handle errors appropriately"
|
|
667
|
+
|
|
668
|
+
- id: semantic.privilege-escalation
|
|
669
|
+
languages: [c, cpp, python, java, go]
|
|
670
|
+
severity: ERROR
|
|
671
|
+
message: "Privilege escalation vulnerability - elevated privileges not dropped"
|
|
672
|
+
metadata:
|
|
673
|
+
category: privilege-escalation
|
|
674
|
+
cwe: "CWE-250"
|
|
675
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
676
|
+
confidence: medium
|
|
677
|
+
impact: critical
|
|
678
|
+
description: "Running with elevated privileges without dropping them increases attack surface"
|
|
679
|
+
remediation: "Drop privileges after initialization (setuid, setgid)"
|
|
@@ -7,6 +7,7 @@ import { deduplicateFindings } from '../dedup.js';
|
|
|
7
7
|
import { applyContextFilter, detectFrameworks, applyFrameworkAdjustments } from '../context.js';
|
|
8
8
|
import { loadConfig, shouldExcludeFile, applyConfig } from '../config.js';
|
|
9
9
|
import { discoverProjectContext } from './project-context.js';
|
|
10
|
+
import { runSemanticAnalysis, isSemanticAnalysisAvailable } from '../semantic-integration.js';
|
|
10
11
|
|
|
11
12
|
const MAX_FILE_SIZE = 1024 * 1024; // 1MB - skip files larger than this to avoid timeouts
|
|
12
13
|
|
|
@@ -14,9 +15,10 @@ export const scanSecuritySchema = {
|
|
|
14
15
|
file_path: z.string().describe("Path to the file to scan"),
|
|
15
16
|
output_format: z.enum(['json', 'sarif']).optional().describe("Output format: 'json' (default) or 'sarif' for GitHub/GitLab integration"),
|
|
16
17
|
verbosity: z.enum(['minimal', 'compact', 'full']).optional().describe("Response detail level: 'minimal' (counts only), 'compact' (default, actionable info), 'full' (complete metadata)"),
|
|
17
|
-
engine: z.enum(['auto', 'ast', 'regex']).optional().describe("Analysis engine: 'auto' (default, AST with regex fallback), 'ast' (tree-sitter only), 'regex' (regex only)"),
|
|
18
|
+
engine: z.enum(['auto', 'ast', 'regex', 'semantic', 'all']).optional().describe("Analysis engine: 'auto' (default, AST+semantic with regex fallback), 'ast' (tree-sitter only), 'regex' (regex only), 'semantic' (semantic/CPG only), 'all' (all engines)"),
|
|
18
19
|
project_context: z.boolean().optional().describe("Include project context (framework, security middleware, dependencies)"),
|
|
19
|
-
include_context: z.boolean().optional().describe("Include surrounding code context for each issue")
|
|
20
|
+
include_context: z.boolean().optional().describe("Include surrounding code context for each issue"),
|
|
21
|
+
enable_semantic: z.boolean().optional().describe("Enable semantic/CPG analysis (default: true if available)")
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
// Verbosity formatters
|
|
@@ -64,7 +66,7 @@ function formatFull(file_path, language, issues) {
|
|
|
64
66
|
};
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
export async function scanSecurity({ file_path, output_format, verbosity, engine, project_context, include_context }) {
|
|
69
|
+
export async function scanSecurity({ file_path, output_format, verbosity, engine, project_context, include_context, enable_semantic }) {
|
|
68
70
|
if (!existsSync(file_path)) {
|
|
69
71
|
return {
|
|
70
72
|
content: [{ type: "text", text: JSON.stringify({ error: "File not found" }) }]
|
|
@@ -101,7 +103,34 @@ export async function scanSecurity({ file_path, output_format, verbosity, engine
|
|
|
101
103
|
};
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
|
|
106
|
+
// Determine which engines to run
|
|
107
|
+
const engineMode = engine || 'auto';
|
|
108
|
+
const shouldRunSemantic = (enable_semantic !== false) &&
|
|
109
|
+
(engineMode === 'auto' || engineMode === 'semantic' || engineMode === 'all') &&
|
|
110
|
+
isSemanticAnalysisAvailable();
|
|
111
|
+
|
|
112
|
+
// Run primary analysis (AST/regex)
|
|
113
|
+
let rawIssues = [];
|
|
114
|
+
if (engineMode !== 'semantic') {
|
|
115
|
+
rawIssues = await runAnalyzerAsync(file_path, engineMode === 'all' ? 'auto' : engineMode);
|
|
116
|
+
if (rawIssues.error) {
|
|
117
|
+
return {
|
|
118
|
+
content: [{ type: "text", text: JSON.stringify(rawIssues) }]
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Run semantic analysis if enabled
|
|
124
|
+
if (shouldRunSemantic) {
|
|
125
|
+
try {
|
|
126
|
+
const semanticFindings = await runSemanticAnalysis(file_path);
|
|
127
|
+
if (semanticFindings && semanticFindings.length > 0) {
|
|
128
|
+
rawIssues = rawIssues.concat(semanticFindings);
|
|
129
|
+
}
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('[SEMANTIC] Analysis failed, continuing without semantic findings:', error.message);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
105
134
|
|
|
106
135
|
if (rawIssues.error) {
|
|
107
136
|
return {
|
package/src/tools/scan-skill.js
CHANGED
|
@@ -900,9 +900,21 @@ export async function scanSkill({ skill_path, verbosity, baseline }) {
|
|
|
900
900
|
// Resolve to canonical path immediately (defeats symlink attacks)
|
|
901
901
|
realPath = realpathSync(resolve(inputPath));
|
|
902
902
|
} catch (err) {
|
|
903
|
+
// Check for different error types
|
|
904
|
+
let errorMessage;
|
|
905
|
+
if (err.code === 'ENOENT') {
|
|
906
|
+
errorMessage = "Path not found";
|
|
907
|
+
} else if (err.code === 'ELOOP') {
|
|
908
|
+
errorMessage = "Symlink loop detected";
|
|
909
|
+
} else if (err.code === 'EACCES') {
|
|
910
|
+
errorMessage = "Permission denied";
|
|
911
|
+
} else {
|
|
912
|
+
errorMessage = "Invalid path";
|
|
913
|
+
}
|
|
914
|
+
|
|
903
915
|
return {
|
|
904
916
|
content: [{ type: "text", text: JSON.stringify({
|
|
905
|
-
error:
|
|
917
|
+
error: errorMessage,
|
|
906
918
|
skill_path: inputPath,
|
|
907
919
|
details: err.message
|
|
908
920
|
}) }]
|
|
@@ -1007,7 +1019,7 @@ export async function scanSkill({ skill_path, verbosity, baseline }) {
|
|
|
1007
1019
|
const [promptFindings, codeBlockFindings, supportingFindings, supplyChainFindings] =
|
|
1008
1020
|
await Promise.all([
|
|
1009
1021
|
timed('prompt_scan', () => runPromptScan(content)), // L1
|
|
1010
|
-
timed('code_blocks', () => runCodeBlockScan(codeBlocks, signal)),
|
|
1022
|
+
timed('code_blocks', () => runCodeBlockScan(codeBlocks, signal)), // L2
|
|
1011
1023
|
timed('supporting_files', () => runSupportingFilesScan(skillDir, skillFile, collectedFiles, signal)), // L3
|
|
1012
1024
|
timed('supply_chain', () => runSupplyChainScan(codeBlocks, skillDir, skillFile, collectedFiles, signal)), // L5
|
|
1013
1025
|
]);
|