supply-chain-guard 5.20.2 → 5.22.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 +1 -1
- package/dist/cli.js +1 -1
- package/dist/config-scanner.d.ts.map +1 -1
- package/dist/config-scanner.js +2 -0
- package/dist/config-scanner.js.map +1 -1
- package/dist/dependency-risk-analyzer.d.ts +16 -0
- package/dist/dependency-risk-analyzer.d.ts.map +1 -1
- package/dist/dependency-risk-analyzer.js +248 -46
- package/dist/dependency-risk-analyzer.js.map +1 -1
- package/dist/dockerfile-scanner.d.ts.map +1 -1
- package/dist/dockerfile-scanner.js +2 -0
- package/dist/dockerfile-scanner.js.map +1 -1
- package/dist/entropy.d.ts +14 -4
- package/dist/entropy.d.ts.map +1 -1
- package/dist/entropy.js +50 -18
- package/dist/entropy.js.map +1 -1
- package/dist/install-guard.d.ts +10 -1
- package/dist/install-guard.d.ts.map +1 -1
- package/dist/install-guard.js +83 -13
- package/dist/install-guard.js.map +1 -1
- package/dist/ioc-blocklist.d.ts.map +1 -1
- package/dist/ioc-blocklist.js +41 -0
- package/dist/ioc-blocklist.js.map +1 -1
- package/dist/npm-scanner.d.ts.map +1 -1
- package/dist/npm-scanner.js +34 -0
- package/dist/npm-scanner.js.map +1 -1
- package/dist/patterns.d.ts +15 -0
- package/dist/patterns.d.ts.map +1 -1
- package/dist/patterns.js +136 -12
- package/dist/patterns.js.map +1 -1
- package/dist/policy-engine.d.ts.map +1 -1
- package/dist/policy-engine.js +11 -0
- package/dist/policy-engine.js.map +1 -1
- package/dist/pypi-scanner.d.ts.map +1 -1
- package/dist/pypi-scanner.js +6 -0
- package/dist/pypi-scanner.js.map +1 -1
- package/dist/reporter.js +5 -5
- package/dist/scanner.js +32 -12
- package/dist/scanner.js.map +1 -1
- package/dist/threat-intel.d.ts.map +1 -1
- package/dist/threat-intel.js +305 -0
- package/dist/threat-intel.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vscode-scanner.js +2 -0
- package/dist/vscode-scanner.js.map +1 -1
- package/package.json +1 -1
- package/policy-schema.json +1 -1
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -22,7 +22,7 @@ const program = new commander_1.Command();
|
|
|
22
22
|
program
|
|
23
23
|
.name("supply-chain-guard")
|
|
24
24
|
.description("Open-source supply-chain security scanner. Detects GlassWorm and similar malware campaigns in npm packages, PyPI packages, code repos, VS Code extensions, and project dependencies.")
|
|
25
|
-
.version("5.
|
|
25
|
+
.version("5.22.0");
|
|
26
26
|
// ── scan command ────────────────────────────────────────────────────
|
|
27
27
|
program
|
|
28
28
|
.command("scan")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-scanner.d.ts","sourceRoot":"","sources":["../src/config-scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOxD,eAAO,MAAM,eAAe,EAAE,YAAY,EA4DzC,CAAC;AAYF;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"config-scanner.d.ts","sourceRoot":"","sources":["../src/config-scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOxD,eAAO,MAAM,eAAe,EAAE,YAAY,EA4DzC,CAAC;AAYF;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,CAkCX;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAsBtD"}
|
package/dist/config-scanner.js
CHANGED
|
@@ -122,6 +122,8 @@ function scanConfigFile(content, relativePath) {
|
|
|
122
122
|
const findings = [];
|
|
123
123
|
const lines = content.split("\n");
|
|
124
124
|
for (const pattern of exports.CONFIG_PATTERNS) {
|
|
125
|
+
if (!(0, patterns_js_1.isPatternApplicableToFile)(pattern, content))
|
|
126
|
+
continue;
|
|
125
127
|
const regex = new RegExp(pattern.pattern, "i");
|
|
126
128
|
for (let i = 0; i < lines.length; i++) {
|
|
127
129
|
const line = lines[i] ?? "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-scanner.js","sourceRoot":"","sources":["../src/config-scanner.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,MAAY,EAAE,oCAAgB;AAC9B,MAAY,IAAI,sCAAkB;AAElC,+
|
|
1
|
+
{"version":3,"file":"config-scanner.js","sourceRoot":"","sources":["../src/config-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,22 @@
|
|
|
5
5
|
* Checks package names against popular packages to detect mimicry.
|
|
6
6
|
*/
|
|
7
7
|
import type { Finding } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve an npm alias spec to the package that actually gets installed.
|
|
10
|
+
*
|
|
11
|
+
* `"utils": "npm:chalk-tempalte@1.0.0"` installs chalk-tempalte and calls it
|
|
12
|
+
* `utils` in the tree. The KEY is a local label chosen by whoever wrote the
|
|
13
|
+
* manifest; the TARGET is the real registry package. Checking the key is
|
|
14
|
+
* therefore checking attacker-controlled text, which is how a known-malicious
|
|
15
|
+
* package used to scan completely clean: every consumer here read the key.
|
|
16
|
+
*
|
|
17
|
+
* Returns null for anything that is not an `npm:` alias, so callers can fall
|
|
18
|
+
* back to the literal name.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveNpmAlias(spec: string | undefined): {
|
|
21
|
+
name: string;
|
|
22
|
+
version?: string;
|
|
23
|
+
} | null;
|
|
8
24
|
/**
|
|
9
25
|
* Calculate Levenshtein distance between two strings.
|
|
10
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-risk-analyzer.d.ts","sourceRoot":"","sources":["../src/dependency-risk-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"dependency-risk-analyzer.d.ts","sourceRoot":"","sources":["../src/dependency-risk-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA8D1C;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsB3C;AA2BD;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAsBxD;AAmDD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,CA8JX"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Checks package names against popular packages to detect mimicry.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.resolveNpmAlias = resolveNpmAlias;
|
|
9
10
|
exports.levenshtein = levenshtein;
|
|
10
11
|
exports.analyzeDependencyRisks = analyzeDependencyRisks;
|
|
11
12
|
/** Top popular npm packages (targets for typosquatting) */
|
|
@@ -29,17 +30,99 @@ const POPULAR_PACKAGES = [
|
|
|
29
30
|
];
|
|
30
31
|
/** Packages that are known-safe even when close in name to popular packages */
|
|
31
32
|
const POPULAR_PACKAGES_SET = new Set(POPULAR_PACKAGES);
|
|
32
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Legitimate, widely-used packages that sit one edit from an entry in
|
|
35
|
+
* POPULAR_PACKAGES and must never be reported as typosquats.
|
|
36
|
+
*
|
|
37
|
+
* This is an ADDITIONAL exemption, not a replacement for POPULAR_PACKAGES_SET:
|
|
38
|
+
* entries here are NOT typosquat targets. The two lists are separate because a
|
|
39
|
+
* name can need exempting without being worth defending: putting a name in
|
|
40
|
+
* POPULAR_PACKAGES also makes every name one edit from it a candidate squat, so
|
|
41
|
+
* the target list has to stay a deliberate choice rather than a dumping ground
|
|
42
|
+
* for whatever tripped the rule this week.
|
|
43
|
+
*
|
|
44
|
+
* Scope note: this set gates exactly one rule (TYPOSQUAT_LEVENSHTEIN, at the
|
|
45
|
+
* single call site below). It is NOT a malware bypass - feed IOC matches, the
|
|
46
|
+
* known-bad-version blocklist and every scanner pattern run on separate paths
|
|
47
|
+
* that never consult it. Do not move this check earlier in install-guard's
|
|
48
|
+
* checkSpec, where it would start gating real malware verdicts.
|
|
49
|
+
*
|
|
50
|
+
* Every entry was verified against the npm registry on 2026-07-29 as a real,
|
|
51
|
+
* maintained package with an identifiable owner - the same evidentiary bar
|
|
52
|
+
* src/patterns.ts applies before blocking any bare name.
|
|
53
|
+
*/
|
|
54
|
+
const TYPOSQUAT_ALLOWLIST = new Set([
|
|
55
|
+
"pathe", // unjs, universal path utils (also a transitive dep of this repo)
|
|
56
|
+
"color", // Qix-/color; NOT a squat of the sabotaged "colors"
|
|
57
|
+
"colord", // omgovich, color manipulation
|
|
58
|
+
"mysql", // the original mysqljs driver; "mysql2" is the successor, both real
|
|
59
|
+
"nuxt", // the Nuxt framework
|
|
60
|
+
"ulid", // ULID id generator; near "uuid" by coincidence
|
|
61
|
+
"preact", // 3kb React-compatible virtual DOM
|
|
62
|
+
"gaxios", // googleapis HTTP client
|
|
63
|
+
"enquirer", // interactive CLI prompts
|
|
64
|
+
"ttypescript", // TypeScript wrapper supporting custom transformers
|
|
65
|
+
]);
|
|
66
|
+
/** Registry name shape, used to validate an alias target. */
|
|
67
|
+
const ALIAS_NAME_RE = /^(@[a-z0-9][a-z0-9-._~]*\/)?[a-z0-9-._~][a-z0-9-._~]*$/i;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve an npm alias spec to the package that actually gets installed.
|
|
70
|
+
*
|
|
71
|
+
* `"utils": "npm:chalk-tempalte@1.0.0"` installs chalk-tempalte and calls it
|
|
72
|
+
* `utils` in the tree. The KEY is a local label chosen by whoever wrote the
|
|
73
|
+
* manifest; the TARGET is the real registry package. Checking the key is
|
|
74
|
+
* therefore checking attacker-controlled text, which is how a known-malicious
|
|
75
|
+
* package used to scan completely clean: every consumer here read the key.
|
|
76
|
+
*
|
|
77
|
+
* Returns null for anything that is not an `npm:` alias, so callers can fall
|
|
78
|
+
* back to the literal name.
|
|
79
|
+
*/
|
|
80
|
+
function resolveNpmAlias(spec) {
|
|
81
|
+
if (typeof spec !== "string")
|
|
82
|
+
return null;
|
|
83
|
+
const trimmed = spec.trim();
|
|
84
|
+
if (!trimmed.startsWith("npm:"))
|
|
85
|
+
return null;
|
|
86
|
+
const target = trimmed.slice(4);
|
|
87
|
+
if (target.length === 0)
|
|
88
|
+
return null;
|
|
89
|
+
// Same split rule as a plain spec: the LAST "@" separates the version, and
|
|
90
|
+
// index 0 is a scope marker rather than a separator.
|
|
91
|
+
const at = target.lastIndexOf("@");
|
|
92
|
+
const name = at > 0 ? target.substring(0, at) : target;
|
|
93
|
+
const version = at > 0 ? target.substring(at + 1) : undefined;
|
|
94
|
+
if (!ALIAS_NAME_RE.test(name))
|
|
95
|
+
return null;
|
|
96
|
+
// A nested protocol ("npm:foo@git:...") is not a plain registry pin. Keep the
|
|
97
|
+
// resolved NAME, which is still checkable, and drop only the version.
|
|
98
|
+
if (version !== undefined && (version.length === 0 || version.includes(":"))) {
|
|
99
|
+
return { name };
|
|
100
|
+
}
|
|
101
|
+
return version === undefined ? { name } : { name, version };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Patterns that suggest an internal/private package name published publicly.
|
|
105
|
+
*
|
|
106
|
+
* Only the two EXPLICIT prefixes are kept. The six suffix patterns that used to
|
|
107
|
+
* live here (-service, -api, -lib, -utils, -common, -core, -shared) matched
|
|
108
|
+
* around 1.7% of every real scoped package on npm and reported them at CRITICAL:
|
|
109
|
+
* @babel/helper-plugin-utils, @vue/compiler-core, @tanstack/query-core,
|
|
110
|
+
* @jest/expect-utils, @azure/msal-common and @prisma/driver-adapter-utils were
|
|
111
|
+
* all dependency-confusion verdicts. "-core" is how the JavaScript ecosystem
|
|
112
|
+
* names its core packages; it is not evidence of anything.
|
|
113
|
+
*
|
|
114
|
+
* They did overlap two curated malicious packages, but by coincidence of name
|
|
115
|
+
* shape rather than knowledge. That knowledge now lives where it belongs: the
|
|
116
|
+
* malicious VERSIONS are pinned in the bundled feed, and @tc-core/campus-service
|
|
117
|
+
* carries a bare-name feed entry (registry-verified: absent from npm, every
|
|
118
|
+
* published version malicious).
|
|
119
|
+
*
|
|
120
|
+
* "internal-" and "private-" are deliberate, self-declared markers and had zero
|
|
121
|
+
* measured false positives.
|
|
122
|
+
*/
|
|
33
123
|
const INTERNAL_PATTERNS = [
|
|
34
124
|
/^@[^/]+\/internal-/,
|
|
35
125
|
/^@[^/]+\/private-/,
|
|
36
|
-
/^@[^/]+\/.+-service$/,
|
|
37
|
-
/^@[^/]+\/.+-api$/,
|
|
38
|
-
/^@[^/]+\/.+-lib$/,
|
|
39
|
-
/^@[^/]+\/.+-utils$/,
|
|
40
|
-
/^@[^/]+\/.+-common$/,
|
|
41
|
-
/^@[^/]+\/.+-core$/,
|
|
42
|
-
/^@[^/]+\/.+-shared$/,
|
|
43
126
|
];
|
|
44
127
|
/**
|
|
45
128
|
* Calculate Levenshtein distance between two strings.
|
|
@@ -60,13 +143,63 @@ function levenshtein(a, b) {
|
|
|
60
143
|
}
|
|
61
144
|
return dp[m][n];
|
|
62
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Optimal String Alignment distance (Damerau-Levenshtein restricted to adjacent
|
|
148
|
+
* transpositions), used ONLY by the typosquat heuristic below.
|
|
149
|
+
*
|
|
150
|
+
* Deliberately separate from the exported `levenshtein`, which is public API
|
|
151
|
+
* (re-exported from src/index.ts) and pinned to exact values by its own tests.
|
|
152
|
+
*
|
|
153
|
+
* Why the typosquat rule needs transposition awareness: the realistic squat is a
|
|
154
|
+
* swapped pair of adjacent characters, which plain Levenshtein scores as 2 edits
|
|
155
|
+
* (two substitutions) rather than 1. The curated squats this rule catches that
|
|
156
|
+
* are transpositions - "rimarf" -> rimraf, "yarsg" -> yargs, "lodahs" -> lodash,
|
|
157
|
+
* "axois" -> axios, "raect" -> react - would all be lost at a plain 1-edit
|
|
158
|
+
* ceiling. Scoring them as 1 is what allows the ceiling to drop from 2 to 1
|
|
159
|
+
* without losing them.
|
|
160
|
+
*
|
|
161
|
+
* Note this rule only ever sees squats of names in POPULAR_PACKAGES. Curated
|
|
162
|
+
* malicious names whose target is NOT in that list (cyrpto, hardhta, naniod,
|
|
163
|
+
* suport-color) are matched by exact name in patterns.ts and the feed, never
|
|
164
|
+
* here - so this heuristic's job is unpublished future squats, not the corpus
|
|
165
|
+
* already curated.
|
|
166
|
+
*/
|
|
167
|
+
function osaDistance(a, b) {
|
|
168
|
+
const m = a.length;
|
|
169
|
+
const n = b.length;
|
|
170
|
+
const dp = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0));
|
|
171
|
+
for (let i = 0; i <= m; i++)
|
|
172
|
+
dp[i][0] = i;
|
|
173
|
+
for (let j = 0; j <= n; j++)
|
|
174
|
+
dp[0][j] = j;
|
|
175
|
+
for (let i = 1; i <= m; i++) {
|
|
176
|
+
for (let j = 1; j <= n; j++) {
|
|
177
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
178
|
+
dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost);
|
|
179
|
+
// Adjacent transposition counts as a single edit.
|
|
180
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
181
|
+
dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + cost);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return dp[m][n];
|
|
186
|
+
}
|
|
63
187
|
/**
|
|
64
188
|
* Analyze dependencies for typosquatting and confusion risks.
|
|
65
189
|
*/
|
|
66
190
|
function analyzeDependencyRisks(dependencies, relativePath) {
|
|
67
191
|
const findings = [];
|
|
68
|
-
|
|
69
|
-
|
|
192
|
+
// Every rule below judges the package that is actually INSTALLED. For an npm
|
|
193
|
+
// alias ("utils": "npm:lodahs@1.0.0") that is the target, not the manifest
|
|
194
|
+
// key, which is arbitrary text chosen by whoever wrote the file.
|
|
195
|
+
const entries = Object.keys(dependencies).map((key) => {
|
|
196
|
+
const alias = resolveNpmAlias(dependencies[key]);
|
|
197
|
+
return { key, name: alias ? alias.name : key, aliased: alias !== null };
|
|
198
|
+
});
|
|
199
|
+
/** Sorted "a b" keys, so one pair yields one finding rather than one per side. */
|
|
200
|
+
const reportedPairs = new Set();
|
|
201
|
+
for (const { key, name, aliased } of entries) {
|
|
202
|
+
const via = aliased ? ` (installed via the npm alias "${key}")` : "";
|
|
70
203
|
// Skip scoped packages for Levenshtein (handled separately)
|
|
71
204
|
if (name.startsWith("@")) {
|
|
72
205
|
// Check internal name patterns on public registry
|
|
@@ -74,7 +207,7 @@ function analyzeDependencyRisks(dependencies, relativePath) {
|
|
|
74
207
|
if (pattern.test(name)) {
|
|
75
208
|
findings.push({
|
|
76
209
|
rule: "DEP_INTERNAL_NAME_PUBLIC",
|
|
77
|
-
description: `Dependency "${name}" looks like an internal package name. If this is on a public registry, it may be a dependency confusion attack.`,
|
|
210
|
+
description: `Dependency "${name}" looks like an internal package name${via}. If this is on a public registry, it may be a dependency confusion attack.`,
|
|
78
211
|
severity: "critical",
|
|
79
212
|
file: relativePath,
|
|
80
213
|
confidence: 0.7,
|
|
@@ -86,53 +219,122 @@ function analyzeDependencyRisks(dependencies, relativePath) {
|
|
|
86
219
|
}
|
|
87
220
|
continue;
|
|
88
221
|
}
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
|
|
222
|
+
// Typosquat check against popular packages.
|
|
223
|
+
//
|
|
224
|
+
// The ceiling is ONE transposition-aware edit. It used to be two plain
|
|
225
|
+
// Levenshtein edits, which flagged 321 measured real packages (acorn, preact,
|
|
226
|
+
// cypress, redux, viem, knex, globby, jose...) against 2 true positives that
|
|
227
|
+
// patterns.ts and the feed already catch by exact name - a ~1:160 signal ratio,
|
|
228
|
+
// and it got WORSE the more popular the package was (2.37% of packages above
|
|
229
|
+
// 10M weekly downloads). Two edits against a 4-character name is simply not
|
|
230
|
+
// evidence of anything. Transposition awareness (see osaDistance) is what makes
|
|
231
|
+
// the tightening free: every real squat in this repo's threat data is an
|
|
232
|
+
// adjacent swap, so all of them still score 1 and are still caught.
|
|
233
|
+
//
|
|
234
|
+
// No first-character predicate is used. It would cut a further ~24 false
|
|
235
|
+
// positives, but this repo curates "1odash" and "l0dash" in patterns.ts as
|
|
236
|
+
// canonical squats, and both change character zero - a leading-homoglyph rule
|
|
237
|
+
// would make this heuristic structurally unable to generalize them. It is also
|
|
238
|
+
// published source, so it would be a one-character documented bypass.
|
|
239
|
+
//
|
|
240
|
+
// Skip if the name is itself a known popular/safe package - prevents false
|
|
241
|
+
// positives where two legitimate popular packages are close in name (next/jest).
|
|
242
|
+
if (!POPULAR_PACKAGES_SET.has(name) &&
|
|
243
|
+
!TYPOSQUAT_ALLOWLIST.has(name) &&
|
|
244
|
+
name.length >= 4) {
|
|
245
|
+
// At a ceiling of 1 every hit is the same distance, so there is no closer
|
|
246
|
+
// match to search for and the first hit is reported. (Under the old 2-edit
|
|
247
|
+
// ceiling this loop could report a distance-2 target while a distance-1 one
|
|
248
|
+
// sat later in the array.) If the ceiling is ever raised, this must go back
|
|
249
|
+
// to tracking the minimum before reporting.
|
|
250
|
+
let best;
|
|
93
251
|
for (const popular of POPULAR_PACKAGES) {
|
|
94
252
|
if (name === popular)
|
|
95
253
|
continue; // Exact match = legitimate
|
|
96
|
-
// Skip
|
|
97
|
-
|
|
254
|
+
// Skip short popular targets. The floor is 5, not 4: measured over 29,687
|
|
255
|
+
// real published npm names, a floor of 4 produced 57 false positives and a
|
|
256
|
+
// floor of 5 produces 29, with the curated true-positive set unchanged. The
|
|
257
|
+
// four-letter targets are the damaging ones because almost any short name is
|
|
258
|
+
// one edit from them - "path" alone accounted for 11 (upath, mpath, xpath,
|
|
259
|
+
// paths, ...) and "jest" for 5 (test, nest, rest, ...). Floor 6 is too far:
|
|
260
|
+
// it loses yarsg, axois, raect and chlak.
|
|
261
|
+
if (popular.length < 5)
|
|
98
262
|
continue;
|
|
99
|
-
if (Math.abs(name.length - popular.length) >
|
|
263
|
+
if (Math.abs(name.length - popular.length) > 1)
|
|
100
264
|
continue; // Quick skip
|
|
101
|
-
const dist =
|
|
102
|
-
if (dist > 0 && dist <=
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
description: `Dependency "${name}" is ${dist} edit(s) away from popular package "${popular}". Likely a typosquat.`,
|
|
106
|
-
severity: "high",
|
|
107
|
-
file: relativePath,
|
|
108
|
-
confidence: dist === 1 ? 0.85 : 0.65,
|
|
109
|
-
category: "supply-chain",
|
|
110
|
-
recommendation: `Did you mean "${popular}"? Typosquatting replaces popular packages with malicious copies.`,
|
|
111
|
-
});
|
|
112
|
-
break; // One match per dep is enough
|
|
265
|
+
const dist = osaDistance(name, popular);
|
|
266
|
+
if (dist > 0 && dist <= 1 && (!best || dist < best.dist)) {
|
|
267
|
+
best = { popular, dist };
|
|
268
|
+
break; // Distance 1 is the tightest possible hit; nothing can beat it.
|
|
113
269
|
}
|
|
114
270
|
}
|
|
115
|
-
|
|
116
|
-
// Check if name is similar to another direct dependency
|
|
117
|
-
for (const otherName of depNames) {
|
|
118
|
-
if (name === otherName)
|
|
119
|
-
continue;
|
|
120
|
-
if (name.startsWith("@") || otherName.startsWith("@"))
|
|
121
|
-
continue;
|
|
122
|
-
if (Math.abs(name.length - otherName.length) > 2)
|
|
123
|
-
continue;
|
|
124
|
-
const dist = levenshtein(name, otherName);
|
|
125
|
-
if (dist > 0 && dist <= 1) {
|
|
271
|
+
if (best) {
|
|
126
272
|
findings.push({
|
|
127
|
-
rule: "
|
|
128
|
-
|
|
273
|
+
rule: "TYPOSQUAT_LEVENSHTEIN",
|
|
274
|
+
// The dependency name MUST stay the first quoted token: policy-engine.ts
|
|
275
|
+
// extracts it with /"([^"]+)"/ to honour user `allowlist.packages` rules.
|
|
276
|
+
description: `Dependency "${name}"${via} is ${best.dist} edit(s) away from popular package "${best.popular}". Likely a typosquat.`,
|
|
129
277
|
severity: "high",
|
|
130
278
|
file: relativePath,
|
|
131
|
-
confidence: 0.
|
|
279
|
+
confidence: 0.85,
|
|
132
280
|
category: "supply-chain",
|
|
133
|
-
recommendation: `
|
|
281
|
+
recommendation: `Did you mean "${best.popular}"? Typosquatting replaces popular packages with malicious copies.`,
|
|
134
282
|
});
|
|
135
|
-
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Check if name is similar to another direct dependency.
|
|
286
|
+
//
|
|
287
|
+
// Measured over 939 real manifests, this rule fired on 5.0% of them (8.1% of
|
|
288
|
+
// real repository roots) and every colliding pair was a legitimate co-install:
|
|
289
|
+
// preact+react, vue+vuex, path+pathe, color+colors, mysql+mysql2, uuid+ulid,
|
|
290
|
+
// eslint+tslint. Four guards below cut that to under 1% while INCREASING
|
|
291
|
+
// recall, because switching to osaDistance starts catching the transposition
|
|
292
|
+
// squats (lodahs+lodash, axois+axios, raect+react, yarsg+yargs) that the rule
|
|
293
|
+
// was silently missing next to their own target.
|
|
294
|
+
//
|
|
295
|
+
// The known-good test is ONE-SIDED on purpose. The outer loop visits both
|
|
296
|
+
// members of a pair, so testing only the reported side keeps the case this
|
|
297
|
+
// rule exists for: {expres, express} still reports, because the express-side
|
|
298
|
+
// pass is dropped while the expres-side pass survives. Testing otherName too
|
|
299
|
+
// would suppress exactly the squat-next-to-its-target shape (measured: it
|
|
300
|
+
// drops 11 of 14 true positives).
|
|
301
|
+
//
|
|
302
|
+
// Guards are scoped to this block rather than the outer loop so the two
|
|
303
|
+
// typosquat rules stay independently editable.
|
|
304
|
+
const skipPairRule = name.length < 4 || POPULAR_PACKAGES_SET.has(name) || TYPOSQUAT_ALLOWLIST.has(name);
|
|
305
|
+
if (!skipPairRule) {
|
|
306
|
+
for (const other of entries) {
|
|
307
|
+
const otherName = other.name;
|
|
308
|
+
if (name === otherName)
|
|
309
|
+
continue;
|
|
310
|
+
if (name.startsWith("@") || otherName.startsWith("@"))
|
|
311
|
+
continue;
|
|
312
|
+
// Same length floor as the sibling rule: below 4 characters almost any
|
|
313
|
+
// name is one edit from another (ws/wss, np/nx, fs/fse, qs/q).
|
|
314
|
+
if (otherName.length < 4)
|
|
315
|
+
continue;
|
|
316
|
+
if (Math.abs(name.length - otherName.length) > 1)
|
|
317
|
+
continue;
|
|
318
|
+
const dist = osaDistance(name, otherName);
|
|
319
|
+
if (dist > 0 && dist <= 1) {
|
|
320
|
+
const pairKey = [name, otherName].sort().join(" ");
|
|
321
|
+
if (reportedPairs.has(pairKey))
|
|
322
|
+
break;
|
|
323
|
+
reportedPairs.add(pairKey);
|
|
324
|
+
const otherVia = other.aliased ? ` (installed via the npm alias "${other.key}")` : "";
|
|
325
|
+
findings.push({
|
|
326
|
+
rule: "TYPOSQUAT_SIMILAR_TO_DEP",
|
|
327
|
+
// "name" leads and is guaranteed to be the non-allowlisted side, so
|
|
328
|
+
// the suspicious package is named first.
|
|
329
|
+
description: `Dependencies "${name}"${via} and "${otherName}"${otherVia} differ by only ${dist} character(s). One may be a typosquat of the other.`,
|
|
330
|
+
severity: "high",
|
|
331
|
+
file: relativePath,
|
|
332
|
+
confidence: 0.7,
|
|
333
|
+
category: "supply-chain",
|
|
334
|
+
recommendation: `Review both "${name}" and "${otherName}". Only one should be in your dependencies.`,
|
|
335
|
+
});
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
136
338
|
}
|
|
137
339
|
}
|
|
138
340
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-risk-analyzer.js","sourceRoot":"","sources":["../src/dependency-risk-analyzer.ts"],"names":[],"mappings":";AAAA;;;;;GAKG
|
|
1
|
+
{"version":3,"file":"dependency-risk-analyzer.js","sourceRoot":"","sources":["../src/dependency-risk-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dockerfile-scanner.d.ts","sourceRoot":"","sources":["../src/dockerfile-scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAmCxD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAgB9D;AAMD,eAAO,MAAM,mBAAmB,EAAE,YAAY,EAuF7C,CAAC;AAWF;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"dockerfile-scanner.d.ts","sourceRoot":"","sources":["../src/dockerfile-scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAmCxD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAgB9D;AAMD,eAAO,MAAM,mBAAmB,EAAE,YAAY,EAuF7C,CAAC;AAWF;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,CA6BX;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAwBtD"}
|
|
@@ -197,6 +197,8 @@ function scanDockerFile(content, relativePath) {
|
|
|
197
197
|
const findings = [];
|
|
198
198
|
const lines = content.split("\n");
|
|
199
199
|
for (const pattern of exports.DOCKERFILE_PATTERNS) {
|
|
200
|
+
if (!(0, patterns_js_1.isPatternApplicableToFile)(pattern, content))
|
|
201
|
+
continue;
|
|
200
202
|
const regex = new RegExp(pattern.pattern, "i");
|
|
201
203
|
for (let i = 0; i < lines.length; i++) {
|
|
202
204
|
const line = lines[i] ?? "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dockerfile-scanner.js","sourceRoot":"","sources":["../src/dockerfile-scanner.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,MAAY,EAAE,oCAAgB;AAC9B,MAAY,IAAI,sCAAkB;AAElC,+
|
|
1
|
+
{"version":3,"file":"dockerfile-scanner.js","sourceRoot":"","sources":["../src/dockerfile-scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/entropy.d.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shannon entropy analysis for detecting obfuscated/encoded payloads.
|
|
3
3
|
*
|
|
4
|
-
* High entropy
|
|
5
|
-
*
|
|
4
|
+
* High entropy in a source file indicates compressed, encoded or obfuscated
|
|
5
|
+
* content, a common technique in supply-chain malware.
|
|
6
|
+
*
|
|
7
|
+
* Entropy is computed over UTF-8 BYTES, which bounds it to 0..8. It used to be
|
|
8
|
+
* computed over CODE POINTS, which is unbounded: a file with many distinct
|
|
9
|
+
* non-Latin characters could exceed 8 and trip a threshold that was documented
|
|
10
|
+
* as being on the 0..8 scale.
|
|
6
11
|
*/
|
|
7
12
|
import type { Finding } from "./types.js";
|
|
8
13
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
14
|
+
* Shannon entropy over UTF-8 bytes. Returns 0 (uniform) to 8 (random).
|
|
15
|
+
*
|
|
16
|
+
* Byte-based on purpose. Iterating a JS string yields CODE POINTS, of which
|
|
17
|
+
* there are ~1.1 million, so the result is unbounded and text in a non-Latin
|
|
18
|
+
* script scores higher purely for having a larger alphabet. For pure ASCII the
|
|
19
|
+
* two are identical, so this changes nothing for the overwhelming majority of
|
|
20
|
+
* scanned files while making the value mean what the thresholds assume.
|
|
11
21
|
*/
|
|
12
22
|
export declare function shannonEntropy(data: string): number;
|
|
13
23
|
/**
|
package/dist/entropy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entropy.d.ts","sourceRoot":"","sources":["../src/entropy.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"entropy.d.ts","sourceRoot":"","sources":["../src/entropy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBnD;AA+BD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,EAAE,CA0DX"}
|