[AAE-46514] - Improved check, updated descriptions, skip check on CI as there is already Sonar

This commit is contained in:
VitoAlbano
2026-06-04 09:26:32 +01:00
parent af8432f864
commit 0fa8672f16
9 changed files with 81 additions and 17 deletions
+1
View File
@@ -11,6 +11,7 @@ on:
env:
NODE_OPTIONS: "--max-old-space-size=5120"
ADF_SKIP_SECURITY_CHECK: 1
jobs:
build:
+1
View File
@@ -33,6 +33,7 @@ concurrency:
env:
GH_COMMIT: ${{ github.sha }}
NODE_OPTIONS: "--max-old-space-size=5120"
ADF_SKIP_SECURITY_CHECK: 1
jobs:
pre-checks:
+1
View File
@@ -40,6 +40,7 @@ env:
GH_BUILD_NUMBER: ${{ github.run_id }}
LOG_LEVEL: "ERROR"
NODE_OPTIONS: "--max-old-space-size=5120"
ADF_SKIP_SECURITY_CHECK: 1
jobs:
setup:
+3
View File
@@ -9,6 +9,9 @@ on:
type: string
default: 'develop'
env:
ADF_SKIP_SECURITY_CHECK: 1
jobs:
generate-affected-matrix:
name: "Generate affected matrix"
+13 -3
View File
@@ -31,12 +31,22 @@ This project has built-in supply chain attack protection. When you run `npm inst
1. **Preinstall check** scans both `package.json` AND `package-lock.json` against OSV + GitHub Advisory databases
2. If malicious packages detected → installation blocked BEFORE any code runs
3. Packages install normally
4. **Post-install check** verifies installed packages (defense in depth)
5. Only trusted packages (esbuild, nx, husky, etc.) get their native bindings rebuilt
3. Packages install with `--ignore-scripts` (lifecycle scripts disabled for security)
4. **Post-install check** re-runs the security scan (defense in depth) and deletes `node_modules` if violations found
5. Trusted packages (esbuild, nx, husky, etc.) are rebuilt via `npm rebuild` to run their lifecycle scripts
Checking `package.json` catches new dependencies added during upgrades (e.g., `nx migrate`) before the lockfile is updated. If a malicious package is detected at any stage, installation is blocked.
To disable security checks (e.g., in CI environments):
```bash
ADF_SKIP_SECURITY_CHECK=1 npm install
```
To keep `node_modules` on violations (for debugging):
```bash
ADF_SECURITY_KEEP_NODE_MODULES=1 npm install
```
## Components
You can find the sources for all ADF components in the [`lib`](/lib) folder.
+4 -2
View File
@@ -489,6 +489,8 @@ async function main() {
}
main().catch(error => {
console.error('Security check failed:', error.message);
process.exit(0);
console.error('\n❌ Security check crashed unexpectedly:', error.message);
console.error(' Blocking installation as a precaution.');
console.error(' Set ADF_SKIP_SECURITY_CHECK=1 to bypass.\n');
process.exit(1);
});
+4 -2
View File
@@ -455,6 +455,8 @@ async function main() {
}
main().catch(error => {
console.error('Security check error:', error.message);
process.exit(0);
console.error('\n❌ Security check crashed unexpectedly:', error.message);
console.error(' Blocking installation as a precaution.');
console.error(' Set ADF_SKIP_SECURITY_CHECK=1 to bypass.\n');
process.exit(1);
});
@@ -39,6 +39,10 @@ function listDirectories(path) {
}
function findVSCodeExtensionCli(homeDir) {
if (!homeDir) {
return null;
}
const extensionsDir = join(homeDir, '.vscode', 'extensions');
const extensions = listDirectories(extensionsDir)
.filter(dir => /^meterian\.meterian-heidi-\d+\.\d+\.\d+$/.test(dir))
@@ -58,9 +62,9 @@ function findVSCodeExtensionCli(homeDir) {
function findGlobalCli(homeDir, rootDir) {
const possibleLocations = [
join(rootDir, 'node_modules', '@meterian', 'cli'),
join(homeDir, '.npm-global', 'lib', 'node_modules', '@meterian', 'cli'),
homeDir ? join(homeDir, '.npm-global', 'lib', 'node_modules', '@meterian', 'cli') : null,
'/usr/local/lib/node_modules/@meterian/cli'
];
].filter(Boolean);
for (const location of possibleLocations) {
if (isDirectory(location)) {
+48 -8
View File
@@ -36,18 +36,51 @@ function isMalwareRelated(text) {
return MALWARE_KEYWORDS.some(keyword => lowerText.includes(keyword.toLowerCase()));
}
function extractRangesFromEvents(events) {
const ranges = [];
let introduced = null;
for (const event of events) {
if (event.introduced !== undefined) {
introduced = event.introduced;
} else if (event.fixed !== undefined && introduced !== null) {
if (introduced === '0') {
ranges.push(`< ${event.fixed}`);
} else {
ranges.push(`>= ${introduced}, < ${event.fixed}`);
}
introduced = null;
} else if (event.last_affected !== undefined && introduced !== null) {
if (introduced === '0') {
ranges.push(`<= ${event.last_affected}`);
} else {
ranges.push(`>= ${introduced}, <= ${event.last_affected}`);
}
introduced = null;
}
}
if (introduced !== null && introduced !== '0') {
ranges.push(`>= ${introduced}`);
}
return ranges;
}
function extractVersionsFromVulnerability(vulnerability) {
const affectedEntries = vulnerability.affected || [];
const introducedVersions = affectedEntries
const versionRanges = affectedEntries
.flatMap(entry => entry.ranges || [])
.flatMap(range => range.events || [])
.filter(event => event.introduced && event.introduced !== '0')
.map(event => event.introduced);
.filter(range => range.type === 'SEMVER' || range.type === 'ECOSYSTEM')
.flatMap(range => extractRangesFromEvents(range.events || []));
const explicitVersions = affectedEntries.flatMap(entry => entry.versions || []);
return [...new Set([...introducedVersions, ...explicitVersions])];
return {
versions: [...new Set(explicitVersions)],
versionRanges: [...new Set(versionRanges)]
};
}
function splitIntoBatches(items, batchSize) {
@@ -95,14 +128,15 @@ function extractMalwareInfo(vulnerability) {
return null;
}
const versions = extractVersionsFromVulnerability(vulnerability);
if (versions.length === 0) {
const { versions, versionRanges } = extractVersionsFromVulnerability(vulnerability);
if (versions.length === 0 && versionRanges.length === 0) {
return null;
}
return {
packageName,
versions,
versionRanges,
reason: vulnerability.summary || 'Malware detected by OSV'
};
}
@@ -116,9 +150,15 @@ function processBatchResults(batchResults, malwareRegistry) {
if (malwareInfo) {
if (!malwareRegistry[malwareInfo.packageName]) {
malwareRegistry[malwareInfo.packageName] = { versions: [], reason: '', source: 'OSV' };
malwareRegistry[malwareInfo.packageName] = {
versions: [],
versionRanges: [],
reason: '',
source: 'OSV'
};
}
malwareRegistry[malwareInfo.packageName].versions.push(...malwareInfo.versions);
malwareRegistry[malwareInfo.packageName].versionRanges.push(...malwareInfo.versionRanges);
malwareRegistry[malwareInfo.packageName].reason = malwareInfo.reason;
}
}