@hungpg/skill-audit 0.1.0 → 0.1.1
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 +13 -12
- package/dist/intel.js +87 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,37 +13,38 @@ Security auditing CLI for AI agent skills.
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
17
|
-
npm install
|
|
18
|
-
npm run build
|
|
16
|
+
npm install -g @hungpg/skill-audit
|
|
19
17
|
```
|
|
20
18
|
|
|
21
19
|
## Usage
|
|
22
20
|
|
|
23
21
|
```bash
|
|
24
22
|
# Audit global skills
|
|
25
|
-
|
|
23
|
+
skill-audit -g
|
|
26
24
|
|
|
27
25
|
# Audit with verbose output
|
|
28
|
-
|
|
26
|
+
skill-audit -v
|
|
29
27
|
|
|
30
28
|
# JSON output for CI
|
|
31
|
-
|
|
29
|
+
skill-audit --json > audit-results.json
|
|
32
30
|
|
|
33
31
|
# Fail if risk score exceeds threshold
|
|
34
|
-
|
|
32
|
+
skill-audit --threshold 5.0
|
|
35
33
|
|
|
36
34
|
# Skip dependency scanning (faster)
|
|
37
|
-
|
|
35
|
+
skill-audit --no-deps
|
|
38
36
|
|
|
39
37
|
# Filter by agent
|
|
40
|
-
|
|
38
|
+
skill-audit -a "Claude Code" "Qwen Code"
|
|
41
39
|
|
|
42
40
|
# Project-level skills only
|
|
43
|
-
|
|
41
|
+
skill-audit --project
|
|
44
42
|
|
|
45
43
|
# Lint mode (spec validation only)
|
|
46
|
-
|
|
44
|
+
skill-audit --mode lint
|
|
45
|
+
|
|
46
|
+
# Update vulnerability DB manually
|
|
47
|
+
skill-audit --update-db
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
## Options
|
|
@@ -115,7 +116,7 @@ Feeds are cached locally with automatic freshness checks:
|
|
|
115
116
|
|
|
116
117
|
**False positives**: Review finding at file:line, add inline comment explaining legitimate use
|
|
117
118
|
|
|
118
|
-
**Stale DB warning**: Run `
|
|
119
|
+
**Stale DB warning**: Run `skill-audit --update-db` to refresh KEV/EPSS/OSV feeds
|
|
119
120
|
|
|
120
121
|
**Skill not found**: Verify `SKILL.md` exists in root or `skills/` directory
|
|
121
122
|
|
package/dist/intel.js
CHANGED
|
@@ -228,28 +228,98 @@ export async function queryOSV(ecosystem, packageName) {
|
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
/**
|
|
231
|
-
* Query GHSA via GitHub API
|
|
231
|
+
* Query GHSA via GitHub GraphQL API
|
|
232
|
+
*
|
|
233
|
+
* Note: GHSA integration requires GitHub API authentication.
|
|
234
|
+
* For now, OSV provides comprehensive coverage for most ecosystems.
|
|
235
|
+
*
|
|
236
|
+
* To implement GHSA:
|
|
237
|
+
* 1. Get GitHub token: https://github.com/settings/tokens
|
|
238
|
+
* 2. Set GITHUB_TOKEN environment variable
|
|
239
|
+
* 3. Use GraphQL API with SecurityAdvisory query
|
|
240
|
+
*
|
|
241
|
+
* Example:
|
|
242
|
+
* ```
|
|
243
|
+
* const token = process.env.GITHUB_TOKEN;
|
|
244
|
+
* const response = await fetch('https://api.github.com/graphql', {
|
|
245
|
+
* method: 'POST',
|
|
246
|
+
* headers: {
|
|
247
|
+
* 'Authorization': `Bearer ${token}`,
|
|
248
|
+
* 'Content-Type': 'application/json'
|
|
249
|
+
* },
|
|
250
|
+
* body: JSON.stringify({
|
|
251
|
+
* query: `query {
|
|
252
|
+
* securityVulnerabilities(first: 100, ecosystem: NPM, package: "packageName") {
|
|
253
|
+
* nodes {
|
|
254
|
+
* advisory { ghsaId, summary, severity }
|
|
255
|
+
* }
|
|
256
|
+
* }
|
|
257
|
+
* }`
|
|
258
|
+
* })
|
|
259
|
+
* });
|
|
260
|
+
* ```
|
|
232
261
|
*/
|
|
233
262
|
export async function queryGHSA(ecosystem, packageName) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
'npm': 'npm',
|
|
239
|
-
'pypi': 'PyPI',
|
|
240
|
-
'go': 'Go',
|
|
241
|
-
'cargo': 'Cargo',
|
|
242
|
-
'rubygems': 'RubyGems',
|
|
243
|
-
'maven': 'Maven',
|
|
244
|
-
'nuget': 'NuGet'
|
|
245
|
-
};
|
|
246
|
-
const ghsaQuery = encodeURIComponent(`${packageName} repo:github/advisory-database`);
|
|
247
|
-
// Note: This is a simplified approach - production would use GraphQL API
|
|
248
|
-
console.log(`GHSA query: ${ecosystem}/${packageName} (API token recommended for production)`);
|
|
263
|
+
const token = process.env.GITHUB_TOKEN;
|
|
264
|
+
if (!token) {
|
|
265
|
+
// GHSA requires authentication - skip silently
|
|
266
|
+
// OSV provides comprehensive coverage as fallback
|
|
249
267
|
return [];
|
|
250
268
|
}
|
|
269
|
+
try {
|
|
270
|
+
const response = await fetchWithRetry('https://api.github.com/graphql', FETCH_TIMEOUT_MS, {
|
|
271
|
+
method: 'POST',
|
|
272
|
+
headers: {
|
|
273
|
+
'Authorization': `Bearer ${token}`,
|
|
274
|
+
'Content-Type': 'application/json',
|
|
275
|
+
'User-Agent': 'skill-audit/0.1.0 (Vulnerability Intelligence Scanner)'
|
|
276
|
+
},
|
|
277
|
+
body: JSON.stringify({
|
|
278
|
+
query: `
|
|
279
|
+
query GetAdvisories($ecosystem: SecurityAdvisoryEcosystem!, $package: String!) {
|
|
280
|
+
securityVulnerabilities(first: 100, ecosystem: $ecosystem, package: $package) {
|
|
281
|
+
nodes {
|
|
282
|
+
advisory {
|
|
283
|
+
ghsaId
|
|
284
|
+
summary
|
|
285
|
+
severity
|
|
286
|
+
publishedAt
|
|
287
|
+
identifiers { type, value }
|
|
288
|
+
}
|
|
289
|
+
severity
|
|
290
|
+
vulnerableVersionRange
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
`,
|
|
295
|
+
variables: {
|
|
296
|
+
ecosystem: ecosystem.toUpperCase(),
|
|
297
|
+
package: packageName
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
});
|
|
301
|
+
if (!response.ok) {
|
|
302
|
+
console.error(`GHSA API error: ${response.status}`);
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
const data = await response.json();
|
|
306
|
+
if (!data.data?.securityVulnerabilities?.nodes) {
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
return data.data.securityVulnerabilities.nodes.map(node => ({
|
|
310
|
+
id: node.advisory?.ghsaId || `GHSA-unknown`,
|
|
311
|
+
aliases: node.advisory?.identifiers?.map(i => i.value) || [],
|
|
312
|
+
source: "GHSA",
|
|
313
|
+
ecosystem,
|
|
314
|
+
packageName,
|
|
315
|
+
severity: node.advisory?.severity || node.severity,
|
|
316
|
+
published: node.advisory?.publishedAt,
|
|
317
|
+
summary: node.advisory?.summary,
|
|
318
|
+
references: []
|
|
319
|
+
}));
|
|
320
|
+
}
|
|
251
321
|
catch (error) {
|
|
252
|
-
console.error(`GHSA query failed:`, error);
|
|
322
|
+
console.error(`GHSA query failed for ${ecosystem}/${packageName}:`, error);
|
|
253
323
|
return [];
|
|
254
324
|
}
|
|
255
325
|
}
|