mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
Some cleanup
This commit is contained in:
parent
2df8ce463c
commit
8a4f759a78
2 changed files with 67 additions and 28 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { getMinimumPackageAgeHours, getNpmMinimumPackageAgeExclusions } from "../../../config/settings.js";
|
||||
import { getMinimumPackageAgeHours } from "../../../config/settings.js";
|
||||
import { ui } from "../../../environment/userInteraction.js";
|
||||
import { getHeaderValueAsString } from "../../http-utils.js";
|
||||
|
||||
|
|
@ -65,16 +65,6 @@ export function modifyNpmInfoResponse(body, headers) {
|
|||
return body;
|
||||
}
|
||||
|
||||
// Check if this package is excluded from minimum age filtering
|
||||
const packageName = bodyJson.name;
|
||||
const exclusions = getNpmMinimumPackageAgeExclusions();
|
||||
if (packageName && exclusions.some((pattern) => matchesExclusionPattern(packageName, pattern))) {
|
||||
ui.writeVerbose(
|
||||
`Safe-chain: ${packageName} is excluded from minimum package age filtering (minimumPackageAgeExclusions setting).`
|
||||
);
|
||||
return body;
|
||||
}
|
||||
|
||||
const cutOff = new Date(
|
||||
new Date().getTime() - getMinimumPackageAgeHours() * 3600 * 1000
|
||||
);
|
||||
|
|
|
|||
|
|
@ -46,27 +46,43 @@ function buildNpmInterceptor(registry) {
|
|||
reqContext.targetUrl,
|
||||
registry
|
||||
);
|
||||
const minimumAgeChecksEnabled = !skipMinimumPackageAge();
|
||||
const packageIsExcludedFromMinimumAgeChecks =
|
||||
packageName && isExcludedFromMinimumPackageAge(packageName);
|
||||
|
||||
if (await isMalwarePackage(packageName, version)) {
|
||||
reqContext.blockMalware(packageName, version);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!skipMinimumPackageAge() && isPackageInfoUrl(reqContext.targetUrl)) {
|
||||
if (minimumAgeChecksEnabled && isPackageInfoUrl(reqContext.targetUrl)) {
|
||||
reqContext.modifyRequestHeaders(modifyNpmInfoRequestHeaders);
|
||||
reqContext.modifyBody(modifyNpmInfoResponse);
|
||||
reqContext.modifyBody((body, headers) => {
|
||||
const metadataPackageName = getPackageNameFromMetadataResponse(
|
||||
body,
|
||||
headers
|
||||
);
|
||||
|
||||
if (
|
||||
metadataPackageName &&
|
||||
isExcludedFromMinimumPackageAge(metadataPackageName)
|
||||
) {
|
||||
return body;
|
||||
}
|
||||
|
||||
return modifyNpmInfoResponse(body, headers);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// For tarball requests the metadata check above is skipped, so we check the
|
||||
// new packages list as a fallback (covers e.g. frozen-lockfile installs).
|
||||
if (!skipMinimumPackageAge() && packageName && version) {
|
||||
const exclusions = getNpmMinimumPackageAgeExclusions();
|
||||
const isExcluded = exclusions.some((pattern) =>
|
||||
matchesExclusionPattern(packageName, pattern)
|
||||
);
|
||||
|
||||
if (!isExcluded) {
|
||||
if (
|
||||
minimumAgeChecksEnabled &&
|
||||
packageName &&
|
||||
version &&
|
||||
!packageIsExcludedFromMinimumAgeChecks
|
||||
) {
|
||||
const newPackagesDatabase = await openNewPackagesDatabase();
|
||||
|
||||
if (newPackagesDatabase.isNewlyReleasedPackage(packageName, version)) {
|
||||
|
|
@ -77,6 +93,39 @@ function buildNpmInterceptor(registry) {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packageName
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isExcludedFromMinimumPackageAge(packageName) {
|
||||
const exclusions = getNpmMinimumPackageAgeExclusions();
|
||||
return exclusions.some((pattern) =>
|
||||
matchesExclusionPattern(packageName, pattern)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} body
|
||||
* @param {NodeJS.Dict<string | string[]> | undefined} headers
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function getPackageNameFromMetadataResponse(body, headers) {
|
||||
try {
|
||||
const contentType = headers?.["content-type"];
|
||||
const normalizedContentType = Array.isArray(contentType)
|
||||
? contentType.join(",")
|
||||
: contentType;
|
||||
|
||||
if (!normalizedContentType?.toLowerCase().includes("application/json")) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const bodyJson = JSON.parse(body.toString("utf8"));
|
||||
return typeof bodyJson.name === "string" ? bodyJson.name : undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue