Skip to content

Commit ad19a37

Browse files
committed
chore: pin override versions exactly and reject semver ranges
Replace lodash and minimatch >= overrides with exact lockfile versions and fail supply-chain checks when overrides use ranges.
1 parent a810dd8 commit ad19a37

4 files changed

Lines changed: 47 additions & 14 deletions

File tree

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This repository uses defenses against npm supply-chain worms such as **Mini Shai
1313
- **Blocklist scan**`pnpm run audit:supply-chain` checks the lockfile against `security/compromised-packages.json` and validates pnpm config.
1414
- **Delayed updates**`minimumReleaseAge` (24h, strict) reduces exposure to freshly published malicious versions.
1515
- **No exotic transitive deps**`blockExoticSubdeps` blocks git/tarball transitive resolutions.
16-
- **Version overrides**known CVEs are mitigated via `overrides` in `pnpm-workspace.yaml` (e.g. `lodash`, `uuid`, `minimatch`).
16+
- **Version overrides**CVE mitigations use **exact pins** in `pnpm-workspace.yaml` (e.g. `lodash`, `uuid`, `minimatch`). Do not use `>=`/`^`/`~` ranges in overrides; bump versions deliberately with an updated lockfile and passing audit.
1717

1818
### Enforcing pnpm for contributors
1919

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ packages:
22
- '.'
33

44
# Supply-chain hardening (see SECURITY.md). Configured here — pnpm 10+ ignores package.json "pnpm".
5+
# Pin exact versions only (no >=/^/~ ranges). Bump deliberately with lockfile + audit.
56
overrides:
6-
lodash: '>=4.18.0'
7+
lodash: '4.18.1'
78
uuid: '11.1.1'
8-
minimatch: '>=9.0.7'
9+
minimatch: '10.2.5'
910
# npm dist-tag stable; block 2.23+ beta-channel releases
1011
n8n-workflow: '2.22.3'
1112

scripts/check-supply-chain.mjs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,36 @@ function verifyPnpmOnlyRepository() {
5555
return errors;
5656
}
5757

58+
function verifyExactOverridePins() {
59+
const errors = [];
60+
61+
if (!existsSync(workspacePath)) {
62+
return errors;
63+
}
64+
65+
const workspace = readFileSync(workspacePath, 'utf8');
66+
const overridesBlock = workspace.match(/^overrides:\n([\s\S]*?)(?:\n\S|\n*$)/m);
67+
if (!overridesBlock) {
68+
return errors;
69+
}
70+
71+
for (const line of overridesBlock[1].split('\n')) {
72+
const match = line.match(/^\s+([a-zA-Z0-9@/_-]+):\s*['"]?([^'"\n#]+)['"]?\s*$/);
73+
if (!match) {
74+
continue;
75+
}
76+
const [, name, value] = match;
77+
const trimmed = value.trim();
78+
if (/^[<>=~^*]/.test(trimmed) || trimmed.includes(' ')) {
79+
errors.push(
80+
`pnpm-workspace.yaml override ${name} must be an exact version pin, not a range (${trimmed})`,
81+
);
82+
}
83+
}
84+
85+
return errors;
86+
}
87+
5888
function verifyPnpmWorkspaceConfig() {
5989
const errors = [];
6090

@@ -70,6 +100,8 @@ function verifyPnpmWorkspaceConfig() {
70100
}
71101
}
72102

103+
errors.push(...verifyExactOverridePins());
104+
73105
if (existsSync(packageJsonPath)) {
74106
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
75107
if (pkg.pnpm) {
@@ -116,8 +148,8 @@ function verifyActivePnpmConfig() {
116148
}
117149
}
118150

119-
if (!config.includes('lodash=') || !config.includes('uuid=')) {
120-
errors.push('pnpm overrides for lodash/uuid are not active — check pnpm-workspace.yaml');
151+
if (!config.includes('lodash=') || !config.includes('uuid=') || !config.includes('minimatch=')) {
152+
errors.push('pnpm overrides for lodash/uuid/minimatch are not active — check pnpm-workspace.yaml');
121153
}
122154
} catch (error) {
123155
errors.push(`unable to read pnpm config: ${error.message}`);

0 commit comments

Comments
 (0)