sentinello 3.8.0 → 3.8.2
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/dist/cli.cjs +639 -216
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -2680,16 +2680,16 @@ var require_parse2 = __commonJS({
|
|
|
2680
2680
|
return self2.pull(4).then(function(data) {
|
|
2681
2681
|
if (data.length === 0)
|
|
2682
2682
|
return;
|
|
2683
|
-
const
|
|
2684
|
-
if (
|
|
2683
|
+
const signature2 = data.readUInt32LE(0);
|
|
2684
|
+
if (signature2 === 875721283) {
|
|
2685
2685
|
return self2._readCrxHeader();
|
|
2686
2686
|
}
|
|
2687
|
-
if (
|
|
2687
|
+
if (signature2 === 67324752) {
|
|
2688
2688
|
return self2._readFile();
|
|
2689
|
-
} else if (
|
|
2689
|
+
} else if (signature2 === 33639248) {
|
|
2690
2690
|
self2.reachedCD = true;
|
|
2691
2691
|
return self2._readCentralDirectoryFileHeader();
|
|
2692
|
-
} else if (
|
|
2692
|
+
} else if (signature2 === 101010256) {
|
|
2693
2693
|
return self2._readEndOfCentralDirectoryRecord();
|
|
2694
2694
|
} else if (self2.reachedCD) {
|
|
2695
2695
|
const includeEof = true;
|
|
@@ -2697,7 +2697,7 @@ var require_parse2 = __commonJS({
|
|
|
2697
2697
|
return self2._readEndOfCentralDirectoryRecord();
|
|
2698
2698
|
});
|
|
2699
2699
|
} else
|
|
2700
|
-
self2.emit("error", new Error("invalid signature: 0x" +
|
|
2700
|
+
self2.emit("error", new Error("invalid signature: 0x" + signature2.toString(16)));
|
|
2701
2701
|
}).then((function(loop) {
|
|
2702
2702
|
if (loop) {
|
|
2703
2703
|
return self2._readRecord();
|
|
@@ -5487,8 +5487,8 @@ var require_graceful_fs = __commonJS({
|
|
|
5487
5487
|
fs2.createReadStream = createReadStream;
|
|
5488
5488
|
fs2.createWriteStream = createWriteStream2;
|
|
5489
5489
|
var fs$readFile = fs2.readFile;
|
|
5490
|
-
fs2.readFile =
|
|
5491
|
-
function
|
|
5490
|
+
fs2.readFile = readFile14;
|
|
5491
|
+
function readFile14(path, options, cb) {
|
|
5492
5492
|
if (typeof options === "function")
|
|
5493
5493
|
cb = options, options = null;
|
|
5494
5494
|
return go$readFile(path, options, cb);
|
|
@@ -6874,7 +6874,7 @@ var require_jsonfile = __commonJS({
|
|
|
6874
6874
|
}
|
|
6875
6875
|
return obj2;
|
|
6876
6876
|
}
|
|
6877
|
-
var
|
|
6877
|
+
var readFile14 = universalify.fromPromise(_readFile);
|
|
6878
6878
|
function readFileSync2(file2, options = {}) {
|
|
6879
6879
|
if (typeof options === "string") {
|
|
6880
6880
|
options = { encoding: options };
|
|
@@ -6906,7 +6906,7 @@ var require_jsonfile = __commonJS({
|
|
|
6906
6906
|
return fs.writeFileSync(file2, str2, options);
|
|
6907
6907
|
}
|
|
6908
6908
|
module2.exports = {
|
|
6909
|
-
readFile:
|
|
6909
|
+
readFile: readFile14,
|
|
6910
6910
|
readFileSync: readFileSync2,
|
|
6911
6911
|
writeFile: writeFile4,
|
|
6912
6912
|
writeFileSync
|
|
@@ -12784,13 +12784,13 @@ var require_directory = __commonJS({
|
|
|
12784
12784
|
var parseDateTime = require_parseDateTime();
|
|
12785
12785
|
var parseBuffer = require_parseBuffer();
|
|
12786
12786
|
var Bluebird = require_bluebird();
|
|
12787
|
-
var
|
|
12788
|
-
|
|
12787
|
+
var signature2 = Buffer.alloc(4);
|
|
12788
|
+
signature2.writeUInt32LE(101010256, 0);
|
|
12789
12789
|
function getCrxHeader(source) {
|
|
12790
12790
|
const sourceStream = source.stream(0).pipe(PullStream());
|
|
12791
12791
|
return sourceStream.pull(4).then(function(data) {
|
|
12792
|
-
const
|
|
12793
|
-
if (
|
|
12792
|
+
const signature3 = data.readUInt32LE(0);
|
|
12793
|
+
if (signature3 === 875721283) {
|
|
12794
12794
|
let crxHeader;
|
|
12795
12795
|
return sourceStream.pull(12).then(function(data2) {
|
|
12796
12796
|
crxHeader = parseBuffer.parse(data2, [
|
|
@@ -12853,7 +12853,7 @@ var require_directory = __commonJS({
|
|
|
12853
12853
|
source.stream(Math.max(0, size - tailSize)).on("error", function(error62) {
|
|
12854
12854
|
endDir.emit("error", error62);
|
|
12855
12855
|
}).pipe(endDir);
|
|
12856
|
-
return endDir.pull(
|
|
12856
|
+
return endDir.pull(signature2);
|
|
12857
12857
|
}).then(function() {
|
|
12858
12858
|
return Bluebird.props({ directory: endDir.pull(22), crxHeader });
|
|
12859
12859
|
}).then(function(d) {
|
|
@@ -13113,6 +13113,7 @@ var SEVERITY_WEIGHT = {
|
|
|
13113
13113
|
critical: 5,
|
|
13114
13114
|
high: 4,
|
|
13115
13115
|
moderate: 3,
|
|
13116
|
+
unrated: 3,
|
|
13116
13117
|
low: 2,
|
|
13117
13118
|
info: 1
|
|
13118
13119
|
};
|
|
@@ -13133,7 +13134,7 @@ function maxSeverity(severities) {
|
|
|
13133
13134
|
for (const s of severities) {
|
|
13134
13135
|
const normalized = s.trim().toLowerCase();
|
|
13135
13136
|
const known = SEVERITY_WEIGHT[normalized];
|
|
13136
|
-
if (known !== void 0 && known > bestWeight) {
|
|
13137
|
+
if (known !== void 0 && (known > bestWeight || known === bestWeight && normalized === "moderate")) {
|
|
13137
13138
|
bestWeight = known;
|
|
13138
13139
|
best = normalized;
|
|
13139
13140
|
}
|
|
@@ -13174,6 +13175,7 @@ var REASON_CODE_VALUES = [
|
|
|
13174
13175
|
"ambiguous_dependency_spec",
|
|
13175
13176
|
"unsupported_lockfile",
|
|
13176
13177
|
"ecosystem_source_disabled",
|
|
13178
|
+
"source_not_applicable",
|
|
13177
13179
|
"timeout"
|
|
13178
13180
|
];
|
|
13179
13181
|
var SOURCE_UNAVAILABLE_REASON_CODES = [
|
|
@@ -13747,7 +13749,7 @@ var ECOSYSTEMS = [
|
|
|
13747
13749
|
status: "stable",
|
|
13748
13750
|
osvEcosystem: "npm",
|
|
13749
13751
|
gemnasiumPackageType: "npm",
|
|
13750
|
-
resolverKinds: ["package-lock.json", "pnpm-lock.yaml", "yarn.lock"],
|
|
13752
|
+
resolverKinds: ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"],
|
|
13751
13753
|
manifestKinds: ["package.json"],
|
|
13752
13754
|
comparator: "semver",
|
|
13753
13755
|
wayOut: true,
|
|
@@ -13821,6 +13823,9 @@ function getSource(id) {
|
|
|
13821
13823
|
}
|
|
13822
13824
|
return null;
|
|
13823
13825
|
}
|
|
13826
|
+
function sourceAppliesToPackageManager(source, packageManager) {
|
|
13827
|
+
return !(source === "npm-audit" && packageManager === "bun");
|
|
13828
|
+
}
|
|
13824
13829
|
function requireEcosystemId(id) {
|
|
13825
13830
|
const def = getEcosystem(id);
|
|
13826
13831
|
if (def === null) throw new Error("unknown ecosystem " + JSON.stringify(id));
|
|
@@ -13855,6 +13860,8 @@ var MANIFEST_PACKAGE_MANAGERS = {
|
|
|
13855
13860
|
"package-lock.json": "npm",
|
|
13856
13861
|
"pnpm-lock.yaml": "pnpm",
|
|
13857
13862
|
"yarn.lock": "yarn",
|
|
13863
|
+
"bun.lock": "bun",
|
|
13864
|
+
"bun.lockb": "bun",
|
|
13858
13865
|
"package.json": "unknown",
|
|
13859
13866
|
"poetry.lock": "poetry",
|
|
13860
13867
|
"Pipfile.lock": "pipenv",
|
|
@@ -13904,6 +13911,7 @@ var REASON_CODE_LABELS = {
|
|
|
13904
13911
|
ambiguous_dependency_spec: "Ambiguous dependency spec",
|
|
13905
13912
|
unsupported_lockfile: "Unsupported lockfile",
|
|
13906
13913
|
ecosystem_source_disabled: "No source enabled for ecosystem",
|
|
13914
|
+
source_not_applicable: "npm audit does not read bun.lock",
|
|
13907
13915
|
timeout: "Timeout"
|
|
13908
13916
|
},
|
|
13909
13917
|
"es": {
|
|
@@ -13935,6 +13943,7 @@ var REASON_CODE_LABELS = {
|
|
|
13935
13943
|
ambiguous_dependency_spec: "Especificaci\xF3n de dependencia ambigua",
|
|
13936
13944
|
unsupported_lockfile: "Lockfile no compatible",
|
|
13937
13945
|
ecosystem_source_disabled: "Sin fuente habilitada para el ecosistema",
|
|
13946
|
+
source_not_applicable: "npm audit no lee bun.lock",
|
|
13938
13947
|
timeout: "Tiempo de espera agotado"
|
|
13939
13948
|
},
|
|
13940
13949
|
"fr": {
|
|
@@ -13966,6 +13975,7 @@ var REASON_CODE_LABELS = {
|
|
|
13966
13975
|
ambiguous_dependency_spec: "Sp\xE9cification de d\xE9pendance ambigu\xEB",
|
|
13967
13976
|
unsupported_lockfile: "Lockfile non pris en charge",
|
|
13968
13977
|
ecosystem_source_disabled: "Aucune source activ\xE9e pour l\u2019\xE9cosyst\xE8me",
|
|
13978
|
+
source_not_applicable: "npm audit ne lit pas bun.lock",
|
|
13969
13979
|
timeout: "D\xE9lai d\xE9pass\xE9"
|
|
13970
13980
|
},
|
|
13971
13981
|
"de": {
|
|
@@ -13997,6 +14007,7 @@ var REASON_CODE_LABELS = {
|
|
|
13997
14007
|
ambiguous_dependency_spec: "Mehrdeutige Abh\xE4ngigkeitsangabe",
|
|
13998
14008
|
unsupported_lockfile: "Nicht unterst\xFCtzte Lockfile",
|
|
13999
14009
|
ecosystem_source_disabled: "Keine Quelle f\xFCr \xD6kosystem aktiviert",
|
|
14010
|
+
source_not_applicable: "npm audit liest bun.lock nicht",
|
|
14000
14011
|
timeout: "Zeit\xFCberschreitung"
|
|
14001
14012
|
},
|
|
14002
14013
|
"pt-BR": {
|
|
@@ -14028,6 +14039,7 @@ var REASON_CODE_LABELS = {
|
|
|
14028
14039
|
ambiguous_dependency_spec: "Especifica\xE7\xE3o de depend\xEAncia amb\xEDgua",
|
|
14029
14040
|
unsupported_lockfile: "Lockfile n\xE3o suportado",
|
|
14030
14041
|
ecosystem_source_disabled: "Nenhuma fonte habilitada para o ecossistema",
|
|
14042
|
+
source_not_applicable: "npm audit n\xE3o l\xEA bun.lock",
|
|
14031
14043
|
timeout: "Tempo esgotado"
|
|
14032
14044
|
},
|
|
14033
14045
|
"it": {
|
|
@@ -14059,6 +14071,7 @@ var REASON_CODE_LABELS = {
|
|
|
14059
14071
|
ambiguous_dependency_spec: "Specifica di dipendenza ambigua",
|
|
14060
14072
|
unsupported_lockfile: "Lockfile non supportato",
|
|
14061
14073
|
ecosystem_source_disabled: "Nessuna fonte abilitata per l\u2019ecosistema",
|
|
14074
|
+
source_not_applicable: "npm audit non legge bun.lock",
|
|
14062
14075
|
timeout: "Timeout scaduto"
|
|
14063
14076
|
},
|
|
14064
14077
|
"ja": {
|
|
@@ -14090,6 +14103,7 @@ var REASON_CODE_LABELS = {
|
|
|
14090
14103
|
ambiguous_dependency_spec: "\u4F9D\u5B58\u95A2\u4FC2\u306E\u6307\u5B9A\u304C\u66D6\u6627",
|
|
14091
14104
|
unsupported_lockfile: "\u672A\u5BFE\u5FDC\u306E\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB",
|
|
14092
14105
|
ecosystem_source_disabled: "\u30A8\u30B3\u30B7\u30B9\u30C6\u30E0\u306B\u6709\u52B9\u306A\u30BD\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093",
|
|
14106
|
+
source_not_applicable: "npm audit \u306F bun.lock \u3092\u8AAD\u307F\u53D6\u308A\u307E\u305B\u3093",
|
|
14093
14107
|
timeout: "\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8"
|
|
14094
14108
|
},
|
|
14095
14109
|
"zh-CN": {
|
|
@@ -14121,6 +14135,7 @@ var REASON_CODE_LABELS = {
|
|
|
14121
14135
|
ambiguous_dependency_spec: "\u4F9D\u8D56\u9879\u89C4\u8303\u4E0D\u660E\u786E",
|
|
14122
14136
|
unsupported_lockfile: "\u4E0D\u652F\u6301\u7684\u9501\u6587\u4EF6",
|
|
14123
14137
|
ecosystem_source_disabled: "\u8BE5\u751F\u6001\u7CFB\u7EDF\u672A\u542F\u7528\u4EFB\u4F55\u6765\u6E90",
|
|
14138
|
+
source_not_applicable: "npm audit \u4E0D\u8BFB\u53D6 bun.lock",
|
|
14124
14139
|
timeout: "\u8D85\u65F6"
|
|
14125
14140
|
},
|
|
14126
14141
|
"ko": {
|
|
@@ -14152,6 +14167,7 @@ var REASON_CODE_LABELS = {
|
|
|
14152
14167
|
ambiguous_dependency_spec: "\uBAA8\uD638\uD55C \uC758\uC874\uC131 \uBA85\uC138",
|
|
14153
14168
|
unsupported_lockfile: "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC7A0\uAE08 \uD30C\uC77C",
|
|
14154
14169
|
ecosystem_source_disabled: "\uC0DD\uD0DC\uACC4\uC5D0 \uD65C\uC131\uD654\uB41C \uC18C\uC2A4 \uC5C6\uC74C",
|
|
14170
|
+
source_not_applicable: "npm audit\uB294 bun.lock\uC744 \uC77D\uC9C0 \uC54A\uC74C",
|
|
14155
14171
|
timeout: "\uC2DC\uAC04 \uCD08\uACFC"
|
|
14156
14172
|
},
|
|
14157
14173
|
"ru": {
|
|
@@ -14183,6 +14199,7 @@ var REASON_CODE_LABELS = {
|
|
|
14183
14199
|
ambiguous_dependency_spec: "\u041D\u0435\u043E\u0434\u043D\u043E\u0437\u043D\u0430\u0447\u043D\u0430\u044F \u0441\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0438",
|
|
14184
14200
|
unsupported_lockfile: "\u041D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 lockfile",
|
|
14185
14201
|
ecosystem_source_disabled: "\u041D\u0435\u0442 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u044D\u043A\u043E\u0441\u0438\u0441\u0442\u0435\u043C\u044B",
|
|
14202
|
+
source_not_applicable: "npm audit \u043D\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 bun.lock",
|
|
14186
14203
|
timeout: "\u0422\u0430\u0439\u043C-\u0430\u0443\u0442"
|
|
14187
14204
|
}
|
|
14188
14205
|
};
|
|
@@ -14322,6 +14339,7 @@ var REASON_SIDE = {
|
|
|
14322
14339
|
gemnasium_db_not_seeded: "environment",
|
|
14323
14340
|
gemnasium_db_unavailable: "environment",
|
|
14324
14341
|
ecosystem_source_disabled: "environment",
|
|
14342
|
+
source_not_applicable: "environment",
|
|
14325
14343
|
timeout: "environment"
|
|
14326
14344
|
};
|
|
14327
14345
|
function failureReasonCode(code) {
|
|
@@ -14402,6 +14420,12 @@ var NOT_YET_RUN_LABELS = {
|
|
|
14402
14420
|
};
|
|
14403
14421
|
|
|
14404
14422
|
// ../../packages/core/src/fix-status.ts
|
|
14423
|
+
function fixKindOf(f) {
|
|
14424
|
+
if (f.fixStatus !== "released" || !f.fixVersion) return null;
|
|
14425
|
+
const comparator = comparatorForEcosystem(f.ecosystem);
|
|
14426
|
+
const normalized = comparator?.normalize(f.fixVersion) ?? null;
|
|
14427
|
+
return normalized !== null && comparator.releaseKind(normalized) === "pseudo" ? "untagged_commit" : "release";
|
|
14428
|
+
}
|
|
14405
14429
|
function isoDate2(at) {
|
|
14406
14430
|
return new Date(at).toISOString().slice(0, 10);
|
|
14407
14431
|
}
|
|
@@ -14420,12 +14444,17 @@ function staleSuffix(check2) {
|
|
|
14420
14444
|
return " \xB7 cached data from " + isoDate2(check2.packageDataAsOf);
|
|
14421
14445
|
}
|
|
14422
14446
|
function describeNotRechecked(reason) {
|
|
14423
|
-
const project = reason
|
|
14424
|
-
if (reason.manifests !== null) return "copies in " + reason.manifests.join(", ") + " not re-checked \u2014 " + project +
|
|
14447
|
+
const project = projectCannotBeScanned(reason);
|
|
14448
|
+
if (reason.manifests !== null) return "copies in " + reason.manifests.join(", ") + " not re-checked \u2014 " + project + reasonCodeLabel(reason.reasonCode);
|
|
14425
14449
|
const when = reason.lastOkScanAt === null ? "never scanned successfully" : "last scanned successfully " + isoDate2(reason.lastOkScanAt);
|
|
14426
|
-
return "not re-checked \u2014 " + project +
|
|
14450
|
+
return "not re-checked \u2014 " + project + reasonCodeLabel(reason.reasonCode) + " (" + when + ")";
|
|
14451
|
+
}
|
|
14452
|
+
function projectCannotBeScanned(reason) {
|
|
14453
|
+
if (reason.projectState === "cannot_scan") return "the project cannot be scanned: ";
|
|
14454
|
+
return reason.projectState === "partial" || reason.manifests !== null ? "the project cannot be fully scanned: " : "";
|
|
14427
14455
|
}
|
|
14428
14456
|
function describeFix(f, style) {
|
|
14457
|
+
if (f.noticeKind) return "no fix to chase \u2014 this is a notice (" + f.noticeKind + "), not a vulnerability";
|
|
14429
14458
|
const notRechecked = f.notRecheckedBecause ?? null;
|
|
14430
14459
|
if (notRechecked === null) return describeSettledFix(f, style);
|
|
14431
14460
|
if (f.fixCheck === null) return describeNotRechecked(notRechecked);
|
|
@@ -14435,6 +14464,7 @@ function describeSettledFix(f, style) {
|
|
|
14435
14464
|
const check2 = f.fixCheck;
|
|
14436
14465
|
if (check2 === null) return "fix not re-checked yet \u2014 rescan pending";
|
|
14437
14466
|
if (f.fixStatus === "released" && f.fixVersion) {
|
|
14467
|
+
if (fixKindOf(f) === "untagged_commit") return "upgrade to " + style.code(f.fixVersion) + " (an untagged commit: no tagged release has the fix)" + staleSuffix(check2);
|
|
14438
14468
|
return "upgrade to " + style.code(f.fixVersion) + staleSuffix(check2);
|
|
14439
14469
|
}
|
|
14440
14470
|
if (f.fixStatus === "none_released") {
|
|
@@ -14460,6 +14490,93 @@ function describeFixDisagreement(f, style) {
|
|
|
14460
14490
|
return "sources disagree: " + listed + " \u2014 " + style.code(f.fixVersion) + " is outside " + outside;
|
|
14461
14491
|
}
|
|
14462
14492
|
|
|
14493
|
+
// ../../packages/core/src/reason-fix-hints.ts
|
|
14494
|
+
var REASON_FIX_HINTS = {
|
|
14495
|
+
"en": {
|
|
14496
|
+
no_lockfile: "commit the lockfile your package manager writes",
|
|
14497
|
+
unknown_pm: "name the package manager in package.json, or commit its lockfile",
|
|
14498
|
+
yarn_v1_unsupported: "move to Yarn 2 or later, npm or pnpm",
|
|
14499
|
+
partial_dependency_graph: "pin what comes from git, a local path or a URL to a released version where you can",
|
|
14500
|
+
ambiguous_dependency_spec: "pin exact versions (== in requirements.txt) or commit a lockfile",
|
|
14501
|
+
unsupported_lockfile: "regenerate it in a format Sentinello reads: npm install with npm 7 or later, or bun install --save-text-lockfile"
|
|
14502
|
+
},
|
|
14503
|
+
"es": {
|
|
14504
|
+
no_lockfile: "haz commit del lockfile que escribe tu gestor de paquetes",
|
|
14505
|
+
unknown_pm: "indica el gestor de paquetes en package.json o haz commit de su lockfile",
|
|
14506
|
+
yarn_v1_unsupported: "pasa a Yarn 2 o posterior, npm o pnpm",
|
|
14507
|
+
partial_dependency_graph: "fija en una versi\xF3n publicada lo que venga de git, de una ruta local o de una URL, cuando puedas",
|
|
14508
|
+
ambiguous_dependency_spec: "fija versiones exactas (== en requirements.txt) o haz commit de un lockfile",
|
|
14509
|
+
unsupported_lockfile: "regen\xE9ralo en un formato que Sentinello lea: npm install con npm 7 o posterior, o bun install --save-text-lockfile"
|
|
14510
|
+
},
|
|
14511
|
+
"fr": {
|
|
14512
|
+
no_lockfile: "committez le lockfile \xE9crit par votre gestionnaire de paquets",
|
|
14513
|
+
unknown_pm: "indiquez le gestionnaire de paquets dans package.json, ou committez son lockfile",
|
|
14514
|
+
yarn_v1_unsupported: "passez \xE0 Yarn 2 ou ult\xE9rieur, npm ou pnpm",
|
|
14515
|
+
partial_dependency_graph: "\xE9pinglez sur une version publi\xE9e ce qui vient de git, d'un chemin local ou d'une URL, si possible",
|
|
14516
|
+
ambiguous_dependency_spec: "\xE9pinglez des versions exactes (== dans requirements.txt) ou committez un lockfile",
|
|
14517
|
+
unsupported_lockfile: "r\xE9g\xE9n\xE9rez-le dans un format que Sentinello lit : npm install avec npm 7 ou ult\xE9rieur, ou bun install --save-text-lockfile"
|
|
14518
|
+
},
|
|
14519
|
+
"de": {
|
|
14520
|
+
no_lockfile: "committe die Lockfile, die dein Paketmanager schreibt",
|
|
14521
|
+
unknown_pm: "nenne den Paketmanager in package.json oder committe seine Lockfile",
|
|
14522
|
+
yarn_v1_unsupported: "wechsle zu Yarn 2 oder neuer, npm oder pnpm",
|
|
14523
|
+
partial_dependency_graph: "pinne, was aus git, einem lokalen Pfad oder einer URL kommt, wo m\xF6glich auf eine ver\xF6ffentlichte Version",
|
|
14524
|
+
ambiguous_dependency_spec: "pinne exakte Versionen (== in requirements.txt) oder committe eine Lockfile",
|
|
14525
|
+
unsupported_lockfile: "erzeuge sie in einem Format neu, das Sentinello liest: npm install mit npm 7 oder neuer, oder bun install --save-text-lockfile"
|
|
14526
|
+
},
|
|
14527
|
+
"pt-BR": {
|
|
14528
|
+
no_lockfile: "fa\xE7a commit do lockfile que seu gerenciador de pacotes escreve",
|
|
14529
|
+
unknown_pm: "indique o gerenciador de pacotes no package.json ou fa\xE7a commit do lockfile dele",
|
|
14530
|
+
yarn_v1_unsupported: "migre para Yarn 2 ou posterior, npm ou pnpm",
|
|
14531
|
+
partial_dependency_graph: "fixe em uma vers\xE3o publicada o que vem do git, de um caminho local ou de uma URL, quando poss\xEDvel",
|
|
14532
|
+
ambiguous_dependency_spec: "fixe vers\xF5es exatas (== no requirements.txt) ou fa\xE7a commit de um lockfile",
|
|
14533
|
+
unsupported_lockfile: "gere-o de novo em um formato que o Sentinello leia: npm install com npm 7 ou posterior, ou bun install --save-text-lockfile"
|
|
14534
|
+
},
|
|
14535
|
+
"it": {
|
|
14536
|
+
no_lockfile: "esegui il commit del lockfile scritto dal tuo gestore di pacchetti",
|
|
14537
|
+
unknown_pm: "indica il gestore di pacchetti in package.json o esegui il commit del suo lockfile",
|
|
14538
|
+
yarn_v1_unsupported: "passa a Yarn 2 o successivo, npm o pnpm",
|
|
14539
|
+
partial_dependency_graph: "fissa su una versione pubblicata ci\xF2 che viene da git, da un percorso locale o da un URL, dove puoi",
|
|
14540
|
+
ambiguous_dependency_spec: "fissa versioni esatte (== in requirements.txt) o esegui il commit di un lockfile",
|
|
14541
|
+
unsupported_lockfile: "rigeneralo in un formato che Sentinello legge: npm install con npm 7 o successivo, oppure bun install --save-text-lockfile"
|
|
14542
|
+
},
|
|
14543
|
+
"ja": {
|
|
14544
|
+
no_lockfile: "\u30D1\u30C3\u30B1\u30FC\u30B8\u30DE\u30CD\u30FC\u30B8\u30E3\u30FC\u304C\u751F\u6210\u3059\u308B lockfile \u3092\u30B3\u30DF\u30C3\u30C8\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
14545
|
+
unknown_pm: "package.json \u3067\u30D1\u30C3\u30B1\u30FC\u30B8\u30DE\u30CD\u30FC\u30B8\u30E3\u30FC\u3092\u6307\u5B9A\u3059\u308B\u304B\u3001\u305D\u306E lockfile \u3092\u30B3\u30DF\u30C3\u30C8\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
14546
|
+
yarn_v1_unsupported: "Yarn 2 \u4EE5\u964D\u3001npm\u3001pnpm \u306E\u3044\u305A\u308C\u304B\u306B\u79FB\u884C\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
14547
|
+
partial_dependency_graph: "git\u3001\u30ED\u30FC\u30AB\u30EB\u30D1\u30B9\u3001URL \u304B\u3089\u53D6\u5F97\u3057\u3066\u3044\u308B\u3082\u306E\u306F\u3001\u53EF\u80FD\u306A\u7BC4\u56F2\u3067\u516C\u958B\u6E08\u307F\u30D0\u30FC\u30B8\u30E7\u30F3\u306B\u56FA\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
14548
|
+
ambiguous_dependency_spec: "\u6B63\u78BA\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u56FA\u5B9A\u3059\u308B\uFF08requirements.txt \u306E ==\uFF09\u304B\u3001lockfile \u3092\u30B3\u30DF\u30C3\u30C8\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
14549
|
+
unsupported_lockfile: "Sentinello \u304C\u8AAD\u3081\u308B\u5F62\u5F0F\u3067\u518D\u751F\u6210\u3057\u3066\u304F\u3060\u3055\u3044: npm 7 \u4EE5\u964D\u306E npm install\u3001\u307E\u305F\u306F bun install --save-text-lockfile"
|
|
14550
|
+
},
|
|
14551
|
+
"zh-CN": {
|
|
14552
|
+
no_lockfile: "\u63D0\u4EA4\u5305\u7BA1\u7406\u5668\u751F\u6210\u7684 lockfile",
|
|
14553
|
+
unknown_pm: "\u5728 package.json \u4E2D\u6307\u660E\u5305\u7BA1\u7406\u5668\uFF0C\u6216\u63D0\u4EA4\u5176 lockfile",
|
|
14554
|
+
yarn_v1_unsupported: "\u8FC1\u79FB\u5230 Yarn 2 \u6216\u66F4\u9AD8\u7248\u672C\u3001npm \u6216 pnpm",
|
|
14555
|
+
partial_dependency_graph: "\u5C3D\u53EF\u80FD\u5C06\u6765\u81EA git\u3001\u672C\u5730\u8DEF\u5F84\u6216 URL \u7684\u4F9D\u8D56\u56FA\u5B9A\u5230\u5DF2\u53D1\u5E03\u7248\u672C",
|
|
14556
|
+
ambiguous_dependency_spec: "\u56FA\u5B9A\u786E\u5207\u7248\u672C\uFF08requirements.txt \u4E2D\u4F7F\u7528 ==\uFF09\u6216\u63D0\u4EA4 lockfile",
|
|
14557
|
+
unsupported_lockfile: "\u4EE5 Sentinello \u53EF\u8BFB\u7684\u683C\u5F0F\u91CD\u65B0\u751F\u6210\uFF1A\u4F7F\u7528 npm 7 \u6216\u66F4\u9AD8\u7248\u672C\u8FD0\u884C npm install\uFF0C\u6216\u8FD0\u884C bun install --save-text-lockfile"
|
|
14558
|
+
},
|
|
14559
|
+
"ko": {
|
|
14560
|
+
no_lockfile: "\uD328\uD0A4\uC9C0 \uAD00\uB9AC\uC790\uAC00 \uC0DD\uC131\uD558\uB294 lockfile\uC744 \uCEE4\uBC0B\uD558\uC138\uC694",
|
|
14561
|
+
unknown_pm: "package.json\uC5D0 \uD328\uD0A4\uC9C0 \uAD00\uB9AC\uC790\uB97C \uC9C0\uC815\uD558\uAC70\uB098 \uD574\uB2F9 lockfile\uC744 \uCEE4\uBC0B\uD558\uC138\uC694",
|
|
14562
|
+
yarn_v1_unsupported: "Yarn 2 \uC774\uC0C1, npm \uB610\uB294 pnpm\uC73C\uB85C \uC62E\uAE30\uC138\uC694",
|
|
14563
|
+
partial_dependency_graph: "git, \uB85C\uCEEC \uACBD\uB85C, URL\uC5D0\uC11C \uAC00\uC838\uC624\uB294 \uD56D\uBAA9\uC740 \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uAC8C\uC2DC\uB41C \uBC84\uC804\uC73C\uB85C \uACE0\uC815\uD558\uC138\uC694",
|
|
14564
|
+
ambiguous_dependency_spec: "\uC815\uD655\uD55C \uBC84\uC804\uC744 \uACE0\uC815\uD558\uAC70\uB098(requirements.txt\uC758 ==) lockfile\uC744 \uCEE4\uBC0B\uD558\uC138\uC694",
|
|
14565
|
+
unsupported_lockfile: "Sentinello\uAC00 \uC77D\uC744 \uC218 \uC788\uB294 \uD615\uC2DD\uC73C\uB85C \uB2E4\uC2DC \uC0DD\uC131\uD558\uC138\uC694: npm 7 \uC774\uC0C1\uC758 npm install \uB610\uB294 bun install --save-text-lockfile"
|
|
14566
|
+
},
|
|
14567
|
+
"ru": {
|
|
14568
|
+
no_lockfile: "\u0437\u0430\u043A\u043E\u043C\u043C\u0438\u0442\u044C\u0442\u0435 lockfile, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u043E\u0437\u0434\u0430\u0451\u0442 \u0432\u0430\u0448 \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440 \u043F\u0430\u043A\u0435\u0442\u043E\u0432",
|
|
14569
|
+
unknown_pm: "\u0443\u043A\u0430\u0436\u0438\u0442\u0435 \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440 \u043F\u0430\u043A\u0435\u0442\u043E\u0432 \u0432 package.json \u0438\u043B\u0438 \u0437\u0430\u043A\u043E\u043C\u043C\u0438\u0442\u044C\u0442\u0435 \u0435\u0433\u043E lockfile",
|
|
14570
|
+
yarn_v1_unsupported: "\u043F\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043D\u0430 Yarn 2 \u0438\u043B\u0438 \u043D\u043E\u0432\u0435\u0435, npm \u0438\u043B\u0438 pnpm",
|
|
14571
|
+
partial_dependency_graph: "\u043F\u043E \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438 \u0437\u0430\u043A\u0440\u0435\u043F\u0438\u0442\u0435 \u043D\u0430 \u043E\u043F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u043D\u043D\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0442\u043E, \u0447\u0442\u043E \u0431\u0435\u0440\u0451\u0442\u0441\u044F \u0438\u0437 git, \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043F\u0443\u0442\u0438 \u0438\u043B\u0438 URL",
|
|
14572
|
+
ambiguous_dependency_spec: "\u0437\u0430\u043A\u0440\u0435\u043F\u0438\u0442\u0435 \u0442\u043E\u0447\u043D\u044B\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 (== \u0432 requirements.txt) \u0438\u043B\u0438 \u0437\u0430\u043A\u043E\u043C\u043C\u0438\u0442\u044C\u0442\u0435 lockfile",
|
|
14573
|
+
unsupported_lockfile: "\u0441\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u0435\u0433\u043E \u0437\u0430\u043D\u043E\u0432\u043E \u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0435, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 Sentinello: npm install \u0441 npm 7 \u0438\u043B\u0438 \u043D\u043E\u0432\u0435\u0435 \u043B\u0438\u0431\u043E bun install --save-text-lockfile"
|
|
14574
|
+
}
|
|
14575
|
+
};
|
|
14576
|
+
function reasonFixHint(code, locale = "en") {
|
|
14577
|
+
return REASON_FIX_HINTS[locale][code] ?? null;
|
|
14578
|
+
}
|
|
14579
|
+
|
|
14463
14580
|
// ../../packages/core/src/scan-state-text.ts
|
|
14464
14581
|
function scanReasonLabel(reason, locale = "en") {
|
|
14465
14582
|
if (reason.reasonCode === "not_yet_run") return NOT_YET_RUN_LABELS[locale];
|
|
@@ -14469,7 +14586,7 @@ function labelScanState(state, locale = "en") {
|
|
|
14469
14586
|
return {
|
|
14470
14587
|
state: state.state,
|
|
14471
14588
|
reasons: state.reasons.map(function labelled(reason) {
|
|
14472
|
-
return { ...reason, label: scanReasonLabel(reason, locale) };
|
|
14589
|
+
return { ...reason, label: scanReasonLabel(reason, locale), fixHint: reasonFixHint(reason.reasonCode, locale) };
|
|
14473
14590
|
})
|
|
14474
14591
|
};
|
|
14475
14592
|
}
|
|
@@ -14503,14 +14620,15 @@ function groupScanReasons(reasons, locale = "en") {
|
|
|
14503
14620
|
if (!group.subjects.includes(subject)) group.subjects.push(subject);
|
|
14504
14621
|
continue;
|
|
14505
14622
|
}
|
|
14506
|
-
out.push({ reasonCode: reason.reasonCode, side: reason.side, label: scanReasonLabel(reason, locale), subjects: [subject] });
|
|
14623
|
+
out.push({ reasonCode: reason.reasonCode, side: reason.side, label: scanReasonLabel(reason, locale), subjects: [subject], fixHint: reasonFixHint(reason.reasonCode, locale) });
|
|
14507
14624
|
}
|
|
14508
14625
|
return out;
|
|
14509
14626
|
}
|
|
14510
|
-
function describeScanReasons(reasons, locale = "en") {
|
|
14627
|
+
function describeScanReasons(reasons, locale = "en", withFix = false) {
|
|
14511
14628
|
return groupScanReasons(reasons, locale).map(function line(g) {
|
|
14512
14629
|
if (g.side === null) return g.subjects.join(", ") + ": " + g.label;
|
|
14513
|
-
|
|
14630
|
+
const whose = g.label + " (" + SCAN_STATE_SIDE_SHORT[g.side] + ")";
|
|
14631
|
+
return withFix && g.fixHint !== null ? whose + ": " + g.fixHint : whose;
|
|
14514
14632
|
}).join(" \xB7 ");
|
|
14515
14633
|
}
|
|
14516
14634
|
function describeGroupedReasonLong(group) {
|
|
@@ -14531,9 +14649,9 @@ function asError(err) {
|
|
|
14531
14649
|
// ../../packages/core/src/advisory-rows.ts
|
|
14532
14650
|
var OSV_NORMALIZER_VERSIONS = {
|
|
14533
14651
|
npm: 8,
|
|
14534
|
-
PyPI:
|
|
14652
|
+
PyPI: 9,
|
|
14535
14653
|
Go: 8,
|
|
14536
|
-
"crates.io":
|
|
14654
|
+
"crates.io": 9,
|
|
14537
14655
|
RubyGems: 8
|
|
14538
14656
|
};
|
|
14539
14657
|
function osvNormalizerVersion(ecosystem) {
|
|
@@ -14659,7 +14777,7 @@ function escapeForMarkdown(value) {
|
|
|
14659
14777
|
}
|
|
14660
14778
|
function formatFinding(index, f) {
|
|
14661
14779
|
const lines = [];
|
|
14662
|
-
const headline = "`" + escapeForMarkdown(f.packageName) + "@" + escapeForMarkdown(f.installedVersion) + "` \u2014 " + f.severity;
|
|
14780
|
+
const headline = "`" + escapeForMarkdown(f.packageName) + "@" + escapeForMarkdown(f.installedVersion) + "` \u2014 " + (f.noticeKind ? "notice: " + f.noticeKind : f.severity);
|
|
14663
14781
|
lines.push("### " + index + ". " + headline);
|
|
14664
14782
|
lines.push("");
|
|
14665
14783
|
lines.push("- **Ecosystem:** " + ecosystemLabel(f.ecosystem));
|
|
@@ -14736,8 +14854,16 @@ function wayOutLines(ecosystem, r, notRechecked) {
|
|
|
14736
14854
|
for (const a of text.alternatives) lines.push(" - **Alternatives:** " + a);
|
|
14737
14855
|
return lines;
|
|
14738
14856
|
}
|
|
14857
|
+
function isNotice(f) {
|
|
14858
|
+
return Boolean(f.noticeKind);
|
|
14859
|
+
}
|
|
14860
|
+
function countNotices(findings) {
|
|
14861
|
+
return findings.filter(isNotice).length;
|
|
14862
|
+
}
|
|
14739
14863
|
function sortForExport(findings) {
|
|
14740
14864
|
return [...findings].sort(function bySeverityThenName(a, b) {
|
|
14865
|
+
const kind = Number(isNotice(a)) - Number(isNotice(b));
|
|
14866
|
+
if (kind !== 0) return kind;
|
|
14741
14867
|
const sev = compareSeverity(a.severity, b.severity);
|
|
14742
14868
|
if (sev !== 0) return sev;
|
|
14743
14869
|
const nameCmp = a.packageName.localeCompare(b.packageName);
|
|
@@ -14745,13 +14871,14 @@ function sortForExport(findings) {
|
|
|
14745
14871
|
return a.advisoryId.localeCompare(b.advisoryId);
|
|
14746
14872
|
});
|
|
14747
14873
|
}
|
|
14748
|
-
function buildHeader(scope, generatedAt, count2, range) {
|
|
14874
|
+
function buildHeader(scope, generatedAt, count2, range, notices) {
|
|
14749
14875
|
const title = "Sentinello advisory export \u2014 " + scopeTitle(scope);
|
|
14750
14876
|
const subtitleParts = [];
|
|
14751
14877
|
subtitleParts.push("Generated " + new Date(generatedAt).toISOString());
|
|
14752
14878
|
{
|
|
14753
14879
|
subtitleParts.push(count2 + " " + (count2 === 1 ? "finding" : "findings"));
|
|
14754
14880
|
}
|
|
14881
|
+
if (notices > 0) subtitleParts.push(notices + " " + (notices === 1 ? "notice" : "notices") + ", not vulnerabilities");
|
|
14755
14882
|
if (scope.kind === "project") {
|
|
14756
14883
|
subtitleParts.push("project: `" + escapeForMarkdown(scope.projectPath) + "`");
|
|
14757
14884
|
} else if (scope.kind === "library") {
|
|
@@ -14803,12 +14930,21 @@ function buildFindingsSection(findings, startIndex) {
|
|
|
14803
14930
|
const out = [];
|
|
14804
14931
|
out.push("## Findings");
|
|
14805
14932
|
out.push("");
|
|
14806
|
-
if (findings.
|
|
14933
|
+
if (!findings.some(function vulnerability(f) {
|
|
14934
|
+
return !isNotice(f);
|
|
14935
|
+
})) {
|
|
14807
14936
|
out.push("_No current findings._");
|
|
14808
14937
|
out.push("");
|
|
14809
|
-
return out;
|
|
14810
14938
|
}
|
|
14939
|
+
let noticesStarted = false;
|
|
14811
14940
|
findings.forEach(function appendFinding(f, i) {
|
|
14941
|
+
if (isNotice(f) && !noticesStarted) {
|
|
14942
|
+
noticesStarted = true;
|
|
14943
|
+
out.push("## Notices");
|
|
14944
|
+
out.push("");
|
|
14945
|
+
out.push("Not vulnerabilities: the advisory says the package is unmaintained, unsound or worth knowing about, and there is no fix version to chase. Weigh them when you next touch the dependency.");
|
|
14946
|
+
out.push("");
|
|
14947
|
+
}
|
|
14812
14948
|
out.push(formatFinding(startIndex + i + 1, f));
|
|
14813
14949
|
out.push("");
|
|
14814
14950
|
});
|
|
@@ -14817,7 +14953,8 @@ function buildFindingsSection(findings, startIndex) {
|
|
|
14817
14953
|
function buildAdvisoryMarkdown(args) {
|
|
14818
14954
|
const { scope, prompt, findings, generatedAt } = args;
|
|
14819
14955
|
const sorted = sortForExport(findings);
|
|
14820
|
-
const
|
|
14956
|
+
const notices = countNotices(sorted);
|
|
14957
|
+
const out = buildHeader(scope, generatedAt, sorted.length - notices, null, notices).concat(buildPromptSection(prompt)).concat(buildScanStateSection(args.scanStates ?? [])).concat(buildFindingsSection(sorted, 0));
|
|
14821
14958
|
return out.join("\n");
|
|
14822
14959
|
}
|
|
14823
14960
|
function buildExportFilename(scope, generatedAt) {
|
|
@@ -34766,8 +34903,8 @@ function evaluableContains(ev, version2) {
|
|
|
34766
34903
|
|
|
34767
34904
|
// ../../packages/scanners/src/npm-audit-parse.ts
|
|
34768
34905
|
var NPM_AUDIT_SCANNER_NAME = "npm-audit";
|
|
34769
|
-
var SEVERITY_VALUES = ["critical", "high", "moderate", "low", "info"];
|
|
34770
|
-
var severitySchema = external_exports.enum(SEVERITY_VALUES).catch("
|
|
34906
|
+
var SEVERITY_VALUES = ["critical", "high", "moderate", "unrated", "low", "info"];
|
|
34907
|
+
var severitySchema = external_exports.enum(SEVERITY_VALUES).catch("unrated");
|
|
34771
34908
|
var viaObjectSchema = external_exports.object({
|
|
34772
34909
|
source: external_exports.number().int().optional(),
|
|
34773
34910
|
name: external_exports.string().optional(),
|
|
@@ -34952,7 +35089,7 @@ function pickAdvisoryAliases(advisoryId, url2, githubAdvisoryId) {
|
|
|
34952
35089
|
function pickSeverity(via, vuln) {
|
|
34953
35090
|
if (via.severity) return via.severity;
|
|
34954
35091
|
if (vuln.severity) return vuln.severity;
|
|
34955
|
-
return "
|
|
35092
|
+
return "unrated";
|
|
34956
35093
|
}
|
|
34957
35094
|
function pickFixAvailability(fix) {
|
|
34958
35095
|
if (fix === void 0 || fix === false) return { fixAvailable: false, fixVersion: null, fixName: null };
|
|
@@ -35074,7 +35211,7 @@ function normalizePnpmAuditOutput(parsed, classifier) {
|
|
|
35074
35211
|
const adv = advisories[idKey];
|
|
35075
35212
|
if (!adv) continue;
|
|
35076
35213
|
const advisoryId = pickPnpmAdvisoryId(adv, idKey);
|
|
35077
|
-
const severity = adv.severity || "
|
|
35214
|
+
const severity = adv.severity || "unrated";
|
|
35078
35215
|
const patched = adv.patched_versions || null;
|
|
35079
35216
|
const recommendation = adv.recommendation || null;
|
|
35080
35217
|
const vulnRange = adv.vulnerable_versions || "";
|
|
@@ -35793,6 +35930,141 @@ function unauditable(details) {
|
|
|
35793
35930
|
return { status: "unauditable", ecosystem: GO_ECOSYSTEM, reasonCode: "ambiguous_dependency_spec", details };
|
|
35794
35931
|
}
|
|
35795
35932
|
var NPM_ECOSYSTEM = "npm";
|
|
35933
|
+
async function parseBunLock(absolutePath, manifestPath) {
|
|
35934
|
+
let doc;
|
|
35935
|
+
try {
|
|
35936
|
+
doc = parseJsonc(await promises.readFile(absolutePath, "utf8"));
|
|
35937
|
+
} catch {
|
|
35938
|
+
return { status: "unauditable", ecosystem: NPM_ECOSYSTEM, reasonCode: "unsupported_lockfile", details: ["could not read " + manifestPath] };
|
|
35939
|
+
}
|
|
35940
|
+
const packages = recordOf(recordOf(doc).packages);
|
|
35941
|
+
const workspaces = recordOf(recordOf(doc).workspaces);
|
|
35942
|
+
const entries = /* @__PURE__ */ new Map();
|
|
35943
|
+
const cannotAudit = [];
|
|
35944
|
+
for (const key of Object.keys(packages)) {
|
|
35945
|
+
const entry = readEntry(key, packages[key]);
|
|
35946
|
+
if (entry === null) cannotAudit.push(key);
|
|
35947
|
+
else if (!entry.spec.startsWith("workspace:")) entries.set(key, entry);
|
|
35948
|
+
}
|
|
35949
|
+
const nodes = [];
|
|
35950
|
+
const edges = [];
|
|
35951
|
+
const auditable = /* @__PURE__ */ new Set();
|
|
35952
|
+
for (const entry of entries.values()) {
|
|
35953
|
+
nodes.push({ id: entry.key, name: entry.name, version: entry.spec });
|
|
35954
|
+
if (entry.spec.includes(":")) cannotAudit.push(entry.name + "@" + entry.spec);
|
|
35955
|
+
else auditable.add(entry.key);
|
|
35956
|
+
const chain = packageChain(entry.key);
|
|
35957
|
+
addEdges(entry.key, chain, entry.meta.dependencies, "prod", entries, edges);
|
|
35958
|
+
addEdges(entry.key, chain, entry.meta.optionalDependencies, "optional", entries, edges);
|
|
35959
|
+
addEdges(entry.key, chain, entry.meta.peerDependencies, "peer", entries, edges);
|
|
35960
|
+
}
|
|
35961
|
+
const roots = [];
|
|
35962
|
+
for (const path of Object.keys(workspaces)) {
|
|
35963
|
+
const workspace = recordOf(workspaces[path]);
|
|
35964
|
+
const importer = path === "" ? "." : path;
|
|
35965
|
+
const chain = typeof workspace.name === "string" ? [workspace.name] : [];
|
|
35966
|
+
addRoots(importer, chain, workspace.dependencies, "prod", entries, roots);
|
|
35967
|
+
addRoots(importer, chain, workspace.peerDependencies, "prod", entries, roots);
|
|
35968
|
+
addRoots(importer, chain, workspace.optionalDependencies, "optional", entries, roots);
|
|
35969
|
+
addRoots(importer, chain, workspace.devDependencies, "dev", entries, roots);
|
|
35970
|
+
}
|
|
35971
|
+
const graph = graphFromLock({
|
|
35972
|
+
ecosystem: NPM_ECOSYSTEM,
|
|
35973
|
+
manifestPath,
|
|
35974
|
+
nodes,
|
|
35975
|
+
edges,
|
|
35976
|
+
roots,
|
|
35977
|
+
auditable(nodeId) {
|
|
35978
|
+
return auditable.has(nodeId);
|
|
35979
|
+
}
|
|
35980
|
+
});
|
|
35981
|
+
if (cannotAudit.length === 0) return { status: "ok", ecosystem: NPM_ECOSYSTEM, graph };
|
|
35982
|
+
return {
|
|
35983
|
+
status: "partial",
|
|
35984
|
+
ecosystem: NPM_ECOSYSTEM,
|
|
35985
|
+
graph,
|
|
35986
|
+
reasonCode: "partial_dependency_graph",
|
|
35987
|
+
details: [cannotAudit.length + " packages from git, local path or URL sources cannot be audited: " + cannotAudit.sort().join(", ")]
|
|
35988
|
+
};
|
|
35989
|
+
}
|
|
35990
|
+
function readEntry(key, value) {
|
|
35991
|
+
if (!Array.isArray(value) || typeof value[0] !== "string") return null;
|
|
35992
|
+
const at = value[0].indexOf("@", 1);
|
|
35993
|
+
if (at < 0 || at === value[0].length - 1) return null;
|
|
35994
|
+
const meta3 = value.slice(1).find(function isMeta(part) {
|
|
35995
|
+
return part !== null && typeof part === "object" && !Array.isArray(part);
|
|
35996
|
+
});
|
|
35997
|
+
return { key, name: value[0].slice(0, at), spec: value[0].slice(at + 1), meta: meta3 ?? {} };
|
|
35998
|
+
}
|
|
35999
|
+
function packageChain(key) {
|
|
36000
|
+
const chain = [];
|
|
36001
|
+
const parts = key.split("/");
|
|
36002
|
+
for (let i = 0; i < parts.length; i++) {
|
|
36003
|
+
const part = parts[i];
|
|
36004
|
+
if (part.startsWith("@") && i + 1 < parts.length) {
|
|
36005
|
+
chain.push(part + "/" + parts[i + 1]);
|
|
36006
|
+
i += 1;
|
|
36007
|
+
} else {
|
|
36008
|
+
chain.push(part);
|
|
36009
|
+
}
|
|
36010
|
+
}
|
|
36011
|
+
return chain;
|
|
36012
|
+
}
|
|
36013
|
+
function resolveFrom(chain, child, entries) {
|
|
36014
|
+
for (let depth = chain.length; depth >= 0; depth--) {
|
|
36015
|
+
const key = [...chain.slice(0, depth), child].join("/");
|
|
36016
|
+
if (entries.has(key)) return key;
|
|
36017
|
+
}
|
|
36018
|
+
return null;
|
|
36019
|
+
}
|
|
36020
|
+
function addEdges(from, chain, deps, kind, entries, out) {
|
|
36021
|
+
for (const child of Object.keys(deps ?? {})) {
|
|
36022
|
+
const to = resolveFrom(chain, child, entries);
|
|
36023
|
+
if (to !== null) out.push({ from, to, kind });
|
|
36024
|
+
}
|
|
36025
|
+
}
|
|
36026
|
+
function addRoots(importer, chain, deps, kind, entries, out) {
|
|
36027
|
+
for (const child of Object.keys(deps ?? {})) {
|
|
36028
|
+
const nodeId = resolveFrom(chain, child, entries);
|
|
36029
|
+
if (nodeId !== null) out.push({ importer, nodeId, kind });
|
|
36030
|
+
}
|
|
36031
|
+
}
|
|
36032
|
+
function recordOf(value) {
|
|
36033
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
36034
|
+
}
|
|
36035
|
+
function parseJsonc(text) {
|
|
36036
|
+
let out = "";
|
|
36037
|
+
let i = 0;
|
|
36038
|
+
while (i < text.length) {
|
|
36039
|
+
const c = text[i];
|
|
36040
|
+
if (c === '"') {
|
|
36041
|
+
const end = stringEnd(text, i);
|
|
36042
|
+
out += text.slice(i, end);
|
|
36043
|
+
i = end;
|
|
36044
|
+
} else if (c === "/" && text[i + 1] === "/") {
|
|
36045
|
+
const newline = text.indexOf("\n", i);
|
|
36046
|
+
i = newline < 0 ? text.length : newline;
|
|
36047
|
+
} else if (c === "/" && text[i + 1] === "*") {
|
|
36048
|
+
const close = text.indexOf("*/", i + 2);
|
|
36049
|
+
i = close < 0 ? text.length : close + 2;
|
|
36050
|
+
} else {
|
|
36051
|
+
if (c === "}" || c === "]") out = out.replace(/,\s*$/, "");
|
|
36052
|
+
out += c;
|
|
36053
|
+
i += 1;
|
|
36054
|
+
}
|
|
36055
|
+
}
|
|
36056
|
+
return JSON.parse(out);
|
|
36057
|
+
}
|
|
36058
|
+
function stringEnd(text, start) {
|
|
36059
|
+
let i = start + 1;
|
|
36060
|
+
while (i < text.length) {
|
|
36061
|
+
if (text[i] === "\\") i += 2;
|
|
36062
|
+
else if (text[i] === '"') return i + 1;
|
|
36063
|
+
else i += 1;
|
|
36064
|
+
}
|
|
36065
|
+
return text.length;
|
|
36066
|
+
}
|
|
36067
|
+
var NPM_ECOSYSTEM2 = "npm";
|
|
35796
36068
|
async function parseNpmLock(projectPath, absolutePath, manifestPath) {
|
|
35797
36069
|
let text;
|
|
35798
36070
|
try {
|
|
@@ -35808,6 +36080,7 @@ async function parseNpmLock(projectPath, absolutePath, manifestPath) {
|
|
|
35808
36080
|
}
|
|
35809
36081
|
if (!parsed || typeof parsed !== "object") return null;
|
|
35810
36082
|
const doc = parsed;
|
|
36083
|
+
if (doc.lockfileVersion === 1) return null;
|
|
35811
36084
|
const packages = doc.packages || {};
|
|
35812
36085
|
const direct = await readDirectDeps(projectPath);
|
|
35813
36086
|
const out = [];
|
|
@@ -35823,7 +36096,7 @@ async function parseNpmLock(projectPath, absolutePath, manifestPath) {
|
|
|
35823
36096
|
if (direct.prod.has(name)) isProd = true;
|
|
35824
36097
|
if (direct.dev.has(name)) isDev = true;
|
|
35825
36098
|
out.push({
|
|
35826
|
-
ecosystem:
|
|
36099
|
+
ecosystem: NPM_ECOSYSTEM2,
|
|
35827
36100
|
name,
|
|
35828
36101
|
version: entry.version,
|
|
35829
36102
|
scope: { isProd, isDev, isOptional: entry.optional === true || entry.devOptional === true },
|
|
@@ -35833,6 +36106,13 @@ async function parseNpmLock(projectPath, absolutePath, manifestPath) {
|
|
|
35833
36106
|
}
|
|
35834
36107
|
return makeGraph(out, doc.packages ? buildNodeGraph(packages) : null);
|
|
35835
36108
|
}
|
|
36109
|
+
async function isNpmLockV1(absolutePath) {
|
|
36110
|
+
try {
|
|
36111
|
+
return JSON.parse(await promises.readFile(absolutePath, "utf8"))?.lockfileVersion === 1;
|
|
36112
|
+
} catch {
|
|
36113
|
+
return false;
|
|
36114
|
+
}
|
|
36115
|
+
}
|
|
35836
36116
|
function buildNodeGraph(packages) {
|
|
35837
36117
|
const nodes = [];
|
|
35838
36118
|
const edges = [];
|
|
@@ -35842,37 +36122,37 @@ function buildNodeGraph(packages) {
|
|
|
35842
36122
|
if (!entry) continue;
|
|
35843
36123
|
if (!isNodePath(path)) {
|
|
35844
36124
|
const importer = path === "" ? "." : path;
|
|
35845
|
-
|
|
35846
|
-
|
|
35847
|
-
|
|
35848
|
-
|
|
36125
|
+
addRoots2(importer, path, entry.dependencies, "prod", packages, roots);
|
|
36126
|
+
addRoots2(importer, path, entry.peerDependencies, "prod", packages, roots);
|
|
36127
|
+
addRoots2(importer, path, entry.optionalDependencies, "optional", packages, roots);
|
|
36128
|
+
addRoots2(importer, path, entry.devDependencies, "dev", packages, roots);
|
|
35849
36129
|
continue;
|
|
35850
36130
|
}
|
|
35851
36131
|
const name = entry.name || nameFromNodePath(path);
|
|
35852
36132
|
if (entry.link === true || !entry.version || !name) continue;
|
|
35853
36133
|
nodes.push({ id: path, name, version: entry.version });
|
|
35854
|
-
|
|
35855
|
-
|
|
35856
|
-
|
|
36134
|
+
addEdges2(path, entry.dependencies, "prod", packages, edges);
|
|
36135
|
+
addEdges2(path, entry.optionalDependencies, "optional", packages, edges);
|
|
36136
|
+
addEdges2(path, entry.peerDependencies, "peer", packages, edges);
|
|
35857
36137
|
}
|
|
35858
36138
|
return { nodes, edges, roots };
|
|
35859
36139
|
}
|
|
35860
36140
|
function isNodePath(path) {
|
|
35861
36141
|
return path.startsWith("node_modules/") || path.includes("/node_modules/");
|
|
35862
36142
|
}
|
|
35863
|
-
function
|
|
36143
|
+
function addRoots2(importer, from, deps, kind, packages, out) {
|
|
35864
36144
|
for (const child of Object.keys(deps || {})) {
|
|
35865
|
-
const nodeId =
|
|
36145
|
+
const nodeId = resolveFrom2(from, child, packages);
|
|
35866
36146
|
if (nodeId !== null) out.push({ importer, nodeId, kind });
|
|
35867
36147
|
}
|
|
35868
36148
|
}
|
|
35869
|
-
function
|
|
36149
|
+
function addEdges2(from, deps, kind, packages, out) {
|
|
35870
36150
|
for (const child of Object.keys(deps || {})) {
|
|
35871
|
-
const to =
|
|
36151
|
+
const to = resolveFrom2(from, child, packages);
|
|
35872
36152
|
if (to !== null) out.push({ from, to, kind });
|
|
35873
36153
|
}
|
|
35874
36154
|
}
|
|
35875
|
-
function
|
|
36155
|
+
function resolveFrom2(location, child, packages) {
|
|
35876
36156
|
let base = location;
|
|
35877
36157
|
for (; ; ) {
|
|
35878
36158
|
const candidate = (base === "" ? "" : base + "/") + "node_modules/" + child;
|
|
@@ -38990,7 +39270,7 @@ var {
|
|
|
38990
39270
|
} = yaml;
|
|
38991
39271
|
|
|
38992
39272
|
// ../../packages/scanners/src/resolver/pnpm.ts
|
|
38993
|
-
var
|
|
39273
|
+
var NPM_ECOSYSTEM3 = "npm";
|
|
38994
39274
|
async function parsePnpmLock(absolutePath, manifestPath) {
|
|
38995
39275
|
let text;
|
|
38996
39276
|
try {
|
|
@@ -39063,7 +39343,7 @@ function parsePnpmV9(root, manifestPath) {
|
|
|
39063
39343
|
existing.depPaths.push(key);
|
|
39064
39344
|
} else {
|
|
39065
39345
|
byId.set(id, {
|
|
39066
|
-
ecosystem:
|
|
39346
|
+
ecosystem: NPM_ECOSYSTEM3,
|
|
39067
39347
|
name: parsed.name,
|
|
39068
39348
|
version: parsed.version,
|
|
39069
39349
|
scope: { isProd, isDev, isOptional },
|
|
@@ -39094,7 +39374,7 @@ function parsePnpmLegacy(root, manifestPath) {
|
|
|
39094
39374
|
const version2 = entry.version || parsed.version;
|
|
39095
39375
|
const isDev = entry.dev === true;
|
|
39096
39376
|
out.push({
|
|
39097
|
-
ecosystem:
|
|
39377
|
+
ecosystem: NPM_ECOSYSTEM3,
|
|
39098
39378
|
name: parsed.name,
|
|
39099
39379
|
version: version2,
|
|
39100
39380
|
scope: { isProd: !isDev, isDev, isOptional: entry.optional === true },
|
|
@@ -39825,6 +40105,16 @@ function unauditable3(reasonCode, details) {
|
|
|
39825
40105
|
var CRATES_ECOSYSTEM = "crates.io";
|
|
39826
40106
|
var CRATES_IO_SOURCES = ["registry+https://github.com/rust-lang/crates.io-index", "sparse+https://index.crates.io/"];
|
|
39827
40107
|
var MAX_MANIFESTS = 1e3;
|
|
40108
|
+
function ownCratesOfLock(text) {
|
|
40109
|
+
return parseArrayOfTables(text, "package").flatMap(function ownName(t) {
|
|
40110
|
+
const name = tomlString(t.name);
|
|
40111
|
+
const source = tomlString(t.source);
|
|
40112
|
+
return name !== null && (source === null || source.length === 0) ? [name] : [];
|
|
40113
|
+
});
|
|
40114
|
+
}
|
|
40115
|
+
function crateNameOfManifest(text) {
|
|
40116
|
+
return tomlString(tomlTable(parseTomlDocument(text).package)?.name);
|
|
40117
|
+
}
|
|
39828
40118
|
async function parseCargoLock(projectPath, absolutePath, manifestPath) {
|
|
39829
40119
|
let text;
|
|
39830
40120
|
try {
|
|
@@ -40196,11 +40486,19 @@ async function resolveManifest(projectPath, manifest) {
|
|
|
40196
40486
|
if (lockless !== null) return { status: "unauditable", ecosystem, reasonCode: "no_lockfile", details: [lockless] };
|
|
40197
40487
|
if (ecosystem === "npm") {
|
|
40198
40488
|
if (kind === "package-lock.json") {
|
|
40199
|
-
|
|
40489
|
+
const graph = await parseNpmLock(projectPath, absolutePath, manifestPath);
|
|
40490
|
+
if (graph === null && await isNpmLockV1(absolutePath)) {
|
|
40491
|
+
return { status: "unauditable", ecosystem, reasonCode: "unsupported_lockfile", details: [manifestPath + " is lockfileVersion 1, which lists no packages to read: run npm install with npm 7 or later to upgrade it"] };
|
|
40492
|
+
}
|
|
40493
|
+
return wrapNpm(ecosystem, graph, kind);
|
|
40200
40494
|
}
|
|
40201
40495
|
if (kind === "pnpm-lock.yaml") {
|
|
40202
40496
|
return wrapNpm(ecosystem, await parsePnpmLock(absolutePath, manifestPath), kind);
|
|
40203
40497
|
}
|
|
40498
|
+
if (kind === "bun.lock") return parseBunLock(absolutePath, manifestPath);
|
|
40499
|
+
if (kind === "bun.lockb") {
|
|
40500
|
+
return { status: "unauditable", ecosystem, reasonCode: "unsupported_lockfile", details: [manifestPath + " is Bun's binary lockfile, which cannot be read: run bun install --save-text-lockfile to write bun.lock"] };
|
|
40501
|
+
}
|
|
40204
40502
|
return { status: "unauditable", ecosystem, reasonCode: "unsupported_lockfile", details: [kind + " is not a supported JavaScript lockfile format"] };
|
|
40205
40503
|
}
|
|
40206
40504
|
if (ecosystem === "PyPI") return parsePythonLock(projectPath, kind, absolutePath, manifestPath);
|
|
@@ -40255,7 +40553,9 @@ var import_ignore = __toESM(require_ignore());
|
|
|
40255
40553
|
var LOCKFILE_TO_PM = {
|
|
40256
40554
|
"pnpm-lock.yaml": "pnpm",
|
|
40257
40555
|
"package-lock.json": "npm",
|
|
40258
|
-
"yarn.lock": "yarn"
|
|
40556
|
+
"yarn.lock": "yarn",
|
|
40557
|
+
"bun.lock": "bun",
|
|
40558
|
+
"bun.lockb": "bun"
|
|
40259
40559
|
};
|
|
40260
40560
|
var ALWAYS_SKIP = /* @__PURE__ */ new Set(["node_modules", ".git"]);
|
|
40261
40561
|
var MANIFEST_SKIP = /* @__PURE__ */ new Set(["node_modules", "vendor", ".venv", "venv", "target", "Pods", "build", "dist"]);
|
|
@@ -40277,6 +40577,7 @@ function discoverProjectsInTree(options) {
|
|
|
40277
40577
|
excludeMatcher,
|
|
40278
40578
|
hasExcludes: Boolean(options.excludes && options.excludes.length > 0),
|
|
40279
40579
|
layers,
|
|
40580
|
+
readIgnoreFiles: true,
|
|
40280
40581
|
onSkip: options.onSkip,
|
|
40281
40582
|
onError: options.onError,
|
|
40282
40583
|
ecosystems,
|
|
@@ -40296,7 +40597,7 @@ function walk(state) {
|
|
|
40296
40597
|
const manifestsOff = owner === state.owner && state.manifestsOff;
|
|
40297
40598
|
if (owner?.npm && state.subEcosystems.length === 0) return;
|
|
40298
40599
|
if (state.maxDepth !== null && state.depth >= state.maxDepth) return;
|
|
40299
|
-
const localLayer = loadIgnoreLayer(state.currentDir);
|
|
40600
|
+
const localLayer = state.readIgnoreFiles ? loadIgnoreLayer(state.currentDir) : null;
|
|
40300
40601
|
const layers = localLayer ? state.layers.concat([localLayer]) : state.layers;
|
|
40301
40602
|
for (const entry of readEntries(state.currentDir, state.onError)) {
|
|
40302
40603
|
if (!entry.isDirectory()) continue;
|
|
@@ -40360,6 +40661,7 @@ function addManifests(project, found) {
|
|
|
40360
40661
|
}
|
|
40361
40662
|
}
|
|
40362
40663
|
function finishProject(project, ecosystems) {
|
|
40664
|
+
project.manifests = withoutLockedCrates(project);
|
|
40363
40665
|
project.manifests.sort(function byDirectory(a, b) {
|
|
40364
40666
|
return manifestDirOf(a.path).localeCompare(manifestDirOf(b.path));
|
|
40365
40667
|
});
|
|
@@ -40371,6 +40673,30 @@ function finishProject(project, ecosystems) {
|
|
|
40371
40673
|
return eco.id;
|
|
40372
40674
|
});
|
|
40373
40675
|
}
|
|
40676
|
+
function withoutLockedCrates(project) {
|
|
40677
|
+
const bare = project.manifests.filter(function isBare(m) {
|
|
40678
|
+
return m.kind === "Cargo.toml";
|
|
40679
|
+
});
|
|
40680
|
+
if (bare.length === 0) return project.manifests;
|
|
40681
|
+
const locked = /* @__PURE__ */ new Set();
|
|
40682
|
+
for (const m of project.manifests) {
|
|
40683
|
+
if (m.kind !== "Cargo.lock") continue;
|
|
40684
|
+
for (const name of ownCratesOfLock(readFileOrEmpty(path.join(project.absolutePath, m.path)))) locked.add(name);
|
|
40685
|
+
}
|
|
40686
|
+
if (locked.size === 0) return project.manifests;
|
|
40687
|
+
return project.manifests.filter(function uncovered(m) {
|
|
40688
|
+
if (m.kind !== "Cargo.toml") return true;
|
|
40689
|
+
const name = crateNameOfManifest(readFileOrEmpty(path.join(project.absolutePath, m.path)));
|
|
40690
|
+
return name === null || !locked.has(name);
|
|
40691
|
+
});
|
|
40692
|
+
}
|
|
40693
|
+
function readFileOrEmpty(path) {
|
|
40694
|
+
try {
|
|
40695
|
+
return fs.readFileSync(path, "utf8");
|
|
40696
|
+
} catch {
|
|
40697
|
+
return "";
|
|
40698
|
+
}
|
|
40699
|
+
}
|
|
40374
40700
|
function isNpm(eco) {
|
|
40375
40701
|
return eco.id === "npm";
|
|
40376
40702
|
}
|
|
@@ -40628,7 +40954,8 @@ function buildFinding(pkg2, advisory, severity, fixVersion, vulnerableRange, aff
|
|
|
40628
40954
|
depPath: pkg2.depPaths,
|
|
40629
40955
|
isProd: pkg2.scope.isProd,
|
|
40630
40956
|
isDev: pkg2.scope.isDev,
|
|
40631
|
-
aliases: advisory.aliases
|
|
40957
|
+
aliases: advisory.aliases,
|
|
40958
|
+
noticeKind: advisory.noticeKind ?? null
|
|
40632
40959
|
};
|
|
40633
40960
|
}
|
|
40634
40961
|
function rangesToDisplay(ranges, exactVersions) {
|
|
@@ -40638,14 +40965,14 @@ function rangesToDisplay(ranges, exactVersions) {
|
|
|
40638
40965
|
return parts.join(" || ");
|
|
40639
40966
|
}
|
|
40640
40967
|
function mapSeverity(severity) {
|
|
40641
|
-
if (!severity) return "
|
|
40968
|
+
if (!severity) return "unrated";
|
|
40642
40969
|
const s = String(severity).trim().toLowerCase();
|
|
40643
40970
|
if (s === "critical") return "critical";
|
|
40644
40971
|
if (s === "high") return "high";
|
|
40645
40972
|
if (s === "moderate" || s === "medium") return "moderate";
|
|
40646
40973
|
if (s === "low") return "low";
|
|
40647
40974
|
if (s === "info" || s === "none") return "info";
|
|
40648
|
-
return "
|
|
40975
|
+
return "unrated";
|
|
40649
40976
|
}
|
|
40650
40977
|
|
|
40651
40978
|
// ../../packages/scanners/src/osv.ts
|
|
@@ -40680,7 +41007,13 @@ function createOsvScanner(deps) {
|
|
|
40680
41007
|
durationMs: Date.now() - startedAt
|
|
40681
41008
|
};
|
|
40682
41009
|
}
|
|
40683
|
-
return {
|
|
41010
|
+
return {
|
|
41011
|
+
name: OSV_SCANNER_NAME,
|
|
41012
|
+
scan,
|
|
41013
|
+
aliasEvidence: function aliasEvidence(ecosystem, packageNames) {
|
|
41014
|
+
return deps.isSeeded(ecosystem) ? deps.lookup(ecosystem, packageNames) : null;
|
|
41015
|
+
}
|
|
41016
|
+
};
|
|
40684
41017
|
}
|
|
40685
41018
|
function matchPackages(packages, lookup, isSeeded2, isEnabled) {
|
|
40686
41019
|
const findings = [];
|
|
@@ -40717,7 +41050,8 @@ function toCanonicalAdvisory(packageName, ecosystem, advisory) {
|
|
|
40717
41050
|
severity: advisory.severity,
|
|
40718
41051
|
summary: advisory.summary,
|
|
40719
41052
|
url: advisory.url,
|
|
40720
|
-
withdrawn: advisory.withdrawn
|
|
41053
|
+
withdrawn: advisory.withdrawn,
|
|
41054
|
+
noticeKind: advisory.noticeKind
|
|
40721
41055
|
};
|
|
40722
41056
|
}
|
|
40723
41057
|
function groupByEcosystem(packages) {
|
|
@@ -40753,6 +41087,64 @@ function unauditable5(reasonCode, message, startedAt) {
|
|
|
40753
41087
|
};
|
|
40754
41088
|
}
|
|
40755
41089
|
|
|
41090
|
+
// ../../packages/scanners/src/withdrawn.ts
|
|
41091
|
+
function stampWithdrawn(advisories, links) {
|
|
41092
|
+
return advisories.map(function stamp(advisory) {
|
|
41093
|
+
const withdrawn = withdrawnAt(advisory, links);
|
|
41094
|
+
if (withdrawn !== null) return { ...advisory, withdrawn };
|
|
41095
|
+
const osvRecords = liveLinks(advisory, links);
|
|
41096
|
+
return osvRecords.length === 0 ? advisory : { ...advisory, osvRecords };
|
|
41097
|
+
});
|
|
41098
|
+
}
|
|
41099
|
+
function stampWithdrawnByPackage(byPackage, linksByPackage) {
|
|
41100
|
+
const out = /* @__PURE__ */ new Map();
|
|
41101
|
+
for (const [name, advisories] of byPackage.entries()) {
|
|
41102
|
+
out.set(name, stampWithdrawn(advisories, linksByPackage.get(name) ?? []));
|
|
41103
|
+
}
|
|
41104
|
+
return out;
|
|
41105
|
+
}
|
|
41106
|
+
function liveLinks(advisory, links) {
|
|
41107
|
+
const identity = /* @__PURE__ */ new Set([advisory.advisoryId, ...advisory.aliases]);
|
|
41108
|
+
return links.filter(function live(link2) {
|
|
41109
|
+
return link2.withdrawn === null && sharesIdentifier(identity, link2);
|
|
41110
|
+
});
|
|
41111
|
+
}
|
|
41112
|
+
function clearedByOsv(records, version2, comparator, acceptedRangeTypes) {
|
|
41113
|
+
if (records === void 0 || records.length === 0) return false;
|
|
41114
|
+
if (comparator.normalize(version2) === null) return false;
|
|
41115
|
+
return !records.some(function contains(record2) {
|
|
41116
|
+
if (record2.rangesDiscarded === true) return true;
|
|
41117
|
+
if (record2.ranges.length === 0 && record2.versions.length === 0) return true;
|
|
41118
|
+
if (record2.versions.includes(version2)) return true;
|
|
41119
|
+
if (record2.ranges.some(function unreadable(range) {
|
|
41120
|
+
return isRefused(range) || range.type === void 0 || !acceptedRangeTypes.includes(range.type);
|
|
41121
|
+
})) return true;
|
|
41122
|
+
const exact = /* @__PURE__ */ new Set();
|
|
41123
|
+
for (const raw of record2.versions) {
|
|
41124
|
+
const normalized = comparator.normalize(raw);
|
|
41125
|
+
if (normalized === null) return true;
|
|
41126
|
+
exact.add(normalized);
|
|
41127
|
+
}
|
|
41128
|
+
return versionInSet(version2, record2.ranges, exact, comparator, void 0);
|
|
41129
|
+
});
|
|
41130
|
+
}
|
|
41131
|
+
function withdrawnAt(advisory, links) {
|
|
41132
|
+
const identity = /* @__PURE__ */ new Set([advisory.advisoryId, ...advisory.aliases]);
|
|
41133
|
+
let latest = null;
|
|
41134
|
+
for (const link2 of links) {
|
|
41135
|
+
if (!sharesIdentifier(identity, link2)) continue;
|
|
41136
|
+
if (link2.withdrawn === null) return null;
|
|
41137
|
+
if (latest === null || link2.withdrawn > latest) latest = link2.withdrawn;
|
|
41138
|
+
}
|
|
41139
|
+
return latest;
|
|
41140
|
+
}
|
|
41141
|
+
function sharesIdentifier(identity, link2) {
|
|
41142
|
+
if (identity.has(link2.advisoryId)) return true;
|
|
41143
|
+
return link2.aliases.some(function inIdentity(alias) {
|
|
41144
|
+
return identity.has(alias);
|
|
41145
|
+
});
|
|
41146
|
+
}
|
|
41147
|
+
|
|
40756
41148
|
// ../../packages/scanners/src/gemnasium.ts
|
|
40757
41149
|
var GEMNASIUM_SCANNER_NAME = "gemnasium";
|
|
40758
41150
|
function createGemnasiumScanner(deps) {
|
|
@@ -40799,7 +41191,13 @@ function createGemnasiumScanner(deps) {
|
|
|
40799
41191
|
durationMs: Date.now() - startedAt
|
|
40800
41192
|
};
|
|
40801
41193
|
}
|
|
40802
|
-
return {
|
|
41194
|
+
return {
|
|
41195
|
+
name: GEMNASIUM_SCANNER_NAME,
|
|
41196
|
+
scan,
|
|
41197
|
+
aliasEvidence: function aliasEvidence(ecosystem, packageNames) {
|
|
41198
|
+
return deps.isSeeded() ? deps.lookup(ecosystem, packageNames) : null;
|
|
41199
|
+
}
|
|
41200
|
+
};
|
|
40803
41201
|
}
|
|
40804
41202
|
function matchPackages2(packages, lookup, isEnabled) {
|
|
40805
41203
|
const findings = [];
|
|
@@ -40815,7 +41213,13 @@ function matchPackages2(packages, lookup, isEnabled) {
|
|
|
40815
41213
|
return toCanonicalAdvisory2(name, ecosystem, advisory);
|
|
40816
41214
|
}));
|
|
40817
41215
|
}
|
|
40818
|
-
|
|
41216
|
+
const acceptedRangeTypes = acceptedRangeTypesForEcosystem(ecosystem);
|
|
41217
|
+
for (const finding of matchAdvisories(pkgs, byPackage, comparator)) {
|
|
41218
|
+
const advisory = byPackageRaw.get(finding.packageName)?.find(function same(a) {
|
|
41219
|
+
return a.advisoryId === finding.advisoryId;
|
|
41220
|
+
});
|
|
41221
|
+
if (!clearedByOsv(advisory?.osvRecords, finding.installedVersion, comparator, acceptedRangeTypes)) findings.push(finding);
|
|
41222
|
+
}
|
|
40819
41223
|
}
|
|
40820
41224
|
return findings;
|
|
40821
41225
|
}
|
|
@@ -40870,37 +41274,6 @@ function unauditable6(reasonCode, message, startedAt) {
|
|
|
40870
41274
|
};
|
|
40871
41275
|
}
|
|
40872
41276
|
|
|
40873
|
-
// ../../packages/scanners/src/withdrawn.ts
|
|
40874
|
-
function stampWithdrawn(advisories, links) {
|
|
40875
|
-
return advisories.map(function stamp(advisory) {
|
|
40876
|
-
const withdrawn = withdrawnAt(advisory, links);
|
|
40877
|
-
return withdrawn === null ? advisory : { ...advisory, withdrawn };
|
|
40878
|
-
});
|
|
40879
|
-
}
|
|
40880
|
-
function stampWithdrawnByPackage(byPackage, linksByPackage) {
|
|
40881
|
-
const out = /* @__PURE__ */ new Map();
|
|
40882
|
-
for (const [name, advisories] of byPackage.entries()) {
|
|
40883
|
-
out.set(name, stampWithdrawn(advisories, linksByPackage.get(name) ?? []));
|
|
40884
|
-
}
|
|
40885
|
-
return out;
|
|
40886
|
-
}
|
|
40887
|
-
function withdrawnAt(advisory, links) {
|
|
40888
|
-
const identity = /* @__PURE__ */ new Set([advisory.advisoryId, ...advisory.aliases]);
|
|
40889
|
-
let latest = null;
|
|
40890
|
-
for (const link2 of links) {
|
|
40891
|
-
if (!sharesIdentifier(identity, link2)) continue;
|
|
40892
|
-
if (link2.withdrawn === null) return null;
|
|
40893
|
-
if (latest === null || link2.withdrawn > latest) latest = link2.withdrawn;
|
|
40894
|
-
}
|
|
40895
|
-
return latest;
|
|
40896
|
-
}
|
|
40897
|
-
function sharesIdentifier(identity, link2) {
|
|
40898
|
-
if (identity.has(link2.advisoryId)) return true;
|
|
40899
|
-
return link2.aliases.some(function inIdentity(alias) {
|
|
40900
|
-
return identity.has(alias);
|
|
40901
|
-
});
|
|
40902
|
-
}
|
|
40903
|
-
|
|
40904
41277
|
// ../../packages/scanners/src/engine/reconcile.ts
|
|
40905
41278
|
function findingIdentityKeys(finding) {
|
|
40906
41279
|
const keys = [finding.advisoryId.toLowerCase()];
|
|
@@ -40922,6 +41295,9 @@ function reconcileAgainstReported(findings, reportedByPackage, source) {
|
|
|
40922
41295
|
const target = firstReported(existing, keys);
|
|
40923
41296
|
if (target && target.source === source) {
|
|
40924
41297
|
foldInstallation(target.finding, finding);
|
|
41298
|
+
target.severity = maxSeverity([target.severity, finding.severity]);
|
|
41299
|
+
target.finding.severity = escalatedSeverity(target.severity, target.finding.corroborations ?? []);
|
|
41300
|
+
clearNoticeWhenReal(target.finding, finding);
|
|
40925
41301
|
target.evidence.push(finding.fixInputs);
|
|
40926
41302
|
continue;
|
|
40927
41303
|
}
|
|
@@ -40934,6 +41310,7 @@ function reconcileAgainstReported(findings, reportedByPackage, source) {
|
|
|
40934
41310
|
})) attached.push(by);
|
|
40935
41311
|
target.finding.corroborations = attached;
|
|
40936
41312
|
target.finding.severity = escalatedSeverity(target.severity, attached);
|
|
41313
|
+
clearNoticeWhenReal(target.finding, finding);
|
|
40937
41314
|
target.evidence.push(finding.fixInputs);
|
|
40938
41315
|
continue;
|
|
40939
41316
|
}
|
|
@@ -40973,6 +41350,9 @@ function foldInstallation(survivor, copy) {
|
|
|
40973
41350
|
function installationsOf(finding) {
|
|
40974
41351
|
return finding.installations ? finding.installations.slice() : [];
|
|
40975
41352
|
}
|
|
41353
|
+
function clearNoticeWhenReal(survivor, other) {
|
|
41354
|
+
if (!other.noticeKind) survivor.noticeKind = null;
|
|
41355
|
+
}
|
|
40976
41356
|
function firstReported(existing, keys) {
|
|
40977
41357
|
for (const key of keys) {
|
|
40978
41358
|
const found = existing.get(key);
|
|
@@ -41169,6 +41549,98 @@ async function openDownloadStream(url2, onProgress, options) {
|
|
|
41169
41549
|
return { stream, contentLength, lastModified: response.headers["last-modified"] ?? null };
|
|
41170
41550
|
}
|
|
41171
41551
|
|
|
41552
|
+
// ../../packages/feeds/src/gemnasium/cvss.ts
|
|
41553
|
+
var V3_AV = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 };
|
|
41554
|
+
var V3_AC = { L: 0.77, H: 0.44 };
|
|
41555
|
+
var V3_UI = { N: 0.85, R: 0.62 };
|
|
41556
|
+
var V3_CIA = { H: 0.56, L: 0.22, N: 0 };
|
|
41557
|
+
var V3_PR_UNCHANGED = { N: 0.85, L: 0.62, H: 0.27 };
|
|
41558
|
+
var V3_PR_CHANGED = { N: 0.85, L: 0.68, H: 0.5 };
|
|
41559
|
+
var V2_AV = { L: 0.395, A: 0.646, N: 1 };
|
|
41560
|
+
var V2_AC = { H: 0.35, M: 0.61, L: 0.71 };
|
|
41561
|
+
var V2_AU = { M: 0.45, S: 0.56, N: 0.704 };
|
|
41562
|
+
var V2_CIA = { N: 0, P: 0.275, C: 0.66 };
|
|
41563
|
+
function severityFromCvss(cvssV3, cvssV2) {
|
|
41564
|
+
const v3 = parseVector(cvssV3);
|
|
41565
|
+
if (v3) {
|
|
41566
|
+
const score = baseScoreV3(v3);
|
|
41567
|
+
if (score !== null) return bucketV3(score);
|
|
41568
|
+
}
|
|
41569
|
+
const v2 = parseVector(cvssV2);
|
|
41570
|
+
if (v2) {
|
|
41571
|
+
const score = baseScoreV2(v2);
|
|
41572
|
+
if (score !== null) return bucketV2(score);
|
|
41573
|
+
}
|
|
41574
|
+
return null;
|
|
41575
|
+
}
|
|
41576
|
+
function parseVector(vector) {
|
|
41577
|
+
if (typeof vector !== "string" || vector.trim().length === 0) return null;
|
|
41578
|
+
const out = {};
|
|
41579
|
+
for (const part of vector.trim().split("/")) {
|
|
41580
|
+
const colon = part.indexOf(":");
|
|
41581
|
+
if (colon <= 0) continue;
|
|
41582
|
+
const key = part.slice(0, colon).trim();
|
|
41583
|
+
const value = part.slice(colon + 1).trim().toUpperCase();
|
|
41584
|
+
if (key === "CVSS") continue;
|
|
41585
|
+
out[key] = value;
|
|
41586
|
+
}
|
|
41587
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
41588
|
+
}
|
|
41589
|
+
function weight(table, key) {
|
|
41590
|
+
if (key === void 0) return void 0;
|
|
41591
|
+
return table[key];
|
|
41592
|
+
}
|
|
41593
|
+
function baseScoreV3(m) {
|
|
41594
|
+
const av = weight(V3_AV, m.AV);
|
|
41595
|
+
const ac = weight(V3_AC, m.AC);
|
|
41596
|
+
const ui = weight(V3_UI, m.UI);
|
|
41597
|
+
const c = weight(V3_CIA, m.C);
|
|
41598
|
+
const i = weight(V3_CIA, m.I);
|
|
41599
|
+
const a = weight(V3_CIA, m.A);
|
|
41600
|
+
const changed = m.S === "C";
|
|
41601
|
+
const pr = weight(changed ? V3_PR_CHANGED : V3_PR_UNCHANGED, m.PR);
|
|
41602
|
+
if (av === void 0 || ac === void 0 || ui === void 0 || pr === void 0) return null;
|
|
41603
|
+
if (c === void 0 || i === void 0 || a === void 0) return null;
|
|
41604
|
+
const iss = 1 - (1 - c) * (1 - i) * (1 - a);
|
|
41605
|
+
const impact = changed ? 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15) : 6.42 * iss;
|
|
41606
|
+
const exploitability = 8.22 * av * ac * pr * ui;
|
|
41607
|
+
if (impact <= 0) return 0;
|
|
41608
|
+
const raw = changed ? 1.08 * (impact + exploitability) : impact + exploitability;
|
|
41609
|
+
return roundUpV3(Math.min(raw, 10));
|
|
41610
|
+
}
|
|
41611
|
+
function roundUpV3(value) {
|
|
41612
|
+
const intInput = Math.round(value * 1e5);
|
|
41613
|
+
if (intInput % 1e4 === 0) return intInput / 1e5;
|
|
41614
|
+
return (Math.floor(intInput / 1e4) + 1) / 10;
|
|
41615
|
+
}
|
|
41616
|
+
function bucketV3(score) {
|
|
41617
|
+
if (score === 0) return "info";
|
|
41618
|
+
if (score < 4) return "low";
|
|
41619
|
+
if (score < 7) return "moderate";
|
|
41620
|
+
if (score < 9) return "high";
|
|
41621
|
+
return "critical";
|
|
41622
|
+
}
|
|
41623
|
+
function baseScoreV2(m) {
|
|
41624
|
+
const av = weight(V2_AV, m.AV);
|
|
41625
|
+
const ac = weight(V2_AC, m.AC);
|
|
41626
|
+
const au = weight(V2_AU, m.Au) ?? weight(V2_AU, m.AU);
|
|
41627
|
+
const c = weight(V2_CIA, m.C);
|
|
41628
|
+
const i = weight(V2_CIA, m.I);
|
|
41629
|
+
const a = weight(V2_CIA, m.A);
|
|
41630
|
+
if (av === void 0 || ac === void 0 || au === void 0) return null;
|
|
41631
|
+
if (c === void 0 || i === void 0 || a === void 0) return null;
|
|
41632
|
+
const impact = 10.41 * (1 - (1 - c) * (1 - i) * (1 - a));
|
|
41633
|
+
const exploitability = 20 * av * ac * au;
|
|
41634
|
+
const f = impact === 0 ? 0 : 1.176;
|
|
41635
|
+
const base = (0.6 * impact + 0.4 * exploitability - 1.5) * f;
|
|
41636
|
+
return Math.round(base * 10) / 10;
|
|
41637
|
+
}
|
|
41638
|
+
function bucketV2(score) {
|
|
41639
|
+
if (score < 4) return "low";
|
|
41640
|
+
if (score < 7) return "moderate";
|
|
41641
|
+
return "high";
|
|
41642
|
+
}
|
|
41643
|
+
|
|
41172
41644
|
// ../../packages/feeds/src/osv/normalize.ts
|
|
41173
41645
|
function normalizeOsvRecord(record2, ecosystem) {
|
|
41174
41646
|
if (!record2 || typeof record2 !== "object") return [];
|
|
@@ -41193,10 +41665,14 @@ function normalizeOsvRecord(record2, ecosystem) {
|
|
|
41193
41665
|
if (!packageName) continue;
|
|
41194
41666
|
const ranges = extractRanges(affected.ranges, affected.database_specific?.last_known_affected_version_range, comparator);
|
|
41195
41667
|
const versions = extractVersions(affected.versions);
|
|
41668
|
+
const noticeKind = noticeKindOf(r.database_specific?.informational) ?? noticeKindOf(affected.database_specific?.informational);
|
|
41669
|
+
const rangesDiscarded = Array.isArray(affected.ranges) && !affected.ranges.every(isReadableRange);
|
|
41196
41670
|
const existing = byPackage.get(packageName);
|
|
41197
41671
|
if (existing) {
|
|
41198
41672
|
for (const range of ranges) existing.ranges.push(range);
|
|
41199
41673
|
for (const version2 of versions) existing.versions.push(version2);
|
|
41674
|
+
existing.noticeKind ??= noticeKind;
|
|
41675
|
+
if (rangesDiscarded) existing.rangesDiscarded = true;
|
|
41200
41676
|
continue;
|
|
41201
41677
|
}
|
|
41202
41678
|
byPackage.set(packageName, {
|
|
@@ -41210,7 +41686,9 @@ function normalizeOsvRecord(record2, ecosystem) {
|
|
|
41210
41686
|
summary,
|
|
41211
41687
|
url: url2,
|
|
41212
41688
|
malicious,
|
|
41213
|
-
withdrawn
|
|
41689
|
+
withdrawn,
|
|
41690
|
+
noticeKind,
|
|
41691
|
+
...rangesDiscarded ? { rangesDiscarded } : {}
|
|
41214
41692
|
});
|
|
41215
41693
|
}
|
|
41216
41694
|
for (const row of byPackage.values()) {
|
|
@@ -41230,14 +41708,17 @@ function extractVersions(versions) {
|
|
|
41230
41708
|
}
|
|
41231
41709
|
return out;
|
|
41232
41710
|
}
|
|
41711
|
+
function isReadableRange(range) {
|
|
41712
|
+
const type2 = typeof range.type === "string" ? range.type : "SEMVER";
|
|
41713
|
+
return (type2 === "SEMVER" || type2 === "ECOSYSTEM") && Array.isArray(range.events);
|
|
41714
|
+
}
|
|
41233
41715
|
function extractRanges(ranges, lastKnownAffected, comparator) {
|
|
41234
41716
|
if (!Array.isArray(ranges)) return [];
|
|
41235
41717
|
const out = [];
|
|
41236
41718
|
const refused = [];
|
|
41237
41719
|
for (const range of ranges) {
|
|
41720
|
+
if (!isReadableRange(range)) continue;
|
|
41238
41721
|
const type2 = typeof range.type === "string" ? range.type : "SEMVER";
|
|
41239
|
-
if (type2 !== "SEMVER" && type2 !== "ECOSYSTEM") continue;
|
|
41240
|
-
if (!Array.isArray(range.events)) continue;
|
|
41241
41722
|
let introduced = null;
|
|
41242
41723
|
let lastAffected = null;
|
|
41243
41724
|
for (const event of range.events) {
|
|
@@ -41295,7 +41776,17 @@ function boundOpenEndedRange(ranges, lastKnownAffected, comparator) {
|
|
|
41295
41776
|
function pickSeverity2(r) {
|
|
41296
41777
|
const ds = r.database_specific && r.database_specific.severity;
|
|
41297
41778
|
if (typeof ds === "string" && ds.length > 0) return ds;
|
|
41298
|
-
return null;
|
|
41779
|
+
if (!Array.isArray(r.severity)) return null;
|
|
41780
|
+
return severityFromCvss(vectorOfType(r.severity, "CVSS_V3"), vectorOfType(r.severity, "CVSS_V2"));
|
|
41781
|
+
}
|
|
41782
|
+
function vectorOfType(severity, type2) {
|
|
41783
|
+
const entry = severity.find(function ofType(s) {
|
|
41784
|
+
return s.type === type2 && typeof s.score === "string";
|
|
41785
|
+
});
|
|
41786
|
+
return entry?.score ?? null;
|
|
41787
|
+
}
|
|
41788
|
+
function noticeKindOf(value) {
|
|
41789
|
+
return isNonEmptyString(value) ? value : null;
|
|
41299
41790
|
}
|
|
41300
41791
|
function pickUrl(r, advisoryId) {
|
|
41301
41792
|
if (Array.isArray(r.references)) {
|
|
@@ -41425,98 +41916,6 @@ function parseSeedEntry(content, ecosystem) {
|
|
|
41425
41916
|
// ../../packages/feeds/src/gemnasium/feed.ts
|
|
41426
41917
|
var import_unzipper2 = __toESM(require_unzip2());
|
|
41427
41918
|
|
|
41428
|
-
// ../../packages/feeds/src/gemnasium/cvss.ts
|
|
41429
|
-
var V3_AV = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 };
|
|
41430
|
-
var V3_AC = { L: 0.77, H: 0.44 };
|
|
41431
|
-
var V3_UI = { N: 0.85, R: 0.62 };
|
|
41432
|
-
var V3_CIA = { H: 0.56, L: 0.22, N: 0 };
|
|
41433
|
-
var V3_PR_UNCHANGED = { N: 0.85, L: 0.62, H: 0.27 };
|
|
41434
|
-
var V3_PR_CHANGED = { N: 0.85, L: 0.68, H: 0.5 };
|
|
41435
|
-
var V2_AV = { L: 0.395, A: 0.646, N: 1 };
|
|
41436
|
-
var V2_AC = { H: 0.35, M: 0.61, L: 0.71 };
|
|
41437
|
-
var V2_AU = { M: 0.45, S: 0.56, N: 0.704 };
|
|
41438
|
-
var V2_CIA = { N: 0, P: 0.275, C: 0.66 };
|
|
41439
|
-
function severityFromCvss(cvssV3, cvssV2) {
|
|
41440
|
-
const v3 = parseVector(cvssV3);
|
|
41441
|
-
if (v3) {
|
|
41442
|
-
const score = baseScoreV3(v3);
|
|
41443
|
-
if (score !== null) return bucketV3(score);
|
|
41444
|
-
}
|
|
41445
|
-
const v2 = parseVector(cvssV2);
|
|
41446
|
-
if (v2) {
|
|
41447
|
-
const score = baseScoreV2(v2);
|
|
41448
|
-
if (score !== null) return bucketV2(score);
|
|
41449
|
-
}
|
|
41450
|
-
return null;
|
|
41451
|
-
}
|
|
41452
|
-
function parseVector(vector) {
|
|
41453
|
-
if (typeof vector !== "string" || vector.trim().length === 0) return null;
|
|
41454
|
-
const out = {};
|
|
41455
|
-
for (const part of vector.trim().split("/")) {
|
|
41456
|
-
const colon = part.indexOf(":");
|
|
41457
|
-
if (colon <= 0) continue;
|
|
41458
|
-
const key = part.slice(0, colon).trim();
|
|
41459
|
-
const value = part.slice(colon + 1).trim().toUpperCase();
|
|
41460
|
-
if (key === "CVSS") continue;
|
|
41461
|
-
out[key] = value;
|
|
41462
|
-
}
|
|
41463
|
-
return Object.keys(out).length > 0 ? out : null;
|
|
41464
|
-
}
|
|
41465
|
-
function weight(table, key) {
|
|
41466
|
-
if (key === void 0) return void 0;
|
|
41467
|
-
return table[key];
|
|
41468
|
-
}
|
|
41469
|
-
function baseScoreV3(m) {
|
|
41470
|
-
const av = weight(V3_AV, m.AV);
|
|
41471
|
-
const ac = weight(V3_AC, m.AC);
|
|
41472
|
-
const ui = weight(V3_UI, m.UI);
|
|
41473
|
-
const c = weight(V3_CIA, m.C);
|
|
41474
|
-
const i = weight(V3_CIA, m.I);
|
|
41475
|
-
const a = weight(V3_CIA, m.A);
|
|
41476
|
-
const changed = m.S === "C";
|
|
41477
|
-
const pr = weight(changed ? V3_PR_CHANGED : V3_PR_UNCHANGED, m.PR);
|
|
41478
|
-
if (av === void 0 || ac === void 0 || ui === void 0 || pr === void 0) return null;
|
|
41479
|
-
if (c === void 0 || i === void 0 || a === void 0) return null;
|
|
41480
|
-
const iss = 1 - (1 - c) * (1 - i) * (1 - a);
|
|
41481
|
-
const impact = changed ? 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15) : 6.42 * iss;
|
|
41482
|
-
const exploitability = 8.22 * av * ac * pr * ui;
|
|
41483
|
-
if (impact <= 0) return 0;
|
|
41484
|
-
const raw = changed ? 1.08 * (impact + exploitability) : impact + exploitability;
|
|
41485
|
-
return roundUpV3(Math.min(raw, 10));
|
|
41486
|
-
}
|
|
41487
|
-
function roundUpV3(value) {
|
|
41488
|
-
const intInput = Math.round(value * 1e5);
|
|
41489
|
-
if (intInput % 1e4 === 0) return intInput / 1e5;
|
|
41490
|
-
return (Math.floor(intInput / 1e4) + 1) / 10;
|
|
41491
|
-
}
|
|
41492
|
-
function bucketV3(score) {
|
|
41493
|
-
if (score === 0) return "info";
|
|
41494
|
-
if (score < 4) return "low";
|
|
41495
|
-
if (score < 7) return "moderate";
|
|
41496
|
-
if (score < 9) return "high";
|
|
41497
|
-
return "critical";
|
|
41498
|
-
}
|
|
41499
|
-
function baseScoreV2(m) {
|
|
41500
|
-
const av = weight(V2_AV, m.AV);
|
|
41501
|
-
const ac = weight(V2_AC, m.AC);
|
|
41502
|
-
const au = weight(V2_AU, m.Au) ?? weight(V2_AU, m.AU);
|
|
41503
|
-
const c = weight(V2_CIA, m.C);
|
|
41504
|
-
const i = weight(V2_CIA, m.I);
|
|
41505
|
-
const a = weight(V2_CIA, m.A);
|
|
41506
|
-
if (av === void 0 || ac === void 0 || au === void 0) return null;
|
|
41507
|
-
if (c === void 0 || i === void 0 || a === void 0) return null;
|
|
41508
|
-
const impact = 10.41 * (1 - (1 - c) * (1 - i) * (1 - a));
|
|
41509
|
-
const exploitability = 20 * av * ac * au;
|
|
41510
|
-
const f = impact === 0 ? 0 : 1.176;
|
|
41511
|
-
const base = (0.6 * impact + 0.4 * exploitability - 1.5) * f;
|
|
41512
|
-
return Math.round(base * 10) / 10;
|
|
41513
|
-
}
|
|
41514
|
-
function bucketV2(score) {
|
|
41515
|
-
if (score < 4) return "low";
|
|
41516
|
-
if (score < 7) return "moderate";
|
|
41517
|
-
return "high";
|
|
41518
|
-
}
|
|
41519
|
-
|
|
41520
41919
|
// ../../packages/feeds/src/gemnasium/normalize.ts
|
|
41521
41920
|
function normalizeGemnasiumRecord(record2, ecosystem, slugPrefix) {
|
|
41522
41921
|
if (!record2 || typeof record2 !== "object") return [];
|
|
@@ -55734,8 +56133,13 @@ function pickReleasedFix(args) {
|
|
|
55734
56133
|
patched.push(range);
|
|
55735
56134
|
}
|
|
55736
56135
|
const stated = statedFixVersions(args.evidence, comparator);
|
|
55737
|
-
|
|
55738
|
-
|
|
56136
|
+
function lowest(current, candidate) {
|
|
56137
|
+
return current === null || comparator.lt(candidate.version, current.version) ? candidate : current;
|
|
56138
|
+
}
|
|
56139
|
+
let tagged = null;
|
|
56140
|
+
let taggedCurrent = null;
|
|
56141
|
+
let pseudo = null;
|
|
56142
|
+
let pseudoCurrent = null;
|
|
55739
56143
|
for (const p of args.published) {
|
|
55740
56144
|
const v = comparator.normalize(p.version);
|
|
55741
56145
|
if (v === null) continue;
|
|
@@ -55749,10 +56153,15 @@ function pickReleasedFix(args) {
|
|
|
55749
56153
|
return evaluableContains(ev, v);
|
|
55750
56154
|
})) continue;
|
|
55751
56155
|
const candidate = { version: v, spelled: p.version };
|
|
55752
|
-
if (
|
|
55753
|
-
|
|
56156
|
+
if (kind === "pseudo") {
|
|
56157
|
+
pseudo = lowest(pseudo, candidate);
|
|
56158
|
+
if (!p.deprecated) pseudoCurrent = lowest(pseudoCurrent, candidate);
|
|
56159
|
+
} else {
|
|
56160
|
+
tagged = lowest(tagged, candidate);
|
|
56161
|
+
if (!p.deprecated) taggedCurrent = lowest(taggedCurrent, candidate);
|
|
56162
|
+
}
|
|
55754
56163
|
}
|
|
55755
|
-
const chosen =
|
|
56164
|
+
const chosen = taggedCurrent ?? tagged ?? pseudoCurrent ?? pseudo;
|
|
55756
56165
|
if (chosen === null) return { kind: "none" };
|
|
55757
56166
|
return { kind: "released", version: chosen.spelled };
|
|
55758
56167
|
}
|
|
@@ -56215,7 +56624,8 @@ function toOsvAdvisory(row) {
|
|
|
56215
56624
|
summary: row.summary,
|
|
56216
56625
|
url: row.url,
|
|
56217
56626
|
malicious: row.malicious,
|
|
56218
|
-
withdrawn: row.withdrawn
|
|
56627
|
+
withdrawn: row.withdrawn,
|
|
56628
|
+
noticeKind: row.noticeKind ?? null
|
|
56219
56629
|
};
|
|
56220
56630
|
}
|
|
56221
56631
|
function toGemnasiumAdvisory(row) {
|
|
@@ -56995,7 +57405,7 @@ function explicitFlagNames(argv) {
|
|
|
56995
57405
|
return out;
|
|
56996
57406
|
}
|
|
56997
57407
|
function emptyCounts() {
|
|
56998
|
-
return { critical: 0, high: 0, moderate: 0, low: 0, info: 0 };
|
|
57408
|
+
return { critical: 0, high: 0, moderate: 0, unrated: 0, low: 0, info: 0 };
|
|
56999
57409
|
}
|
|
57000
57410
|
function matchesDepType(finding, depType) {
|
|
57001
57411
|
if (depType === "all") return true;
|
|
@@ -57005,6 +57415,7 @@ function matchesDepType(finding, depType) {
|
|
|
57005
57415
|
function summarize(results, options) {
|
|
57006
57416
|
const projects = [];
|
|
57007
57417
|
const findings = [];
|
|
57418
|
+
const notices = [];
|
|
57008
57419
|
const total = emptyCounts();
|
|
57009
57420
|
let totalFindings = 0;
|
|
57010
57421
|
for (const result of results) {
|
|
@@ -57012,26 +57423,30 @@ function summarize(results, options) {
|
|
|
57012
57423
|
let projectFindings = 0;
|
|
57013
57424
|
for (const finding of result.findings) {
|
|
57014
57425
|
if (!matchesDepType(finding, options.depType)) continue;
|
|
57015
|
-
if (!meetsSeverityFloor(finding.severity, options.minSeverity)) continue;
|
|
57016
|
-
|
|
57017
|
-
|
|
57018
|
-
|
|
57019
|
-
|
|
57426
|
+
if (!finding.noticeKind && !meetsSeverityFloor(finding.severity, options.minSeverity)) continue;
|
|
57427
|
+
if (!finding.noticeKind) {
|
|
57428
|
+
counts[finding.severity]++;
|
|
57429
|
+
total[finding.severity]++;
|
|
57430
|
+
projectFindings++;
|
|
57431
|
+
totalFindings++;
|
|
57432
|
+
}
|
|
57020
57433
|
const fix = result.fixes.get(finding);
|
|
57021
|
-
findings
|
|
57434
|
+
const list = finding.noticeKind ? notices : findings;
|
|
57435
|
+
list.push({
|
|
57022
57436
|
// npm-audit builds its findings without an ecosystem; it only ever reports npm packages.
|
|
57023
57437
|
ecosystem: finding.ecosystem ?? DEFAULT_ECOSYSTEM,
|
|
57024
57438
|
packageName: finding.packageName,
|
|
57025
57439
|
installedVersion: finding.installedVersion,
|
|
57026
57440
|
// scanProject records the installations of every finding it keeps.
|
|
57027
57441
|
installations: result.installations.get(finding),
|
|
57028
|
-
fixAvailable: fix
|
|
57029
|
-
fixVersion: fix
|
|
57030
|
-
fixStatus: fix
|
|
57031
|
-
fixCheck: fix
|
|
57442
|
+
fixAvailable: fix?.fixAvailable ?? false,
|
|
57443
|
+
fixVersion: fix?.fixVersion ?? null,
|
|
57444
|
+
fixStatus: fix?.fixStatus ?? "unverified",
|
|
57445
|
+
fixCheck: fix?.fixCheck ?? null,
|
|
57032
57446
|
// Only a finding settled 'none_released' has one.
|
|
57033
57447
|
remediation: result.remediations.get(finding) ?? null,
|
|
57034
57448
|
severity: finding.severity,
|
|
57449
|
+
noticeKind: finding.noticeKind ?? null,
|
|
57035
57450
|
advisoryId: finding.advisoryId,
|
|
57036
57451
|
advisoryTitle: finding.advisoryTitle,
|
|
57037
57452
|
advisoryUrl: finding.advisoryUrl,
|
|
@@ -57057,7 +57472,7 @@ function summarize(results, options) {
|
|
|
57057
57472
|
scanState: result.scanState
|
|
57058
57473
|
});
|
|
57059
57474
|
}
|
|
57060
|
-
return { projects, totalFindings, counts: total, findings };
|
|
57475
|
+
return { projects, totalFindings, counts: total, findings, notices };
|
|
57061
57476
|
}
|
|
57062
57477
|
async function resolvePrompt(options) {
|
|
57063
57478
|
if (!options.includePrompt) return "";
|
|
@@ -57079,7 +57494,7 @@ function renderMarkdown(summary, options, prompt, generatedAt) {
|
|
|
57079
57494
|
return buildAdvisoryMarkdown({
|
|
57080
57495
|
scope: buildScope(options, summary.projects.length),
|
|
57081
57496
|
prompt,
|
|
57082
|
-
findings: summary.findings,
|
|
57497
|
+
findings: [...summary.findings, ...summary.notices],
|
|
57083
57498
|
generatedAt,
|
|
57084
57499
|
// Only the projects that could not be (fully) scanned are rendered, in their own section.
|
|
57085
57500
|
scanStates: summary.projects.map(function state(p) {
|
|
@@ -57109,7 +57524,8 @@ function renderJson(summary, options, generatedAt) {
|
|
|
57109
57524
|
scanState: labelScanState(p.scanState)
|
|
57110
57525
|
};
|
|
57111
57526
|
}),
|
|
57112
|
-
findings: summary.findings
|
|
57527
|
+
findings: summary.findings,
|
|
57528
|
+
notices: summary.notices
|
|
57113
57529
|
}, null, 2) + "\n";
|
|
57114
57530
|
}
|
|
57115
57531
|
function hasUnavailableSource(summary) {
|
|
@@ -57266,7 +57682,7 @@ async function scanProject(setup, resolved2, scanners) {
|
|
|
57266
57682
|
for (const scanner of scanners) {
|
|
57267
57683
|
for (const ecosystem of ecosystems) {
|
|
57268
57684
|
if (setup.abortSignal && setup.abortSignal.aborted) break;
|
|
57269
|
-
if (!cellRuns(setup, scanner.name, ecosystem)) continue;
|
|
57685
|
+
if (!cellRuns(setup, scanner.name, ecosystem) || !sourceAppliesToPackageManager(scanner.name, resolved2.project.packageManager)) continue;
|
|
57270
57686
|
const isNpmAudit = scanner.name === NPM_AUDIT_SCANNER_NAME2;
|
|
57271
57687
|
const cell = resolved2.manifests.filter(function of(m) {
|
|
57272
57688
|
return m.result.ecosystem === ecosystem;
|
|
@@ -57319,7 +57735,10 @@ async function scanProject(setup, resolved2, scanners) {
|
|
|
57319
57735
|
}
|
|
57320
57736
|
}
|
|
57321
57737
|
const settled = await settleProject({
|
|
57322
|
-
|
|
57738
|
+
// A notice has no fix to chase, so it is not settled.
|
|
57739
|
+
findings: [...survivors.values()].filter(function vulnerability(reported) {
|
|
57740
|
+
return !reported.finding.noticeKind;
|
|
57741
|
+
}),
|
|
57323
57742
|
evidence,
|
|
57324
57743
|
graph: resolved2.npmGraph,
|
|
57325
57744
|
registry: setup.registry,
|
|
@@ -57330,7 +57749,8 @@ async function scanProject(setup, resolved2, scanners) {
|
|
|
57330
57749
|
const installations = /* @__PURE__ */ new Map();
|
|
57331
57750
|
for (const [finding, reported] of survivors) {
|
|
57332
57751
|
const key = fixEvidenceKey(reported);
|
|
57333
|
-
|
|
57752
|
+
const settlement = settled.settlements.get(key);
|
|
57753
|
+
if (settlement) fixes.set(finding, settlement);
|
|
57334
57754
|
const remediation = settled.remediations.get(key);
|
|
57335
57755
|
if (remediation) remediations.set(finding, remediation);
|
|
57336
57756
|
installations.set(finding, installationsFor(finding, resolved2.npmGraph));
|
|
@@ -57365,7 +57785,7 @@ function cliScanState(setup, resolved2, scanners, outcomes) {
|
|
|
57365
57785
|
const expectedCells = [];
|
|
57366
57786
|
for (const scanner of scanners) {
|
|
57367
57787
|
for (const ecosystem of ecosystems) {
|
|
57368
|
-
if (cellRuns(setup, scanner.name, ecosystem)) expectedCells.push({ source: scanner.name, ecosystem });
|
|
57788
|
+
if (cellRuns(setup, scanner.name, ecosystem) && sourceAppliesToPackageManager(scanner.name, resolved2.project.packageManager)) expectedCells.push({ source: scanner.name, ecosystem });
|
|
57369
57789
|
}
|
|
57370
57790
|
}
|
|
57371
57791
|
return projectScanState({
|
|
@@ -57409,7 +57829,7 @@ var PLAIN = {
|
|
|
57409
57829
|
green: "",
|
|
57410
57830
|
cyan: ""
|
|
57411
57831
|
};
|
|
57412
|
-
var SEVERITY_ORDER = ["critical", "high", "moderate", "low", "info"];
|
|
57832
|
+
var SEVERITY_ORDER = ["critical", "high", "moderate", "unrated", "low", "info"];
|
|
57413
57833
|
function formatBytes(bytes, estimated = false) {
|
|
57414
57834
|
if (bytes === null) return "unknown size";
|
|
57415
57835
|
const prefix = estimated ? "~" : "";
|
|
@@ -57445,7 +57865,7 @@ function createUi(options) {
|
|
|
57445
57865
|
function severityColor(severity) {
|
|
57446
57866
|
if (severity === "critical") return c.red;
|
|
57447
57867
|
if (severity === "high") return c.magenta;
|
|
57448
|
-
if (severity === "moderate") return c.yellow;
|
|
57868
|
+
if (severity === "moderate" || severity === "unrated") return c.yellow;
|
|
57449
57869
|
if (severity === "low") return c.blue;
|
|
57450
57870
|
return c.dim;
|
|
57451
57871
|
}
|
|
@@ -57712,6 +58132,9 @@ function createUi(options) {
|
|
|
57712
58132
|
write(" " + project.relPath.padEnd(38).slice(0, 38) + " " + breakdown);
|
|
57713
58133
|
}
|
|
57714
58134
|
}
|
|
58135
|
+
if (runSummary.notices.length > 0) {
|
|
58136
|
+
write(" " + c.dim + runSummary.notices.length + " notice" + (runSummary.notices.length === 1 ? "" : "s") + " (unmaintained, unsound), not vulnerabilities: listed in the report, in no count above." + c.reset);
|
|
58137
|
+
}
|
|
57715
58138
|
if (unscanned.length > 0) {
|
|
57716
58139
|
const cannot = runSummary.projects.filter(function cannotScan(p) {
|
|
57717
58140
|
return p.scanState.state === "cannot_scan";
|
|
@@ -57773,8 +58196,8 @@ function createUi(options) {
|
|
|
57773
58196
|
|
|
57774
58197
|
// src/help.ts
|
|
57775
58198
|
var CLI_VERSION = (function resolveVersion() {
|
|
57776
|
-
if ("3.8.
|
|
57777
|
-
return "3.8.
|
|
58199
|
+
if ("3.8.2".length > 0) {
|
|
58200
|
+
return "3.8.2";
|
|
57778
58201
|
}
|
|
57779
58202
|
const fromEnv = process.env.SENTINELLO_VERSION;
|
|
57780
58203
|
if (fromEnv && fromEnv.trim().length > 0) return fromEnv.trim();
|