secret-blast-radius 0.1.0 → 0.2.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 +105 -76
- package/action.yml +41 -0
- package/bin/cli.js +24 -5
- package/package.json +41 -9
- package/src/format.js +12 -1
- package/src/incidents.js +92 -0
- package/src/index.js +45 -3
- package/src/iocs.json +251 -0
- package/src/sarif.js +37 -0
- package/src/scanners.js +17 -2
- package/src/supply.js +409 -0
- package/src/util.js +4 -0
package/src/iocs.json
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
{
|
|
2
|
+
"updated": "2026-10-22",
|
|
3
|
+
"packages": [
|
|
4
|
+
{
|
|
5
|
+
"ecosystem": "npm",
|
|
6
|
+
"name": "tensorlake",
|
|
7
|
+
"versions": [
|
|
8
|
+
"0.5.144"
|
|
9
|
+
],
|
|
10
|
+
"campaign": "mini-shai-hulud",
|
|
11
|
+
"incident": "tensorlake",
|
|
12
|
+
"safe": "0.5.143 or 0.5.145+",
|
|
13
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"ecosystem": "npm",
|
|
17
|
+
"name": "tensorlake-native-darwin-arm64",
|
|
18
|
+
"versions": [
|
|
19
|
+
"0.5.144"
|
|
20
|
+
],
|
|
21
|
+
"campaign": "mini-shai-hulud",
|
|
22
|
+
"incident": "tensorlake",
|
|
23
|
+
"safe": "0.5.143",
|
|
24
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"ecosystem": "npm",
|
|
28
|
+
"name": "tensorlake-native-linux-arm64-gnu",
|
|
29
|
+
"versions": [
|
|
30
|
+
"0.5.144"
|
|
31
|
+
],
|
|
32
|
+
"campaign": "mini-shai-hulud",
|
|
33
|
+
"incident": "tensorlake",
|
|
34
|
+
"safe": "0.5.143",
|
|
35
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"ecosystem": "npm",
|
|
39
|
+
"name": "tensorlake-native-linux-arm64-musl",
|
|
40
|
+
"versions": [
|
|
41
|
+
"0.5.144"
|
|
42
|
+
],
|
|
43
|
+
"campaign": "mini-shai-hulud",
|
|
44
|
+
"incident": "tensorlake",
|
|
45
|
+
"safe": "0.5.143",
|
|
46
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"ecosystem": "npm",
|
|
50
|
+
"name": "tensorlake-native-linux-x64-gnu",
|
|
51
|
+
"versions": [
|
|
52
|
+
"0.5.144"
|
|
53
|
+
],
|
|
54
|
+
"campaign": "mini-shai-hulud",
|
|
55
|
+
"incident": "tensorlake",
|
|
56
|
+
"safe": "0.5.143",
|
|
57
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"ecosystem": "npm",
|
|
61
|
+
"name": "tensorlake-native-linux-x64-musl",
|
|
62
|
+
"versions": [
|
|
63
|
+
"0.5.144"
|
|
64
|
+
],
|
|
65
|
+
"campaign": "mini-shai-hulud",
|
|
66
|
+
"incident": "tensorlake",
|
|
67
|
+
"safe": "0.5.143",
|
|
68
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"ecosystem": "npm",
|
|
72
|
+
"name": "tensorlake-native-win32-x64",
|
|
73
|
+
"versions": [
|
|
74
|
+
"0.5.144"
|
|
75
|
+
],
|
|
76
|
+
"campaign": "mini-shai-hulud",
|
|
77
|
+
"incident": "tensorlake",
|
|
78
|
+
"safe": "0.5.143",
|
|
79
|
+
"ref": "https://github.com/tensorlakeai/tensorlake/security/advisories/GHSA-8g63-53c9-65j2"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"ecosystem": "npm",
|
|
83
|
+
"name": "@subql/common",
|
|
84
|
+
"versions": [
|
|
85
|
+
"5.8.3"
|
|
86
|
+
],
|
|
87
|
+
"campaign": "subql",
|
|
88
|
+
"incident": "subql",
|
|
89
|
+
"safe": "5.8.2",
|
|
90
|
+
"ref": "https://osv.dev/vulnerability/MAL-2026-17571"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"ecosystem": "npm",
|
|
94
|
+
"name": "@7nohe/openapi-react-query-codegen",
|
|
95
|
+
"versions": [
|
|
96
|
+
"0.0.0-365d4eb738d3146583431948d3ba6e27a32556be",
|
|
97
|
+
"0.0.0-ec7876d6c917dad516ba69bbfafc948b834bf0ab",
|
|
98
|
+
"0.5.4",
|
|
99
|
+
"0.5.5",
|
|
100
|
+
"1.6.3",
|
|
101
|
+
"1.6.4",
|
|
102
|
+
"2.2.1",
|
|
103
|
+
"2.2.2",
|
|
104
|
+
"3.0.3",
|
|
105
|
+
"3.0.4"
|
|
106
|
+
],
|
|
107
|
+
"campaign": "mini-shai-hulud",
|
|
108
|
+
"incident": "shai-hulud",
|
|
109
|
+
"safe": "0.5.3 / 1.6.2 / 2.2.0 / 3.0.2",
|
|
110
|
+
"ref": "https://socket.dev/blog/openapi-react-query-codegen-npm-compromise"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"ecosystem": "npm",
|
|
114
|
+
"name": "keyv",
|
|
115
|
+
"versions": [
|
|
116
|
+
"6.0.0"
|
|
117
|
+
],
|
|
118
|
+
"campaign": "mini-shai-hulud",
|
|
119
|
+
"incident": "shai-hulud",
|
|
120
|
+
"safe": "5.6.0",
|
|
121
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"ecosystem": "npm",
|
|
125
|
+
"name": "cacheable",
|
|
126
|
+
"versions": [
|
|
127
|
+
"2.5.1"
|
|
128
|
+
],
|
|
129
|
+
"campaign": "mini-shai-hulud",
|
|
130
|
+
"incident": "shai-hulud",
|
|
131
|
+
"safe": "2.5.0",
|
|
132
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"ecosystem": "npm",
|
|
136
|
+
"name": "cacheable-request",
|
|
137
|
+
"versions": [
|
|
138
|
+
"13.0.20"
|
|
139
|
+
],
|
|
140
|
+
"campaign": "mini-shai-hulud",
|
|
141
|
+
"incident": "shai-hulud",
|
|
142
|
+
"safe": "13.0.19",
|
|
143
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"ecosystem": "npm",
|
|
147
|
+
"name": "cache-manager",
|
|
148
|
+
"versions": [
|
|
149
|
+
"7.2.10"
|
|
150
|
+
],
|
|
151
|
+
"campaign": "mini-shai-hulud",
|
|
152
|
+
"incident": "shai-hulud",
|
|
153
|
+
"safe": "7.2.9",
|
|
154
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"ecosystem": "npm",
|
|
158
|
+
"name": "flat-cache",
|
|
159
|
+
"versions": [
|
|
160
|
+
"6.1.24"
|
|
161
|
+
],
|
|
162
|
+
"campaign": "mini-shai-hulud",
|
|
163
|
+
"incident": "shai-hulud",
|
|
164
|
+
"safe": "6.1.23",
|
|
165
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"ecosystem": "npm",
|
|
169
|
+
"name": "file-entry-cache",
|
|
170
|
+
"versions": [
|
|
171
|
+
"11.1.6"
|
|
172
|
+
],
|
|
173
|
+
"campaign": "mini-shai-hulud",
|
|
174
|
+
"incident": "shai-hulud",
|
|
175
|
+
"safe": "11.1.5",
|
|
176
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"ecosystem": "npm",
|
|
180
|
+
"name": "@cacheable/utils",
|
|
181
|
+
"versions": [
|
|
182
|
+
"2.5.1"
|
|
183
|
+
],
|
|
184
|
+
"campaign": "mini-shai-hulud",
|
|
185
|
+
"incident": "shai-hulud",
|
|
186
|
+
"safe": "the release before the listed version (see advisory)",
|
|
187
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"ecosystem": "npm",
|
|
191
|
+
"name": "@cacheable/memory",
|
|
192
|
+
"versions": [
|
|
193
|
+
"2.2.1"
|
|
194
|
+
],
|
|
195
|
+
"campaign": "mini-shai-hulud",
|
|
196
|
+
"incident": "shai-hulud",
|
|
197
|
+
"safe": "the release before the listed version (see advisory)",
|
|
198
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"ecosystem": "npm",
|
|
202
|
+
"name": "@cacheable/node-cache",
|
|
203
|
+
"versions": [
|
|
204
|
+
"3.1.2"
|
|
205
|
+
],
|
|
206
|
+
"campaign": "mini-shai-hulud",
|
|
207
|
+
"incident": "shai-hulud",
|
|
208
|
+
"safe": "the release before the listed version (see advisory)",
|
|
209
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"ecosystem": "npm",
|
|
213
|
+
"name": "@cacheable/net",
|
|
214
|
+
"versions": [
|
|
215
|
+
"2.1.1"
|
|
216
|
+
],
|
|
217
|
+
"campaign": "mini-shai-hulud",
|
|
218
|
+
"incident": "shai-hulud",
|
|
219
|
+
"safe": "the release before the listed version (see advisory)",
|
|
220
|
+
"ref": "https://www.sonatype.com/blog/mini-shai-hulud-npm-attack-more-than-2200-components-impacted"
|
|
221
|
+
}
|
|
222
|
+
],
|
|
223
|
+
"markers": {
|
|
224
|
+
"ips": [
|
|
225
|
+
"193.32.204.199"
|
|
226
|
+
],
|
|
227
|
+
"domains": [
|
|
228
|
+
"iseekaigogo.com",
|
|
229
|
+
"ci-artifacts.dev",
|
|
230
|
+
"npm-cache.com",
|
|
231
|
+
"my-github.com"
|
|
232
|
+
],
|
|
233
|
+
"files": [
|
|
234
|
+
"/tmp/tmp.ts018051808.lock"
|
|
235
|
+
],
|
|
236
|
+
"cron": [
|
|
237
|
+
"#ghc2",
|
|
238
|
+
"193.32.204.199"
|
|
239
|
+
],
|
|
240
|
+
"processes": [
|
|
241
|
+
"manifest-cache.js --warm",
|
|
242
|
+
"gh-token-monitor"
|
|
243
|
+
],
|
|
244
|
+
"branches": [
|
|
245
|
+
"dependabot/github_actions/format/setup-formatter"
|
|
246
|
+
],
|
|
247
|
+
"optionalDependencies": [
|
|
248
|
+
"@opensearch/setup"
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
}
|
package/src/sarif.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const LEVEL = { critical: 'error', high: 'error', medium: 'warning', low: 'note' };
|
|
2
|
+
const SCORE = { critical: '9.5', high: '7.5', medium: '5.0', low: '2.0' };
|
|
3
|
+
|
|
4
|
+
import { relative, isAbsolute } from 'node:path';
|
|
5
|
+
|
|
6
|
+
function repoRelative(result, loc) {
|
|
7
|
+
const abs = loc.startsWith('~') ? result.home + loc.slice(1) : loc;
|
|
8
|
+
if (!isAbsolute(abs)) return null;
|
|
9
|
+
for (const p of result.projects) {
|
|
10
|
+
const r = relative(p, abs);
|
|
11
|
+
if (r && !r.startsWith('..') && !isAbsolute(r)) return r.replace(/\\/g, '/');
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function toSarif(result, version) {
|
|
17
|
+
const rules = new Map();
|
|
18
|
+
for (const f of result.findings) if (!rules.has(f.id)) rules.set(f.id, f);
|
|
19
|
+
return {
|
|
20
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0.json',
|
|
21
|
+
version: '2.1.0',
|
|
22
|
+
runs: [{
|
|
23
|
+
tool: { driver: { name: 'secret-blast-radius', version, informationUri: 'https://github.com/Krrishkumar125/secret-blast-radius',
|
|
24
|
+
rules: [...rules.values()].map((f) => ({ id: f.id, name: f.id.replace(/[^a-z0-9]+/gi, '_'), shortDescription: { text: f.id }, properties: { 'security-severity': SCORE[f.severity], tags: ['security', f.category] } })) } },
|
|
25
|
+
results: result.findings.map((f) => {
|
|
26
|
+
// Only repo-relative paths are meaningful to code scanning; home-dir findings are reported without a file.
|
|
27
|
+
const uri = repoRelative(result, f.location);
|
|
28
|
+
return {
|
|
29
|
+
ruleId: f.id, level: LEVEL[f.severity],
|
|
30
|
+
message: { text: `${f.title}. ${f.detail}` },
|
|
31
|
+
...(uri ? { locations: [{ physicalLocation: { artifactLocation: { uri, uriBaseId: '%SRCROOT%' } } }] } : {}),
|
|
32
|
+
partialFingerprints: { primary: `${f.id}:${f.location}:${f.fingerprint || f.title}` },
|
|
33
|
+
};
|
|
34
|
+
}),
|
|
35
|
+
}],
|
|
36
|
+
};
|
|
37
|
+
}
|
package/src/scanners.js
CHANGED
|
@@ -61,6 +61,17 @@ export function scanNpmrc(ctx) {
|
|
|
61
61
|
return out;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
export function scanPypirc(ctx) {
|
|
65
|
+
const f = join(ctx.home, '.pypirc');
|
|
66
|
+
const t = readText(f);
|
|
67
|
+
if (!t) return [];
|
|
68
|
+
return [...t.matchAll(/^\s*password\s*[=:]\s*(\S+)/gm)].filter((m) => !isReference(m[1])).map((m) => ({
|
|
69
|
+
id: 'pypi.plaintext-token', category: 'npm', severity: m[1].startsWith('pypi-') ? 'critical' : 'high',
|
|
70
|
+
title: 'Plaintext PyPI credential in ~/.pypirc', location: tilde(ctx, f), fingerprint: fingerprint(m[1]),
|
|
71
|
+
detail: 'Lets a stealer publish to your PyPI projects. Revoke at pypi.org/manage/account/token and use trusted publishing.',
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
/* ---------------- 2. GitHub ---------------- */
|
|
65
76
|
export function scanGitHub(ctx) {
|
|
66
77
|
const out = [];
|
|
@@ -287,6 +298,10 @@ export function scanAiConfigs(ctx) {
|
|
|
287
298
|
}
|
|
288
299
|
}
|
|
289
300
|
}
|
|
301
|
+
for (const [rel, label] of [['.claude/.credentials.json', 'Claude Code login'], ['.gemini/oauth_creds.json', 'Gemini CLI OAuth tokens']]) {
|
|
302
|
+
const f = join(ctx.home, ...rel.split('/'));
|
|
303
|
+
if (readText(f)) out.push({ id: 'ai.cli-login', category: 'ai', severity: 'medium', title: `${label} stored in a file`, location: tilde(ctx, f), detail: 'Read verbatim by the GhostAction fake-font stealer. Sign out and back in to rotate if this machine is exposed.' });
|
|
304
|
+
}
|
|
290
305
|
// Codex CLI auth file stores an API key / refresh token.
|
|
291
306
|
for (const f of [join(ctx.home, '.codex', 'auth.json')]) {
|
|
292
307
|
const t = readText(f);
|
|
@@ -362,7 +377,7 @@ export function scanDotenv(ctx) {
|
|
|
362
377
|
for (const root of ctx.projects) {
|
|
363
378
|
for (const f of walk(root, { maxDepth: ctx.depth, skip: SKIP_DIRS })) {
|
|
364
379
|
const base = f.split(/[\\/]/).pop();
|
|
365
|
-
if (!/^\.env(\..+)?$/.test(base) || /\.(example|sample|template|dist|defaults)$/i.test(base)) continue;
|
|
380
|
+
if (!/^\.env(\..+)?$/.test(base) || /\.(example|sample|template|dist|defaults|demo)$/i.test(base)) continue;
|
|
366
381
|
const text = readText(f);
|
|
367
382
|
if (!text) continue;
|
|
368
383
|
const secrets = parseDotenv(text).filter(([k, v]) => isSecretPair(k, v));
|
|
@@ -406,7 +421,7 @@ export function scanHardening(ctx) {
|
|
|
406
421
|
|
|
407
422
|
export const SCANNERS = {
|
|
408
423
|
persistence: scanPersistence,
|
|
409
|
-
npm: scanNpmrc,
|
|
424
|
+
npm: (ctx) => [...scanNpmrc(ctx), ...scanPypirc(ctx)],
|
|
410
425
|
github: scanGitHub,
|
|
411
426
|
cloud: scanCloud,
|
|
412
427
|
kubernetes: scanKubeDocker,
|