@quantakrypto/core 0.4.1 → 0.4.3
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/LICENSE +201 -0
- package/README.md +38 -10
- package/dist/agent-types.js.map +1 -1
- package/dist/baseline.js.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/cbom.d.ts.map +1 -1
- package/dist/cbom.js +13 -4
- package/dist/cbom.js.map +1 -1
- package/dist/changed.js.map +1 -1
- package/dist/codemods/config-toggle.js.map +1 -1
- package/dist/codemods/registry.js.map +1 -1
- package/dist/comments.d.ts +26 -0
- package/dist/comments.d.ts.map +1 -1
- package/dist/comments.js +141 -1
- package/dist/comments.js.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/cwe.js.map +1 -1
- package/dist/dependencies.d.ts +3 -2
- package/dist/dependencies.d.ts.map +1 -1
- package/dist/dependencies.js +151 -4
- package/dist/dependencies.js.map +1 -1
- package/dist/detect-utils.d.ts +14 -3
- package/dist/detect-utils.d.ts.map +1 -1
- package/dist/detect-utils.js +32 -4
- package/dist/detect-utils.js.map +1 -1
- package/dist/detectors/c.d.ts.map +1 -1
- package/dist/detectors/c.js +190 -2
- package/dist/detectors/c.js.map +1 -1
- package/dist/detectors/csharp.d.ts.map +1 -1
- package/dist/detectors/csharp.js +141 -3
- package/dist/detectors/csharp.js.map +1 -1
- package/dist/detectors/go.d.ts +5 -3
- package/dist/detectors/go.d.ts.map +1 -1
- package/dist/detectors/go.js +187 -3
- package/dist/detectors/go.js.map +1 -1
- package/dist/detectors/java.d.ts.map +1 -1
- package/dist/detectors/java.js +168 -3
- package/dist/detectors/java.js.map +1 -1
- package/dist/detectors/pem.d.ts.map +1 -1
- package/dist/detectors/pem.js +49 -1
- package/dist/detectors/pem.js.map +1 -1
- package/dist/detectors/python.d.ts.map +1 -1
- package/dist/detectors/python.js +74 -3
- package/dist/detectors/python.js.map +1 -1
- package/dist/detectors/ruby.d.ts +9 -5
- package/dist/detectors/ruby.d.ts.map +1 -1
- package/dist/detectors/ruby.js +122 -2
- package/dist/detectors/ruby.js.map +1 -1
- package/dist/detectors/rust.d.ts +8 -3
- package/dist/detectors/rust.d.ts.map +1 -1
- package/dist/detectors/rust.js +185 -3
- package/dist/detectors/rust.js.map +1 -1
- package/dist/detectors/source.d.ts.map +1 -1
- package/dist/detectors/source.js +131 -13
- package/dist/detectors/source.js.map +1 -1
- package/dist/detectors/stateful-hbs.d.ts +22 -0
- package/dist/detectors/stateful-hbs.d.ts.map +1 -0
- package/dist/detectors/stateful-hbs.js +139 -0
- package/dist/detectors/stateful-hbs.js.map +1 -0
- package/dist/errors.js.map +1 -1
- package/dist/evidence.d.ts +48 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +76 -0
- package/dist/evidence.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/inventory.d.ts +2 -0
- package/dist/inventory.d.ts.map +1 -1
- package/dist/inventory.js +27 -1
- package/dist/inventory.js.map +1 -1
- package/dist/parallel.js +15 -0
- package/dist/parallel.js.map +1 -1
- package/dist/patch-policy.js.map +1 -1
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +122 -7
- package/dist/redact.js.map +1 -1
- package/dist/registry.d.ts +2 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -2
- package/dist/registry.js.map +1 -1
- package/dist/remediate-pipeline.d.ts +3 -0
- package/dist/remediate-pipeline.d.ts.map +1 -1
- package/dist/remediate-pipeline.js +50 -0
- package/dist/remediate-pipeline.js.map +1 -1
- package/dist/remediate-request.js.map +1 -1
- package/dist/remediation.d.ts +9 -3
- package/dist/remediation.d.ts.map +1 -1
- package/dist/remediation.js +33 -6
- package/dist/remediation.js.map +1 -1
- package/dist/report.d.ts +9 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +31 -0
- package/dist/report.js.map +1 -1
- package/dist/scan-worker.js.map +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +16 -2
- package/dist/scan.js.map +1 -1
- package/dist/severity.js.map +1 -1
- package/dist/triage.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/verify.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/walk.js.map +1 -1
- package/dist/worktree.d.ts.map +1 -1
- package/dist/worktree.js +10 -1
- package/dist/worktree.js.map +1 -1
- package/package.json +1 -1
- package/src/cbom.ts +13 -4
- package/src/comments.ts +140 -1
- package/src/dependencies.ts +156 -6
- package/src/detect-utils.ts +33 -4
- package/src/detectors/c.ts +202 -2
- package/src/detectors/csharp.ts +154 -3
- package/src/detectors/go.ts +209 -6
- package/src/detectors/java.ts +189 -3
- package/src/detectors/pem.ts +53 -1
- package/src/detectors/python.ts +82 -3
- package/src/detectors/ruby.ts +138 -7
- package/src/detectors/rust.ts +211 -7
- package/src/detectors/source.ts +163 -12
- package/src/detectors/stateful-hbs.ts +177 -0
- package/src/evidence.ts +124 -0
- package/src/index.ts +5 -1
- package/src/inventory.ts +31 -1
- package/src/parallel.ts +15 -0
- package/src/redact.ts +125 -8
- package/src/registry.ts +4 -2
- package/src/remediate-pipeline.ts +55 -0
- package/src/remediation.ts +41 -9
- package/src/report.ts +41 -2
- package/src/scan.ts +21 -2
- package/src/types.ts +8 -1
- package/src/version.ts +1 -1
- package/src/worktree.ts +9 -1
package/dist/comments.js
CHANGED
|
@@ -90,6 +90,55 @@ export function commentSpans(content, style) {
|
|
|
90
90
|
}
|
|
91
91
|
return spans;
|
|
92
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Compute Python triple-quoted string spans (`"""…"""` / `'''…'''`). These are
|
|
95
|
+
* docstrings / prose in practice, so a crypto *name* mentioned inside one
|
|
96
|
+
* (`:param key_type: eg "ssh-ed25519"`) should not fire a token finding — but a
|
|
97
|
+
* PEM key pasted into one is still real material, so {@link stripCommentFindings}
|
|
98
|
+
* exempts `pem-*` rules. Comments and normal strings are skipped so a `"""`
|
|
99
|
+
* delimiter inside them is not mis-detected.
|
|
100
|
+
*/
|
|
101
|
+
export function pythonDocstringSpans(content) {
|
|
102
|
+
const spans = [];
|
|
103
|
+
const n = content.length;
|
|
104
|
+
let i = 0;
|
|
105
|
+
while (i < n) {
|
|
106
|
+
const c = content[i];
|
|
107
|
+
if (c === "#") {
|
|
108
|
+
i++;
|
|
109
|
+
while (i < n && content[i] !== "\n")
|
|
110
|
+
i++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if ((c === '"' || c === "'") && content[i + 1] === c && content[i + 2] === c) {
|
|
114
|
+
const start = i;
|
|
115
|
+
i += 3;
|
|
116
|
+
while (i < n && !(content[i] === c && content[i + 1] === c && content[i + 2] === c))
|
|
117
|
+
i++;
|
|
118
|
+
i = Math.min(n, i + 3);
|
|
119
|
+
spans.push([start, i]);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (c === '"' || c === "'") {
|
|
123
|
+
const q = c;
|
|
124
|
+
i++;
|
|
125
|
+
while (i < n) {
|
|
126
|
+
if (content[i] === "\\") {
|
|
127
|
+
i += 2;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (content[i] === q) {
|
|
131
|
+
i++;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
i++;
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
i++;
|
|
139
|
+
}
|
|
140
|
+
return spans;
|
|
141
|
+
}
|
|
93
142
|
/** True if `offset` falls inside one of the (sorted, non-overlapping) spans. */
|
|
94
143
|
export function offsetInSpans(spans, offset) {
|
|
95
144
|
let lo = 0;
|
|
@@ -146,7 +195,9 @@ export function stripCommentFindings(findings, content, file) {
|
|
|
146
195
|
if (!style)
|
|
147
196
|
return findings;
|
|
148
197
|
const spans = commentSpans(content, style);
|
|
149
|
-
|
|
198
|
+
// Python docstrings suppress prose *token* rules but keep real PEM material.
|
|
199
|
+
const docSpans = style === "hash" ? pythonDocstringSpans(content) : [];
|
|
200
|
+
if (spans.length === 0 && docSpans.length === 0)
|
|
150
201
|
return findings;
|
|
151
202
|
// 1-based line → start offset, to turn a finding's (line, column) back into an
|
|
152
203
|
// absolute offset (column is 1-based: offset = lineStart + column - 1).
|
|
@@ -158,6 +209,95 @@ export function stripCommentFindings(findings, content, file) {
|
|
|
158
209
|
return findings.filter((f) => {
|
|
159
210
|
const start = lineStarts[f.location.line - 1] ?? 0;
|
|
160
211
|
const offset = start + ((f.location.column ?? 1) - 1);
|
|
212
|
+
if (offsetInSpans(spans, offset))
|
|
213
|
+
return false;
|
|
214
|
+
if (docSpans.length > 0 && !f.ruleId.startsWith("pem-") && offsetInSpans(docSpans, offset)) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
return true;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Compute the string-literal spans (`[start, end)`) of `content`, skipping over
|
|
222
|
+
* comments so a quote inside a comment is not treated as a string. Used to
|
|
223
|
+
* suppress findings from IDENTIFIER-only rules (e.g. a Go `SigningMethodRS256`
|
|
224
|
+
* mentioned inside an error-message string) — the mirror of {@link commentSpans}.
|
|
225
|
+
*/
|
|
226
|
+
export function stringSpans(content, style) {
|
|
227
|
+
const spans = [];
|
|
228
|
+
const n = content.length;
|
|
229
|
+
let i = 0;
|
|
230
|
+
while (i < n) {
|
|
231
|
+
const c = content[i];
|
|
232
|
+
if (style === "c" && c === "/" && content[i + 1] === "/") {
|
|
233
|
+
i += 2;
|
|
234
|
+
while (i < n && content[i] !== "\n")
|
|
235
|
+
i++;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (style === "c" && c === "/" && content[i + 1] === "*") {
|
|
239
|
+
i += 2;
|
|
240
|
+
while (i < n && !(content[i] === "*" && content[i + 1] === "/"))
|
|
241
|
+
i++;
|
|
242
|
+
i = Math.min(n, i + 2);
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (style === "hash" && c === "#") {
|
|
246
|
+
i++;
|
|
247
|
+
while (i < n && content[i] !== "\n")
|
|
248
|
+
i++;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
252
|
+
const quote = c;
|
|
253
|
+
const start = i;
|
|
254
|
+
i++;
|
|
255
|
+
while (i < n) {
|
|
256
|
+
if (content[i] === "\\") {
|
|
257
|
+
i += 2;
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (content[i] === quote) {
|
|
261
|
+
i++;
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
i++;
|
|
265
|
+
}
|
|
266
|
+
spans.push([start, i]);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
i++;
|
|
270
|
+
}
|
|
271
|
+
return spans;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Drop findings of "code-only" rules (`ruleIds`) whose match starts inside a
|
|
275
|
+
* string literal. Some rules — an identifier-form JWT signing method, a Go
|
|
276
|
+
* `SigningMethodRS256` — are only meaningful as code; when the same token appears
|
|
277
|
+
* inside a string (a test's `t.Error("SigningMethodPS256 …")`) it is prose, not a
|
|
278
|
+
* usage. Rules that legitimately match inside strings (quoted `"RS256"` alg
|
|
279
|
+
* tokens, cipher-suite strings, ssh-key tokens) are NOT in `ruleIds` and pass
|
|
280
|
+
* through untouched.
|
|
281
|
+
*/
|
|
282
|
+
export function stripStringLiteralFindings(findings, content, file, ruleIds) {
|
|
283
|
+
if (findings.length === 0 || !findings.some((f) => ruleIds.has(f.ruleId)))
|
|
284
|
+
return findings;
|
|
285
|
+
const style = commentStyleForFile(file);
|
|
286
|
+
if (!style)
|
|
287
|
+
return findings;
|
|
288
|
+
const spans = stringSpans(content, style);
|
|
289
|
+
if (spans.length === 0)
|
|
290
|
+
return findings;
|
|
291
|
+
const lineStarts = [0];
|
|
292
|
+
for (let i = 0; i < content.length; i++) {
|
|
293
|
+
if (content[i] === "\n")
|
|
294
|
+
lineStarts.push(i + 1);
|
|
295
|
+
}
|
|
296
|
+
return findings.filter((f) => {
|
|
297
|
+
if (!ruleIds.has(f.ruleId))
|
|
298
|
+
return true;
|
|
299
|
+
const start = lineStarts[f.location.line - 1] ?? 0;
|
|
300
|
+
const offset = start + ((f.location.column ?? 1) - 1);
|
|
161
301
|
return !offsetInSpans(spans, offset);
|
|
162
302
|
});
|
|
163
303
|
}
|
package/dist/comments.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Comment-aware false-positive suppression.\n *\n * The detectors are lexical (regex over source text), so a crypto API name\n * written in a COMMENT — `// migrated off createECDH()` — fires a finding just\n * like real code. This module computes the comment spans of a file (respecting\n * string literals, so a `//` inside a string is not a comment) and drops any\n * finding whose match starts inside one.\n *\n * The lexer is deliberately conservative: it only ever ENTERS a comment on a\n * literal line comment, block comment, or `#` in code position (all of which ARE\n * comments), so it never mis-classifies code as a comment and can only reduce\n * false positives, not recall. The one inherent lexical ambiguity — a regex\n * literal that looks like a block-comment open — is rare and guarded by the\n * detection benchmark's recall gate.\n */\nimport type { Finding } from \"./types.js\";\n\nexport type CommentStyle = \"c\" | \"hash\";\n\n/** C-style (line + block) comment languages, by extension. */\nconst C_LIKE: readonly string[] = [\n \".js\",\n \".jsx\",\n \".ts\",\n \".tsx\",\n \".mjs\",\n \".cjs\",\n \".vue\",\n \".svelte\",\n \".go\",\n \".java\",\n \".kt\",\n \".kts\",\n \".cs\",\n \".rs\",\n \".c\",\n \".h\",\n \".cc\",\n \".cpp\",\n \".cxx\",\n \".hpp\",\n \".hh\",\n];\n\n/** Hash-style (`#`) comment languages, by extension. */\nconst HASH_LIKE: readonly string[] = [\".py\", \".pyi\", \".pyw\", \".rb\"];\n\n/** The comment style for a file path, or null when we don't strip comments for it. */\nexport function commentStyleForFile(file: string): CommentStyle | null {\n const lower = file.toLowerCase();\n if (C_LIKE.some((e) => lower.endsWith(e))) return \"c\";\n if (HASH_LIKE.some((e) => lower.endsWith(e))) return \"hash\";\n return null;\n}\n\n/**\n * Compute the comment spans (`[start, end)` offsets) of `content`, skipping over\n * string literals so a comment marker inside a string is not treated as a\n * comment. Spans are returned sorted and non-overlapping.\n */\nexport function commentSpans(content: string, style: CommentStyle): Array<[number, number]> {\n const spans: Array<[number, number]> = [];\n const n = content.length;\n let i = 0;\n while (i < n) {\n const c = content[i];\n // String / template literal: skip to the matching unescaped delimiter.\n if (c === '\"' || c === \"'\" || c === \"`\") {\n const quote = c;\n i++;\n while (i < n) {\n if (content[i] === \"\\\\\") {\n i += 2;\n continue;\n }\n if (content[i] === quote) {\n i++;\n break;\n }\n i++;\n }\n continue;\n }\n if (style === \"c\" && c === \"/\" && content[i + 1] === \"/\") {\n const start = i;\n i += 2;\n while (i < n && content[i] !== \"\\n\") i++;\n spans.push([start, i]);\n continue;\n }\n if (style === \"c\" && c === \"/\" && content[i + 1] === \"*\") {\n const start = i;\n i += 2;\n while (i < n && !(content[i] === \"*\" && content[i + 1] === \"/\")) i++;\n i = Math.min(n, i + 2);\n spans.push([start, i]);\n continue;\n }\n if (style === \"hash\" && c === \"#\") {\n const start = i;\n i++;\n while (i < n && content[i] !== \"\\n\") i++;\n spans.push([start, i]);\n continue;\n }\n i++;\n }\n return spans;\n}\n\n/**\n * Compute Python triple-quoted string spans (`\"\"\"…\"\"\"` / `'''…'''`). These are\n * docstrings / prose in practice, so a crypto *name* mentioned inside one\n * (`:param key_type: eg \"ssh-ed25519\"`) should not fire a token finding — but a\n * PEM key pasted into one is still real material, so {@link stripCommentFindings}\n * exempts `pem-*` rules. Comments and normal strings are skipped so a `\"\"\"`\n * delimiter inside them is not mis-detected.\n */\nexport function pythonDocstringSpans(content: string): Array<[number, number]> {\n const spans: Array<[number, number]> = [];\n const n = content.length;\n let i = 0;\n while (i < n) {\n const c = content[i];\n if (c === \"#\") {\n i++;\n while (i < n && content[i] !== \"\\n\") i++;\n continue;\n }\n if ((c === '\"' || c === \"'\") && content[i + 1] === c && content[i + 2] === c) {\n const start = i;\n i += 3;\n while (i < n && !(content[i] === c && content[i + 1] === c && content[i + 2] === c)) i++;\n i = Math.min(n, i + 3);\n spans.push([start, i]);\n continue;\n }\n if (c === '\"' || c === \"'\") {\n const q = c;\n i++;\n while (i < n) {\n if (content[i] === \"\\\\\") {\n i += 2;\n continue;\n }\n if (content[i] === q) {\n i++;\n break;\n }\n i++;\n }\n continue;\n }\n i++;\n }\n return spans;\n}\n\n/** True if `offset` falls inside one of the (sorted, non-overlapping) spans. */\nexport function offsetInSpans(spans: ReadonlyArray<[number, number]>, offset: number): boolean {\n let lo = 0;\n let hi = spans.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const [s, e] = spans[mid];\n if (offset < s) hi = mid - 1;\n else if (offset >= e) lo = mid + 1;\n else return true;\n }\n return false;\n}\n\n/**\n * Line numbers (1-based) suppressed by an inline ignore directive:\n * - `qscan-ignore-line` on a line suppresses findings on THAT line.\n * - `qscan-ignore-next-line` on a line suppresses findings on the NEXT line.\n * The directive text is matched anywhere on the line (usually in a comment), so\n * it is language-agnostic. `qscan-ignore-line` is not a substring of\n * `qscan-ignore-next-line`, so the two never collide.\n */\nexport function ignoredLines(content: string): Set<number> {\n const ignored = new Set<number>();\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes(\"qscan-ignore-next-line\")) ignored.add(i + 2);\n else if (line.includes(\"qscan-ignore-line\")) ignored.add(i + 1);\n }\n return ignored;\n}\n\n/** Drop findings on lines suppressed by an inline `qscan-ignore` directive. */\nexport function stripIgnoredFindings(findings: Finding[], content: string): Finding[] {\n if (findings.length === 0 || !content.includes(\"qscan-ignore\")) return findings;\n const ignored = ignoredLines(content);\n if (ignored.size === 0) return findings;\n return findings.filter((f) => !ignored.has(f.location.line));\n}\n\n/**\n * Drop findings whose match starts inside a comment. No-op when the file's\n * language has no comment style we handle, or when it has no comments.\n */\nexport function stripCommentFindings(\n findings: Finding[],\n content: string,\n file: string,\n): Finding[] {\n if (findings.length === 0) return findings;\n const style = commentStyleForFile(file);\n if (!style) return findings;\n const spans = commentSpans(content, style);\n // Python docstrings suppress prose *token* rules but keep real PEM material.\n const docSpans = style === \"hash\" ? pythonDocstringSpans(content) : [];\n if (spans.length === 0 && docSpans.length === 0) return findings;\n\n // 1-based line → start offset, to turn a finding's (line, column) back into an\n // absolute offset (column is 1-based: offset = lineStart + column - 1).\n const lineStarts: number[] = [0];\n for (let i = 0; i < content.length; i++) {\n if (content[i] === \"\\n\") lineStarts.push(i + 1);\n }\n\n return findings.filter((f) => {\n const start = lineStarts[f.location.line - 1] ?? 0;\n const offset = start + ((f.location.column ?? 1) - 1);\n if (offsetInSpans(spans, offset)) return false;\n if (docSpans.length > 0 && !f.ruleId.startsWith(\"pem-\") && offsetInSpans(docSpans, offset)) {\n return false;\n }\n return true;\n });\n}\n\n/**\n * Compute the string-literal spans (`[start, end)`) of `content`, skipping over\n * comments so a quote inside a comment is not treated as a string. Used to\n * suppress findings from IDENTIFIER-only rules (e.g. a Go `SigningMethodRS256`\n * mentioned inside an error-message string) — the mirror of {@link commentSpans}.\n */\nexport function stringSpans(content: string, style: CommentStyle): Array<[number, number]> {\n const spans: Array<[number, number]> = [];\n const n = content.length;\n let i = 0;\n while (i < n) {\n const c = content[i];\n if (style === \"c\" && c === \"/\" && content[i + 1] === \"/\") {\n i += 2;\n while (i < n && content[i] !== \"\\n\") i++;\n continue;\n }\n if (style === \"c\" && c === \"/\" && content[i + 1] === \"*\") {\n i += 2;\n while (i < n && !(content[i] === \"*\" && content[i + 1] === \"/\")) i++;\n i = Math.min(n, i + 2);\n continue;\n }\n if (style === \"hash\" && c === \"#\") {\n i++;\n while (i < n && content[i] !== \"\\n\") i++;\n continue;\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n const quote = c;\n const start = i;\n i++;\n while (i < n) {\n if (content[i] === \"\\\\\") {\n i += 2;\n continue;\n }\n if (content[i] === quote) {\n i++;\n break;\n }\n i++;\n }\n spans.push([start, i]);\n continue;\n }\n i++;\n }\n return spans;\n}\n\n/**\n * Drop findings of \"code-only\" rules (`ruleIds`) whose match starts inside a\n * string literal. Some rules — an identifier-form JWT signing method, a Go\n * `SigningMethodRS256` — are only meaningful as code; when the same token appears\n * inside a string (a test's `t.Error(\"SigningMethodPS256 …\")`) it is prose, not a\n * usage. Rules that legitimately match inside strings (quoted `\"RS256\"` alg\n * tokens, cipher-suite strings, ssh-key tokens) are NOT in `ruleIds` and pass\n * through untouched.\n */\nexport function stripStringLiteralFindings(\n findings: Finding[],\n content: string,\n file: string,\n ruleIds: ReadonlySet<string>,\n): Finding[] {\n if (findings.length === 0 || !findings.some((f) => ruleIds.has(f.ruleId))) return findings;\n const style = commentStyleForFile(file);\n if (!style) return findings;\n const spans = stringSpans(content, style);\n if (spans.length === 0) return findings;\n\n const lineStarts: number[] = [0];\n for (let i = 0; i < content.length; i++) {\n if (content[i] === \"\\n\") lineStarts.push(i + 1);\n }\n\n return findings.filter((f) => {\n if (!ruleIds.has(f.ruleId)) return true;\n const start = lineStarts[f.location.line - 1] ?? 0;\n const offset = start + ((f.location.column ?? 1) - 1);\n return !offsetInSpans(spans, offset);\n });\n}\n"]}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAE1D,uEAAuE;AACvE,MAAM,UAAU,GAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAEtF,yEAAyE;AACzE,MAAM,iBAAiB,GAAG;IACxB,aAAa;IACb,WAAW;IACX,aAAa;IACb,UAAU;IACV,YAAY;IACZ,cAAc;IACd,cAAc;CACN,CAAC;AA2CX,+EAA+E;AAC/E,MAAM,OAAO,WAAY,SAAQ,KAAK;IAClB,IAAI,GAAG,aAAa,CAAC;IACvC,6DAA6D;IACpD,IAAI,CAAqB;IAClC,YAAY,OAAe,EAAE,UAAmB;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,8EAA8E;AAC9E,SAAS,MAAM,CAAC,GAA4B,EAAE,GAAW,EAAE,IAAY;IACrE,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,WAAW,CAAC,IAAI,GAAG,4BAA4B,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,uDAAuD;AACvD,SAAS,KAAK,CAAC,GAA4B,EAAE,GAAW,EAAE,IAAY;IACpE,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,WAAW,CAAC,IAAI,GAAG,kCAAkC,EAAE,IAAI,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,4EAA4E;AAC5E,SAAS,aAAa,CACpB,GAA4B,EAC5B,GAAW,EACX,IAAY;IAEZ,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,WAAW,CAAC,IAAI,GAAG,+BAA+B,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAChB,GAA4B,EAC5B,IAAY,EACZ,QAAkB;IAElB,kEAAkE;IAClE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC;QACpB,SAAS;QACT,SAAS;QACT,SAAS;QACT,SAAS;QACT,kBAAkB;QAClB,aAAa;QACb,cAAc;QACd,WAAW;QACX,eAAe;QACf,WAAW;QACX,mBAAmB;QACnB,UAAU;KACX,CAAC,CAAC;IACH,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,uBAAuB,GAAG,WAAW,CAAC,CAAC;IAC5E,CAAC;IAED,8CAA8C;IAC9C,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,WAAW,CAAC,8BAA8B,EAAE,IAAI,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC,oBAAoB,OAAO,2CAA2C,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACpD,IAAI,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IACnC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACpD,IAAI,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IAEnC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,gBAAgB,KAAK,SAAS;QAAE,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC5E,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;IACvD,IAAI,YAAY,KAAK,SAAS;QAAE,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;IAEhE,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IACpD,IAAI,WAAW,KAAK,SAAS;QAAE,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;IAE7D,8EAA8E;IAC9E,6EAA6E;IAC7E,2EAA2E;IAC3E,4CAA4C;IAC5C,4EAA4E;IAC5E,yEAAyE;IACzE,+EAA+E;IAC/E,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,WAAW,CAAC,iDAAiD,EAAE,IAAI,CAAC,CAAC;QACjF,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,IAAI,CAAE,iBAAuC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5D,QAAQ,CAAC,IAAI,CAAC,4BAA4B,GAAG,WAAW,CAAC,CAAC;gBAC1D,SAAS;YACX,CAAC;YACD,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,IAAI,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,WAAW,CAAC,cAAc,GAAG,qBAAqB,EAAE,IAAI,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,CAAC;gBAAE,SAAS,CAAC,sCAAsC;YACvD,QAAQ,GAAG,EAAE,CAAC;gBACZ,KAAK,cAAc;oBACjB,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;oBACzB,MAAM;gBACR,KAAK,YAAY,CAAC;gBAClB,KAAK,cAAc;oBACjB,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;oBACnB,MAAM;gBACR;oBACE,qEAAqE;oBACrE,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;oBACnB,MAAM;YACV,CAAC;QACH,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,aAAa,GAAG,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;IAChE,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,aAAa,GAAG,aAAa,CAAC;IAEjF,+EAA+E;IAC/E,qEAAqE;IACrE,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACxD,IAAI,SAAS;QAAE,QAAQ,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAE9F,2BAA2B;IAC3B,IAAI,mBAAmB,IAAI,GAAG,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAE,UAAgC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,WAAW,CAAC,uCAAuC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9F,CAAC;QACD,GAAG,CAAC,iBAAiB,GAAG,GAAe,CAAC;IAC1C,CAAC;IAED,2EAA2E;IAC3E,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,WAAW,CAAC,4CAA4C,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QACD,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChG,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,OAA+B,EAAE;IAEjC,6EAA6E;IAC7E,6DAA6D;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,IAAI,GACR,IAAI,KAAK,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAChD,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAE1C,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,WAAW,CAAC,0BAA0B,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,kCAAkC;IACzE,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,WAAW,CAAC,mBAAmB,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,WAAW,CAAC,qCAAqC,OAAO,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC1C,CAAC","sourcesContent":["/**\n * `quantakrypto.config.json` loader (ROADMAP P2-9, see docs/CONFIG.md).\n *\n * Reads an optional project configuration file, validates the *types* of known\n * keys, ignores unknown keys (forward compatibility), and maps it onto a\n * `Partial<ScanOptions>` plus the two policy keys qScan consumes\n * (`severityThreshold`, `baseline`). It performs NO scanning and has no\n * side-effects beyond a single `readFile`.\n *\n * Precedence (resolved by the consumer, not here): flags > config > defaults.\n *\n * The parsed object is treated as **untrusted input** in the same spirit as a\n * scanned manifest (THREAT-MODEL Q-09): we only membership-test known keys and\n * never deep-merge the parsed object into anything.\n */\nimport { readFile } from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nimport type { ScanOptions, Severity } from \"./types.js\";\n\n/** Canonical config file name discovered at a scan root. */\nexport const CONFIG_FILENAME = \"quantakrypto.config.json\";\n\n/** Severity levels accepted by `severityThreshold`, for validation. */\nconst SEVERITIES: readonly Severity[] = [\"critical\", \"high\", \"medium\", \"low\", \"info\"];\n\n/** Detector-family toggle names recognised in the `detectors` object. */\nconst DETECTOR_FAMILIES = [\n \"node-crypto\",\n \"webcrypto\",\n \"crypto-libs\",\n \"jwt-jose\",\n \"tls-config\",\n \"pem-material\",\n \"dependencies\",\n] as const;\n\n/**\n * The slice of options a `quantakrypto.config.json` can set. A subset of\n * {@link ScanOptions} (the file-selection + scope keys) extended with the two\n * policy keys qScan owns: `severityThreshold` and `baseline`.\n *\n * `root`, `files`, `detectors` (the programmatic detector array), and `onFile`\n * are intentionally NOT configurable from a file — they are call-site concerns.\n */\nexport interface QuantakryptoFileConfig extends Partial<\n Pick<\n ScanOptions,\n | \"include\"\n | \"exclude\"\n | \"noDefaultIgnores\"\n | \"maxFileSize\"\n | \"scanMinified\"\n | \"source\"\n | \"dependencies\"\n | \"config\"\n | \"disabledRules\"\n >\n> {\n /** Gate severity (drives the exit code). Maps to qScan's `severityThreshold`. */\n severityThreshold?: Severity;\n /** Path to a baseline file, relative to the config file's directory. */\n baseline?: string;\n}\n\n/** Result of {@link loadConfig}: the resolved config plus where it came from. */\nexport interface LoadConfigResult {\n /** Validated, mapped config. Empty object when no file was found. */\n config: QuantakryptoFileConfig;\n /** Absolute path of the file that was loaded, when one was. */\n path?: string;\n /**\n * Non-fatal warnings (unknown keys, unknown future `version`). The caller may\n * surface these; they never abort the load.\n */\n warnings: string[];\n}\n\n/** Thrown when a known key has a malformed *value* (a usage error: exit 2). */\nexport class ConfigError extends Error {\n override readonly name = \"ConfigError\";\n /** The config file path the error relates to, when known. */\n readonly path: string | undefined;\n constructor(message: string, configPath?: string) {\n super(message);\n this.path = configPath;\n }\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Validate an optional boolean field; returns it or undefined, or throws. */\nfunction asBool(obj: Record<string, unknown>, key: string, file: string): boolean | undefined {\n if (!(key in obj)) return undefined;\n const v = obj[key];\n if (typeof v !== \"boolean\") {\n throw new ConfigError(`\"${key}\" must be a boolean (got ${typeof v})`, file);\n }\n return v;\n}\n\n/** Validate an optional non-negative-integer field. */\nfunction asInt(obj: Record<string, unknown>, key: string, file: string): number | undefined {\n if (!(key in obj)) return undefined;\n const v = obj[key];\n if (typeof v !== \"number\" || !Number.isInteger(v) || v < 0) {\n throw new ConfigError(`\"${key}\" must be a non-negative integer`, file);\n }\n return v;\n}\n\n/** Validate an optional string[] field (every element must be a string). */\nfunction asStringArray(\n obj: Record<string, unknown>,\n key: string,\n file: string,\n): string[] | undefined {\n if (!(key in obj)) return undefined;\n const v = obj[key];\n if (!Array.isArray(v) || !v.every((x): x is string => typeof x === \"string\")) {\n throw new ConfigError(`\"${key}\" must be an array of strings`, file);\n }\n return [...v];\n}\n\n/**\n * Map the validated raw JSON object onto a {@link QuantakryptoFileConfig}. Throws\n * {@link ConfigError} on a malformed *value* for any known key; collects\n * warnings for unknown keys and unrecognised `version`.\n */\nfunction mapConfig(\n raw: Record<string, unknown>,\n file: string,\n warnings: string[],\n): QuantakryptoFileConfig {\n // Known top-level keys. Anything else is a warning, not an error.\n const KNOWN = new Set([\n \"$schema\",\n \"version\",\n \"include\",\n \"exclude\",\n \"noDefaultIgnores\",\n \"maxFileSize\",\n \"scanMinified\",\n \"detectors\",\n \"disabledRules\",\n \"languages\",\n \"severityThreshold\",\n \"baseline\",\n ]);\n for (const key of Object.keys(raw)) {\n if (!KNOWN.has(key)) warnings.push(`unknown config key \"${key}\" ignored`);\n }\n\n // version: known forward-compat warning only.\n if (\"version\" in raw) {\n const version = raw[\"version\"];\n if (typeof version !== \"number\" || !Number.isInteger(version)) {\n throw new ConfigError(`\"version\" must be an integer`, file);\n }\n if (version !== 1) {\n warnings.push(`config \"version\" ${version} is newer than supported (1); best-effort`);\n }\n }\n\n const out: QuantakryptoFileConfig = {};\n\n const include = asStringArray(raw, \"include\", file);\n if (include) out.include = include;\n const exclude = asStringArray(raw, \"exclude\", file);\n if (exclude) out.exclude = exclude;\n\n const noDefaultIgnores = asBool(raw, \"noDefaultIgnores\", file);\n if (noDefaultIgnores !== undefined) out.noDefaultIgnores = noDefaultIgnores;\n const scanMinified = asBool(raw, \"scanMinified\", file);\n if (scanMinified !== undefined) out.scanMinified = scanMinified;\n\n const maxFileSize = asInt(raw, \"maxFileSize\", file);\n if (maxFileSize !== undefined) out.maxFileSize = maxFileSize;\n\n // detectors.<family> bool map → source / dependencies / config scope toggles.\n // A family turned off is equivalent to its `--no-*` flag (per docs/CONFIG.md\n // §4.1). We collapse the per-family map onto the three scan-scope toggles:\n // dependencies → ScanOptions.dependencies\n // pem-material + tls-config → ScanOptions.config (config-scope detectors)\n // the JS source families → ScanOptions.source (source-scope detectors)\n // Only an explicit `false` flips a toggle off; absent/true leaves the default.\n if (\"detectors\" in raw) {\n const det = raw[\"detectors\"];\n if (!isObject(det)) {\n throw new ConfigError(`\"detectors\" must be an object of family→boolean`, file);\n }\n for (const key of Object.keys(det)) {\n if (!(DETECTOR_FAMILIES as readonly string[]).includes(key)) {\n warnings.push(`unknown detector family \"${key}\" ignored`);\n continue;\n }\n const v = det[key];\n if (typeof v !== \"boolean\") {\n throw new ConfigError(`\"detectors.${key}\" must be a boolean`, file);\n }\n if (v) continue; // true = default; nothing to disable.\n switch (key) {\n case \"dependencies\":\n out.dependencies = false;\n break;\n case \"tls-config\":\n case \"pem-material\":\n out.config = false;\n break;\n default:\n // node-crypto / webcrypto / crypto-libs / jwt-jose are source-scope.\n out.source = false;\n break;\n }\n }\n }\n\n // disabledRules: rule ids to suppress, threaded to ScanOptions.disabledRules.\n // Unknown ids are harmless (they never match), so we accept the list as-is —\n // this also lets a config forward-reference a rule added in a later version.\n const disabledRules = asStringArray(raw, \"disabledRules\", file);\n if (disabledRules && disabledRules.length > 0) out.disabledRules = disabledRules;\n\n // languages: forward-looking (inert until the plugin registry lands). Validate\n // the type so the file format is stable, but do not map it anywhere.\n const languages = asStringArray(raw, \"languages\", file);\n if (languages) warnings.push(`\"languages\" is accepted but inert until detector plugins land`);\n\n // severityThreshold: enum.\n if (\"severityThreshold\" in raw) {\n const sev = raw[\"severityThreshold\"];\n if (typeof sev !== \"string\" || !(SEVERITIES as readonly string[]).includes(sev)) {\n throw new ConfigError(`\"severityThreshold\" must be one of: ${SEVERITIES.join(\", \")}`, file);\n }\n out.severityThreshold = sev as Severity;\n }\n\n // baseline: path string, resolved relative to the config file's directory.\n if (\"baseline\" in raw) {\n const baseline = raw[\"baseline\"];\n if (typeof baseline !== \"string\" || baseline.length === 0) {\n throw new ConfigError(`\"baseline\" must be a non-empty path string`, file);\n }\n out.baseline = path.isAbsolute(baseline) ? baseline : path.join(path.dirname(file), baseline);\n }\n\n return out;\n}\n\n/**\n * Load a `quantakrypto.config.json` for a scan.\n *\n * By default reads `<root>/quantakrypto.config.json`. Pass an explicit file path as\n * `root` (or via the caller's `--config` flag) to read a named file instead —\n * if the path's basename is `quantakrypto.config.json` it is read directly; otherwise\n * the path is treated as a directory and the file is looked up inside it. When\n * an explicit path is given but missing, that is an error; an *absent*\n * auto-discovered file is tolerated (returns an empty config).\n *\n * @param root Directory to look in, OR an explicit config file path.\n * @param opts.explicit When true, a missing file is an error (the user named it).\n * @throws {ConfigError} On malformed JSON, a bad value for a known key, or a\n * missing explicitly-named file.\n */\nexport async function loadConfig(\n root: string,\n opts: { explicit?: boolean } = {},\n): Promise<LoadConfigResult> {\n // Resolve the file path: an explicit *.json file is used verbatim; otherwise\n // treat `root` as a directory and append the canonical name.\n const base = path.basename(root);\n const file =\n base === CONFIG_FILENAME || base.endsWith(\".json\")\n ? path.resolve(root)\n : path.resolve(root, CONFIG_FILENAME);\n\n let text: string;\n try {\n text = await readFile(file, \"utf8\");\n } catch {\n if (opts.explicit) {\n throw new ConfigError(`config file not found: ${file}`, file);\n }\n return { config: {}, warnings: [] }; // tolerant when auto-discovering.\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n throw new ConfigError(`invalid JSON in ${file}: ${(err as Error).message}`, file);\n }\n if (!isObject(parsed)) {\n throw new ConfigError(`config must be a JSON object, got ${typeof parsed}`, file);\n }\n\n const warnings: string[] = [];\n const config = mapConfig(parsed, file, warnings);\n return { config, path: file, warnings };\n}\n"]}
|
package/dist/cwe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cwe.js","sourceRoot":"","sources":["../src/cwe.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,iEAAiE;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,+CAA+C;AAC/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,gDAAgD;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"cwe.js","sourceRoot":"","sources":["../src/cwe.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,iEAAiE;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,+CAA+C;AAC/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,gDAAgD;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC","sourcesContent":["/**\n * CWE (Common Weakness Enumeration) identifiers used to tag findings. These\n * feed SARIF rule taxa / properties and the CBOM export, and let downstream\n * compliance tooling map quantaKrypto findings to a standard weakness taxonomy.\n */\n\n/** CWE-327: Use of a Broken or Risky Cryptographic Algorithm. */\nexport const CWE_BROKEN_CRYPTO = \"CWE-327\";\n\n/** CWE-326: Inadequate Encryption Strength. */\nexport const CWE_WEAK_STRENGTH = \"CWE-326\";\n\n/** CWE-295: Improper Certificate Validation. */\nexport const CWE_CERT_VALIDATION = \"CWE-295\";\n\n/** CWE-798: Use of Hard-coded Credentials (embedded private keys). */\nexport const CWE_HARDCODED_KEY = \"CWE-798\";\n\n/** CWE-1240: Use of a Cryptographic Primitive with a Risky Implementation. */\nexport const CWE_RISKY_PRIMITIVE = \"CWE-1240\";\n"]}
|
package/dist/dependencies.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Curated database of packages that primarily expose classical asymmetric
|
|
3
3
|
* cryptography (and are therefore quantum-vulnerable), across multiple
|
|
4
|
-
* ecosystems (npm, PyPI, crates.io, Go modules, Maven, RubyGems), plus a
|
|
4
|
+
* ecosystems (npm, PyPI, crates.io, Go modules, Maven, RubyGems, NuGet), plus a
|
|
5
5
|
* manifest scanner that flags any of them found in the corresponding manifest
|
|
6
|
-
* (package.json, requirements.txt, Cargo.toml, go.mod, pom.xml, Gemfile,
|
|
6
|
+
* (package.json, requirements.txt, Cargo.toml, go.mod, pom.xml, Gemfile,
|
|
7
|
+
* packages.config / *.csproj, …).
|
|
7
8
|
*
|
|
8
9
|
* The list is intentionally focused on libraries whose *purpose* is classical
|
|
9
10
|
* public-key crypto. General-purpose packages that merely call the language's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../src/dependencies.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../src/dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAEV,mBAAmB,EACnB,OAAO,EACP,QAAQ,EACR,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAkBjC,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,EAAE,oBAAoB,EAyjBxD,CAAC;AAuEF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAoB1E;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAuID;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAyBrE"}
|
package/dist/dependencies.js
CHANGED
|
@@ -76,6 +76,7 @@ export const vulnerableDependencies = [
|
|
|
76
76
|
reason: "JWTs commonly signed with RS256/ES256 (classical RSA/ECDSA).",
|
|
77
77
|
algorithms: ["RSA", "ECDSA"],
|
|
78
78
|
severity: "high",
|
|
79
|
+
hndl: false,
|
|
79
80
|
},
|
|
80
81
|
{
|
|
81
82
|
name: "jose",
|
|
@@ -90,6 +91,7 @@ export const vulnerableDependencies = [
|
|
|
90
91
|
reason: "JSON Web Signatures using classical RS/ES algorithms.",
|
|
91
92
|
algorithms: ["RSA", "ECDSA"],
|
|
92
93
|
severity: "high",
|
|
94
|
+
hndl: false,
|
|
93
95
|
},
|
|
94
96
|
{
|
|
95
97
|
name: "eccrypto",
|
|
@@ -146,6 +148,7 @@ export const vulnerableDependencies = [
|
|
|
146
148
|
reason: "PASETO public tokens signed with classical Ed25519 (v2/v4) or RSA.",
|
|
147
149
|
algorithms: ["EdDSA", "RSA"],
|
|
148
150
|
severity: "medium",
|
|
151
|
+
hndl: false,
|
|
149
152
|
},
|
|
150
153
|
{
|
|
151
154
|
name: "bcrypto",
|
|
@@ -216,6 +219,7 @@ export const vulnerableDependencies = [
|
|
|
216
219
|
reason: "JSON Web Algorithms: RSA (RS/PS) and EC (ES) signatures.",
|
|
217
220
|
algorithms: ["RSA", "ECDSA"],
|
|
218
221
|
severity: "medium",
|
|
222
|
+
hndl: false,
|
|
219
223
|
},
|
|
220
224
|
{
|
|
221
225
|
name: "jwk-to-pem",
|
|
@@ -230,6 +234,7 @@ export const vulnerableDependencies = [
|
|
|
230
234
|
reason: "JWT signing/verification with classical RS/PS/ES algorithms.",
|
|
231
235
|
algorithms: ["RSA", "ECDSA"],
|
|
232
236
|
severity: "medium",
|
|
237
|
+
hndl: false,
|
|
233
238
|
},
|
|
234
239
|
{
|
|
235
240
|
name: "ssh2",
|
|
@@ -258,6 +263,7 @@ export const vulnerableDependencies = [
|
|
|
258
263
|
reason: "HTTP request signing with classical RSA/ECDSA keys.",
|
|
259
264
|
algorithms: ["RSA", "ECDSA"],
|
|
260
265
|
severity: "medium",
|
|
266
|
+
hndl: false,
|
|
261
267
|
},
|
|
262
268
|
{
|
|
263
269
|
name: "libsodium-wrappers",
|
|
@@ -281,6 +287,28 @@ export const vulnerableDependencies = [
|
|
|
281
287
|
algorithms: ["RSA", "ECDSA", "DSA"],
|
|
282
288
|
severity: "high",
|
|
283
289
|
},
|
|
290
|
+
{
|
|
291
|
+
name: "pycrypto",
|
|
292
|
+
ecosystem: "pypi",
|
|
293
|
+
reason: "Abandoned/unmaintained crypto library — classical RSA/DSA/ElGamal.",
|
|
294
|
+
algorithms: ["RSA", "DSA"],
|
|
295
|
+
severity: "high",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "jwcrypto",
|
|
299
|
+
ecosystem: "pypi",
|
|
300
|
+
reason: "JWK / JWS / JWE with classical RS*/ES* and ECDH-ES key agreement.",
|
|
301
|
+
algorithms: ["RSA", "ECDSA", "ECDH"],
|
|
302
|
+
severity: "medium",
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "authlib",
|
|
306
|
+
ecosystem: "pypi",
|
|
307
|
+
reason: "OAuth / OIDC / JOSE stack using classical RS*/ES* JWT signing.",
|
|
308
|
+
algorithms: ["RSA", "ECDSA"],
|
|
309
|
+
severity: "medium",
|
|
310
|
+
hndl: false,
|
|
311
|
+
},
|
|
284
312
|
{
|
|
285
313
|
name: "pycryptodomex",
|
|
286
314
|
ecosystem: "pypi",
|
|
@@ -315,6 +343,7 @@ export const vulnerableDependencies = [
|
|
|
315
343
|
reason: "JWT signing with classical RS*/ES* algorithms.",
|
|
316
344
|
algorithms: ["RSA", "ECDSA"],
|
|
317
345
|
severity: "medium",
|
|
346
|
+
hndl: false,
|
|
318
347
|
},
|
|
319
348
|
{
|
|
320
349
|
name: "python-jose",
|
|
@@ -387,6 +416,13 @@ export const vulnerableDependencies = [
|
|
|
387
416
|
algorithms: ["ECDSA", "ECDH"],
|
|
388
417
|
severity: "high",
|
|
389
418
|
},
|
|
419
|
+
{
|
|
420
|
+
name: "secp256k1",
|
|
421
|
+
ecosystem: "cargo",
|
|
422
|
+
reason: "libsecp256k1 bindings (blockchain) — classical ECDSA + ECDH.",
|
|
423
|
+
algorithms: ["ECDSA", "ECDH"],
|
|
424
|
+
severity: "high",
|
|
425
|
+
},
|
|
390
426
|
{
|
|
391
427
|
name: "ed25519-dalek",
|
|
392
428
|
ecosystem: "cargo",
|
|
@@ -409,6 +445,43 @@ export const vulnerableDependencies = [
|
|
|
409
445
|
algorithms: ["RSA", "ECDSA", "EdDSA", "ECDH"],
|
|
410
446
|
severity: "medium",
|
|
411
447
|
},
|
|
448
|
+
{
|
|
449
|
+
name: "github.com/golang-jwt/jwt/v5",
|
|
450
|
+
ecosystem: "go",
|
|
451
|
+
reason: "golang-jwt — classical RS*/PS*/ES* JWT algorithms.",
|
|
452
|
+
algorithms: ["RSA", "ECDSA"],
|
|
453
|
+
severity: "medium",
|
|
454
|
+
hndl: false,
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
name: "github.com/golang-jwt/jwt/v4",
|
|
458
|
+
ecosystem: "go",
|
|
459
|
+
reason: "golang-jwt (v4) — classical RS*/PS*/ES* JWT algorithms.",
|
|
460
|
+
algorithms: ["RSA", "ECDSA"],
|
|
461
|
+
severity: "medium",
|
|
462
|
+
hndl: false,
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
name: "github.com/go-jose/go-jose/v4",
|
|
466
|
+
ecosystem: "go",
|
|
467
|
+
reason: "go-jose — classical JOSE (RSA/ECDSA signatures, ECDH-ES key agreement).",
|
|
468
|
+
algorithms: ["RSA", "ECDSA", "ECDH"],
|
|
469
|
+
severity: "medium",
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
name: "github.com/cloudflare/circl",
|
|
473
|
+
ecosystem: "go",
|
|
474
|
+
reason: "Cloudflare CIRCL — classical ECDH/EdDSA curves (X25519, X448, Ed25519, P-256).",
|
|
475
|
+
algorithms: ["ECDH", "EdDSA"],
|
|
476
|
+
severity: "medium",
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
name: "github.com/decred/dcrd/dcrec/secp256k1/v4",
|
|
480
|
+
ecosystem: "go",
|
|
481
|
+
reason: "decred secp256k1 — classical ECDSA/ECDH on the secp256k1 curve (blockchain keys).",
|
|
482
|
+
algorithms: ["ECDSA", "ECDH"],
|
|
483
|
+
severity: "medium",
|
|
484
|
+
},
|
|
412
485
|
// --- Maven (Java) ---
|
|
413
486
|
{
|
|
414
487
|
name: "bcprov-jdk18on",
|
|
@@ -437,6 +510,22 @@ export const vulnerableDependencies = [
|
|
|
437
510
|
reason: "Auth0 JWT with classical RS*/ES* algorithms.",
|
|
438
511
|
algorithms: ["RSA", "ECDSA"],
|
|
439
512
|
severity: "medium",
|
|
513
|
+
hndl: false,
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
name: "nimbus-jose-jwt",
|
|
517
|
+
ecosystem: "maven",
|
|
518
|
+
reason: "Nimbus JOSE+JWT — classical RS*/PS*/ES* JWS and RSA/ECDH-ES JWE.",
|
|
519
|
+
algorithms: ["RSA", "ECDSA", "ECDH"],
|
|
520
|
+
severity: "medium",
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "jjwt-api",
|
|
524
|
+
ecosystem: "maven",
|
|
525
|
+
reason: "JJWT (io.jsonwebtoken) — classical RS*/ES* JWT signing.",
|
|
526
|
+
algorithms: ["RSA", "ECDSA"],
|
|
527
|
+
severity: "medium",
|
|
528
|
+
hndl: false,
|
|
440
529
|
},
|
|
441
530
|
// --- RubyGems ---
|
|
442
531
|
{
|
|
@@ -445,6 +534,14 @@ export const vulnerableDependencies = [
|
|
|
445
534
|
reason: "Ruby JWT with classical RS*/ES* algorithms.",
|
|
446
535
|
algorithms: ["RSA", "ECDSA"],
|
|
447
536
|
severity: "medium",
|
|
537
|
+
hndl: false,
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
name: "net-ssh",
|
|
541
|
+
ecosystem: "rubygems",
|
|
542
|
+
reason: "Ruby SSH client — classical host/user keys (RSA/ECDSA/Ed25519) and ECDH/DH key exchange.",
|
|
543
|
+
algorithms: ["RSA", "ECDSA", "ECDH"],
|
|
544
|
+
severity: "medium",
|
|
448
545
|
},
|
|
449
546
|
{
|
|
450
547
|
name: "rbnacl",
|
|
@@ -460,12 +557,44 @@ export const vulnerableDependencies = [
|
|
|
460
557
|
algorithms: ["EdDSA"],
|
|
461
558
|
severity: "low",
|
|
462
559
|
},
|
|
560
|
+
// --- NuGet (.NET) ---
|
|
561
|
+
{
|
|
562
|
+
name: "BouncyCastle.Cryptography",
|
|
563
|
+
ecosystem: "nuget",
|
|
564
|
+
reason: "BouncyCastle for .NET — full classical RSA/ECDSA/ECDH/DSA suite.",
|
|
565
|
+
algorithms: ["RSA", "ECDSA", "ECDH", "DSA"],
|
|
566
|
+
severity: "high",
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
name: "Portable.BouncyCastle",
|
|
570
|
+
ecosystem: "nuget",
|
|
571
|
+
reason: "Portable BouncyCastle for .NET — classical RSA/ECDSA/ECDH/DSA.",
|
|
572
|
+
algorithms: ["RSA", "ECDSA", "ECDH", "DSA"],
|
|
573
|
+
severity: "high",
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
name: "System.IdentityModel.Tokens.Jwt",
|
|
577
|
+
ecosystem: "nuget",
|
|
578
|
+
reason: "Microsoft JWT handler — classical RS*/ES* (RSA/ECDSA) signatures.",
|
|
579
|
+
algorithms: ["RSA", "ECDSA"],
|
|
580
|
+
severity: "medium",
|
|
581
|
+
hndl: false,
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
name: "Microsoft.IdentityModel.Tokens",
|
|
585
|
+
ecosystem: "nuget",
|
|
586
|
+
reason: "Microsoft IdentityModel token crypto — classical RSA/ECDSA keys.",
|
|
587
|
+
algorithms: ["RSA", "ECDSA"],
|
|
588
|
+
severity: "medium",
|
|
589
|
+
hndl: false,
|
|
590
|
+
},
|
|
463
591
|
];
|
|
464
592
|
/**
|
|
465
593
|
* Normalise a package name for matching within its ecosystem. PyPI is
|
|
466
594
|
* case-insensitive and folds runs of `-_.` to a single `-` (PEP 503); cargo /
|
|
467
|
-
* maven / rubygems are effectively lower-case
|
|
468
|
-
*
|
|
595
|
+
* maven / rubygems / nuget are effectively lower-case (NuGet ids are matched
|
|
596
|
+
* case-insensitively); npm and go module paths are matched verbatim (npm scopes
|
|
597
|
+
* and go paths are case-sensitive).
|
|
469
598
|
*/
|
|
470
599
|
function normalizeName(ecosystem, name) {
|
|
471
600
|
const n = name.trim();
|
|
@@ -556,6 +685,8 @@ export function manifestEcosystem(file) {
|
|
|
556
685
|
return "maven";
|
|
557
686
|
if (base === "gemfile" || base.endsWith(".gemspec"))
|
|
558
687
|
return "rubygems";
|
|
688
|
+
if (base === "packages.config" || base === "directory.packages.props" || base.endsWith(".csproj"))
|
|
689
|
+
return "nuget";
|
|
559
690
|
return null;
|
|
560
691
|
}
|
|
561
692
|
/** True if a file path looks like a manifest we can parse for dependencies. */
|
|
@@ -626,6 +757,20 @@ function candidateNames(ecosystem, content) {
|
|
|
626
757
|
}
|
|
627
758
|
break;
|
|
628
759
|
}
|
|
760
|
+
case "nuget": {
|
|
761
|
+
// NuGet manifests are XML. `.csproj` / `Directory.Packages.props` declare
|
|
762
|
+
// `<PackageReference Include="Name" … />`; `packages.config` uses
|
|
763
|
+
// `<package id="Name" … />`. Pull the Include= / id= attribute value from
|
|
764
|
+
// each. The `[^>]` guard keeps every match inside a single tag, so the
|
|
765
|
+
// scan is linear (no nested quantifiers → no catastrophic backtracking).
|
|
766
|
+
for (const m of content.matchAll(/<PackageReference\b[^>]*\bInclude\s*=\s*"([^"]+)"/gi)) {
|
|
767
|
+
names.push(m[1]);
|
|
768
|
+
}
|
|
769
|
+
for (const m of content.matchAll(/<package\b[^>]*\bid\s*=\s*"([^"]+)"/gi)) {
|
|
770
|
+
names.push(m[1]);
|
|
771
|
+
}
|
|
772
|
+
break;
|
|
773
|
+
}
|
|
629
774
|
case "npm":
|
|
630
775
|
break; // npm uses the JSON path, not this extractor.
|
|
631
776
|
}
|
|
@@ -653,8 +798,10 @@ function dependencyFinding(dep, file, content, index) {
|
|
|
653
798
|
severity: dep.severity,
|
|
654
799
|
confidence: "high",
|
|
655
800
|
algorithm,
|
|
656
|
-
// Confidentiality libs are HNDL-exposed; signature-only ones are not.
|
|
657
|
-
|
|
801
|
+
// Confidentiality libs are HNDL-exposed; signature-only ones are not. An
|
|
802
|
+
// explicit `dep.hndl` wins (some packages list RSA/EC as a family but only
|
|
803
|
+
// ever sign — e.g. JWS/JWT libs — and signatures are not HNDL-exposed).
|
|
804
|
+
hndl: dep.hndl ?? dep.algorithms.some(isConfidentialityFamily),
|
|
658
805
|
cwe: CWE_BROKEN_CRYPTO,
|
|
659
806
|
message: `${dep.name} — ${dep.reason}`,
|
|
660
807
|
remediation: multiFamilyRemediation(dep.algorithms),
|