@quantakrypto/core 0.2.2 → 0.3.0
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/detect-utils.d.ts +26 -1
- package/dist/detect-utils.d.ts.map +1 -1
- package/dist/detect-utils.js +26 -0
- package/dist/detect-utils.js.map +1 -1
- package/dist/detectors/pem.d.ts +4 -0
- package/dist/detectors/pem.d.ts.map +1 -1
- package/dist/detectors/pem.js +113 -91
- package/dist/detectors/pem.js.map +1 -1
- package/dist/detectors/source.d.ts +9 -2
- package/dist/detectors/source.d.ts.map +1 -1
- package/dist/detectors/source.js +366 -265
- package/dist/detectors/source.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/parallel.d.ts.map +1 -1
- package/dist/parallel.js +2 -0
- package/dist/parallel.js.map +1 -1
- package/dist/registry.d.ts +16 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +31 -0
- package/dist/registry.js.map +1 -1
- package/dist/report.d.ts +9 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +56 -23
- package/dist/report.js.map +1 -1
- package/dist/scan-worker.js +1 -1
- package/dist/scan-worker.js.map +1 -1
- package/dist/scan.d.ts +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +8 -2
- package/dist/scan.js.map +1 -1
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/detect-utils.ts +57 -1
- package/src/detectors/pem.ts +124 -105
- package/src/detectors/source.ts +466 -343
- package/src/index.ts +2 -1
- package/src/parallel.ts +9 -1
- package/src/registry.ts +39 -1
- package/src/report.ts +79 -23
- package/src/scan-worker.ts +12 -5
- package/src/scan.ts +19 -5
- package/src/types.ts +54 -0
- package/src/version.ts +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -73,6 +73,45 @@ export type DetectorScope = "source" | "config";
|
|
|
73
73
|
* detector is language-agnostic (e.g. PEM material, config files).
|
|
74
74
|
*/
|
|
75
75
|
export type DetectorLanguage = "js" | "python" | "go" | "java" | "any";
|
|
76
|
+
/**
|
|
77
|
+
* Declarative metadata for a single rule a detector can emit. This is the
|
|
78
|
+
* catalog entry: the stable, queryable description of a rule keyed by the
|
|
79
|
+
* `ruleId` it stamps onto findings. It is the single source of truth for a
|
|
80
|
+
* rule's title / severity / category / remediation, consumed by the SARIF
|
|
81
|
+
* `rules[]` block, the MCP `explain_finding` resolver, and future per-rule
|
|
82
|
+
* enable/disable + language-pack work.
|
|
83
|
+
*
|
|
84
|
+
* For most rules the metadata is fixed and `detect()` builds findings straight
|
|
85
|
+
* from it (see `findingFromRule`). A few rules are inherently multi-variant
|
|
86
|
+
* (e.g. `node-crypto-keygen` spans RSA/EC/DSA/DH/Ed25519 at different
|
|
87
|
+
* severities); for those the metadata here is a REPRESENTATIVE umbrella and
|
|
88
|
+
* `detect()` refines the per-finding fields at match time. The catalog always
|
|
89
|
+
* enumerates every emittable ruleId regardless.
|
|
90
|
+
*/
|
|
91
|
+
export interface RuleMeta {
|
|
92
|
+
/** Stable rule id — matches {@link Finding.ruleId}. Unique across the catalog. */
|
|
93
|
+
id: string;
|
|
94
|
+
/** Canonical human title. */
|
|
95
|
+
title: string;
|
|
96
|
+
category: FindingCategory;
|
|
97
|
+
severity: Severity;
|
|
98
|
+
/** Default confidence for findings of this rule. */
|
|
99
|
+
confidence: Confidence;
|
|
100
|
+
/** Harvest-now-decrypt-later exposure. */
|
|
101
|
+
hndl: boolean;
|
|
102
|
+
/** Representative classical algorithm family; refined per-finding when it varies. */
|
|
103
|
+
algorithm?: AlgorithmFamily;
|
|
104
|
+
/** Associated CWE identifier (e.g. "CWE-327"). */
|
|
105
|
+
cwe?: string;
|
|
106
|
+
/** Suggested post-quantum remediation. When omitted, derived from {@link algorithm}. */
|
|
107
|
+
remediation?: string;
|
|
108
|
+
/** Canonical one-line human explanation; may be refined per-finding. */
|
|
109
|
+
message: string;
|
|
110
|
+
/** True when this rule's matched snippet IS sensitive key material. */
|
|
111
|
+
sensitive?: boolean;
|
|
112
|
+
/** Short description of what the rule detects (for catalog / MCP surfaces). */
|
|
113
|
+
description?: string;
|
|
114
|
+
}
|
|
76
115
|
/** A pluggable source detector. Detectors are pure and stateless. */
|
|
77
116
|
export interface Detector {
|
|
78
117
|
/** Unique id, used as the Finding.ruleId prefix space. */
|
|
@@ -90,6 +129,13 @@ export interface Detector {
|
|
|
90
129
|
* Defaults to `"js"` when omitted.
|
|
91
130
|
*/
|
|
92
131
|
language?: DetectorLanguage;
|
|
132
|
+
/**
|
|
133
|
+
* The rules this detector can emit, as declarative metadata. Together across
|
|
134
|
+
* all detectors these form the rule catalog ({@link DetectorRegistry.ruleCatalog}).
|
|
135
|
+
* Optional for backward compatibility with externally-defined detectors, but
|
|
136
|
+
* all built-in detectors declare it.
|
|
137
|
+
*/
|
|
138
|
+
rules?: RuleMeta[];
|
|
93
139
|
/** Whether this detector should run against the given file path. */
|
|
94
140
|
appliesTo(filePath: string): boolean;
|
|
95
141
|
/** Inspect a single file's contents and return zero or more findings. */
|
|
@@ -140,6 +186,13 @@ export interface ScanOptions {
|
|
|
140
186
|
* registry's detectors are used.
|
|
141
187
|
*/
|
|
142
188
|
detectors?: Detector[];
|
|
189
|
+
/**
|
|
190
|
+
* Rule ids to suppress. Any finding whose `ruleId` is listed here is dropped
|
|
191
|
+
* after detection. Serializable (a plain string array), so it is honoured on
|
|
192
|
+
* both the serial and the worker-thread (`scanParallel`) paths. See the rule
|
|
193
|
+
* catalog ({@link DetectorRegistry.ruleCatalog}) for the valid ids.
|
|
194
|
+
*/
|
|
195
|
+
disabledRules?: string[];
|
|
143
196
|
/** Optional progress callback. */
|
|
144
197
|
onFile?: (file: string) => void;
|
|
145
198
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvE,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEnD,+DAA+D;AAC/D,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,cAAc,GACd,WAAW,GACX,KAAK,GACL,aAAa,GACb,YAAY,GACZ,MAAM,GACN,KAAK,CAAC;AAEV,yEAAyE;AACzE,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,MAAM,GACN,OAAO,GACP,OAAO,GACP,IAAI,GACJ,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,SAAS,CAAC;AAEd,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iCAAiC;AACjC,MAAM,WAAW,OAAO;IACtB,uGAAuG;IACvG,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,yDAAyD;IACzD,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAoB;IACnC,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,KAAK,CAAC;IACjB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;AAEvE,qEAAqE;AACrE,MAAM,WAAW,QAAQ;IACvB,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,oEAAoE;IACpE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACrC,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,kCAAkC;AAClC,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,kCAAkC;IAClC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kFAAkF;IAClF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrC,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,iCAAiC;AACjC,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,eAAe,CAAC;IAC3B,gFAAgF;IAChF,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantakrypto/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared post-quantum readiness library: crypto detectors, vulnerable-dependency database, inventory + SARIF reporting. Zero runtime dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Dandelion Labs <hello@dandelionlabs.io> (https://dandelionlabs.io)",
|
package/src/detect-utils.ts
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
* into a 1-based line/column, extracting a trimmed single-line snippet, and a
|
|
4
4
|
* small factory for building Finding objects with consistent remediation text.
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
AlgorithmFamily,
|
|
8
|
+
Confidence,
|
|
9
|
+
Finding,
|
|
10
|
+
FindingCategory,
|
|
11
|
+
RuleMeta,
|
|
12
|
+
Severity,
|
|
13
|
+
} from "./types.js";
|
|
7
14
|
import { remediationText } from "./remediation.js";
|
|
8
15
|
|
|
9
16
|
/** A 1-based line/column position derived from a character offset. */
|
|
@@ -104,6 +111,55 @@ export function makeFinding(spec: FindingSpec): Finding {
|
|
|
104
111
|
return finding;
|
|
105
112
|
}
|
|
106
113
|
|
|
114
|
+
/** Where a match occurred, plus optional per-finding field overrides. */
|
|
115
|
+
export interface RuleMatch {
|
|
116
|
+
file: string;
|
|
117
|
+
content: string;
|
|
118
|
+
/** Match start offset within `content`. */
|
|
119
|
+
index: number;
|
|
120
|
+
/** Length of the match (used to compute endLine for multi-line matches). */
|
|
121
|
+
matchLength?: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Fields of a {@link RuleMeta} a detector may refine at match time. Multi-variant
|
|
126
|
+
* rules (e.g. key generation across algorithm families) override these; fixed
|
|
127
|
+
* rules pass none and inherit the catalog metadata verbatim.
|
|
128
|
+
*/
|
|
129
|
+
export type RuleOverrides = Partial<
|
|
130
|
+
Pick<
|
|
131
|
+
RuleMeta,
|
|
132
|
+
"title" | "category" | "severity" | "confidence" | "algorithm" | "hndl" | "message" | "cwe"
|
|
133
|
+
>
|
|
134
|
+
> & { remediation?: string };
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Build a {@link Finding} from a rule's catalog metadata plus a match location,
|
|
138
|
+
* applying any per-finding overrides. This is the single construction path for
|
|
139
|
+
* detector findings: the invariant fields (title/severity/category/…) live once
|
|
140
|
+
* in the {@link RuleMeta} declaration, so they can't drift from what the SARIF
|
|
141
|
+
* catalog and the MCP resolver report.
|
|
142
|
+
*/
|
|
143
|
+
export function findingFromRule(rule: RuleMeta, at: RuleMatch, overrides?: RuleOverrides): Finding {
|
|
144
|
+
return makeFinding({
|
|
145
|
+
ruleId: rule.id,
|
|
146
|
+
title: overrides?.title ?? rule.title,
|
|
147
|
+
category: overrides?.category ?? rule.category,
|
|
148
|
+
severity: overrides?.severity ?? rule.severity,
|
|
149
|
+
confidence: overrides?.confidence ?? rule.confidence,
|
|
150
|
+
algorithm: overrides?.algorithm ?? rule.algorithm,
|
|
151
|
+
hndl: overrides?.hndl ?? rule.hndl,
|
|
152
|
+
cwe: overrides?.cwe ?? rule.cwe,
|
|
153
|
+
remediation: overrides?.remediation ?? rule.remediation,
|
|
154
|
+
sensitive: rule.sensitive,
|
|
155
|
+
message: overrides?.message ?? rule.message,
|
|
156
|
+
file: at.file,
|
|
157
|
+
content: at.content,
|
|
158
|
+
index: at.index,
|
|
159
|
+
matchLength: at.matchLength,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
107
163
|
/** True if `filePath` has one of the given (lower-case, dotted) extensions. */
|
|
108
164
|
export function hasExtension(filePath: string, exts: readonly string[]): boolean {
|
|
109
165
|
const lower = filePath.toLowerCase();
|
package/src/detectors/pem.ts
CHANGED
|
@@ -2,131 +2,160 @@
|
|
|
2
2
|
* Config / certificate detector: finds PEM-encoded cryptographic material in
|
|
3
3
|
* any text file (source, config, .pem, .key, .crt, .env, …). This catches
|
|
4
4
|
* embedded private keys and X.509 certificates regardless of language.
|
|
5
|
+
*
|
|
6
|
+
* Every rule's metadata lives in the {@link RuleMeta} declaration below (the
|
|
7
|
+
* catalog entry); `detect()` builds findings straight from it via
|
|
8
|
+
* `findingFromRule`. All PEM findings are high-confidence exact-marker matches.
|
|
5
9
|
*/
|
|
6
|
-
import type { Detector, Finding } from "../types.js";
|
|
7
|
-
import { eachMatch,
|
|
10
|
+
import type { Detector, Finding, RuleMeta } from "../types.js";
|
|
11
|
+
import { eachMatch, findingFromRule } from "../detect-utils.js";
|
|
8
12
|
import { CWE_BROKEN_CRYPTO, CWE_HARDCODED_KEY } from "../cwe.js";
|
|
9
13
|
|
|
14
|
+
/** A PEM rule: its catalog metadata plus the begin-marker regex that triggers it. */
|
|
10
15
|
interface PemRule {
|
|
11
16
|
/** Regex matching the PEM begin marker. */
|
|
12
17
|
re: RegExp;
|
|
13
|
-
|
|
14
|
-
title: string;
|
|
15
|
-
category: Finding["category"];
|
|
16
|
-
severity: Finding["severity"];
|
|
17
|
-
algorithm?: Finding["algorithm"];
|
|
18
|
-
message: string;
|
|
19
|
-
remediation: string;
|
|
20
|
-
hndl: boolean;
|
|
21
|
-
cwe: string;
|
|
22
|
-
/** True when the matched snippet IS key material (reporters drop the snippet). */
|
|
23
|
-
sensitive?: boolean;
|
|
18
|
+
meta: RuleMeta;
|
|
24
19
|
}
|
|
25
20
|
|
|
26
21
|
const PEM_RULES: PemRule[] = [
|
|
27
22
|
{
|
|
28
23
|
re: /-----BEGIN RSA PRIVATE KEY-----/g,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
meta: {
|
|
25
|
+
id: "pem-rsa-private-key",
|
|
26
|
+
title: "RSA private key (PEM)",
|
|
27
|
+
description: "PKCS#1 RSA private key block",
|
|
28
|
+
category: "certificate",
|
|
29
|
+
severity: "critical",
|
|
30
|
+
confidence: "high",
|
|
31
|
+
algorithm: "RSA",
|
|
32
|
+
hndl: true,
|
|
33
|
+
cwe: CWE_HARDCODED_KEY,
|
|
34
|
+
sensitive: true,
|
|
35
|
+
message: "Embedded RSA private key (PKCS#1 PEM); classical and not quantum-safe.",
|
|
36
|
+
remediation: "Migrate to ML-DSA / ML-KEM keys and remove embedded private keys from source.",
|
|
37
|
+
},
|
|
39
38
|
},
|
|
40
39
|
{
|
|
41
40
|
re: /-----BEGIN EC PRIVATE KEY-----/g,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
meta: {
|
|
42
|
+
id: "pem-ec-private-key",
|
|
43
|
+
title: "EC private key (PEM)",
|
|
44
|
+
description: "SEC1 EC private key block",
|
|
45
|
+
category: "certificate",
|
|
46
|
+
severity: "critical",
|
|
47
|
+
confidence: "high",
|
|
48
|
+
algorithm: "ECDSA",
|
|
49
|
+
hndl: true,
|
|
50
|
+
cwe: CWE_HARDCODED_KEY,
|
|
51
|
+
sensitive: true,
|
|
52
|
+
message: "Embedded EC private key (SEC1 PEM); classical ECDSA/ECDH key, not quantum-safe.",
|
|
53
|
+
remediation:
|
|
54
|
+
"Migrate to ML-DSA (FIPS 204) keys and remove embedded private keys from source.",
|
|
55
|
+
},
|
|
52
56
|
},
|
|
53
57
|
{
|
|
54
58
|
re: /-----BEGIN DSA PRIVATE KEY-----/g,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
meta: {
|
|
60
|
+
id: "pem-dsa-private-key",
|
|
61
|
+
title: "DSA private key (PEM)",
|
|
62
|
+
description: "DSA private key block",
|
|
63
|
+
category: "certificate",
|
|
64
|
+
severity: "critical",
|
|
65
|
+
confidence: "high",
|
|
66
|
+
algorithm: "DSA",
|
|
67
|
+
hndl: false,
|
|
68
|
+
cwe: CWE_HARDCODED_KEY,
|
|
69
|
+
sensitive: true,
|
|
70
|
+
message:
|
|
71
|
+
"Embedded DSA private key (PEM); classical, already deprecated, and not quantum-safe.",
|
|
72
|
+
remediation: "Rotate immediately (DSA is deprecated) and migrate to ML-DSA-65 (FIPS 204).",
|
|
73
|
+
},
|
|
65
74
|
},
|
|
66
75
|
{
|
|
67
76
|
re: /-----BEGIN OPENSSH PRIVATE KEY-----/g,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
meta: {
|
|
78
|
+
id: "pem-openssh-private-key",
|
|
79
|
+
title: "OpenSSH private key",
|
|
80
|
+
description: "OpenSSH private key block",
|
|
81
|
+
category: "certificate",
|
|
82
|
+
severity: "critical",
|
|
83
|
+
confidence: "high",
|
|
84
|
+
algorithm: "unknown",
|
|
85
|
+
hndl: true,
|
|
86
|
+
cwe: CWE_HARDCODED_KEY,
|
|
87
|
+
sensitive: true,
|
|
88
|
+
message: "Embedded OpenSSH private key (RSA/ECDSA/Ed25519); classical and not quantum-safe.",
|
|
89
|
+
remediation: "Rotate the key; plan migration to PQC-capable SSH (e.g. sntrup761x25519).",
|
|
90
|
+
},
|
|
78
91
|
},
|
|
79
92
|
{
|
|
80
93
|
re: /-----BEGIN PGP PRIVATE KEY BLOCK-----/g,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
meta: {
|
|
95
|
+
id: "pem-pgp-private-key",
|
|
96
|
+
title: "PGP/GPG private key block",
|
|
97
|
+
description: "OpenPGP private key block",
|
|
98
|
+
category: "certificate",
|
|
99
|
+
severity: "critical",
|
|
100
|
+
confidence: "high",
|
|
101
|
+
algorithm: "unknown",
|
|
102
|
+
hndl: true,
|
|
103
|
+
cwe: CWE_HARDCODED_KEY,
|
|
104
|
+
sensitive: true,
|
|
105
|
+
message:
|
|
106
|
+
"Embedded PGP/GPG private key block (RSA/ECDSA/EdDSA/ElGamal); classical and not quantum-safe.",
|
|
107
|
+
remediation: "Rotate the key; track OpenPGP PQC drafts for migration.",
|
|
108
|
+
},
|
|
92
109
|
},
|
|
93
110
|
{
|
|
94
111
|
re: /-----BEGIN PGP MESSAGE-----/g,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
112
|
+
meta: {
|
|
113
|
+
id: "pem-pgp-message",
|
|
114
|
+
title: "PGP/GPG encrypted message",
|
|
115
|
+
description: "OpenPGP encrypted message block",
|
|
116
|
+
category: "certificate",
|
|
117
|
+
severity: "low",
|
|
118
|
+
confidence: "high",
|
|
119
|
+
algorithm: "unknown",
|
|
120
|
+
hndl: true,
|
|
121
|
+
cwe: CWE_BROKEN_CRYPTO,
|
|
122
|
+
message:
|
|
123
|
+
"Embedded PGP/GPG message; likely encrypted with classical RSA/ElGamal (harvest-now-decrypt-later).",
|
|
124
|
+
remediation: "Re-encrypt with PQC-capable tooling as OpenPGP PQC profiles mature.",
|
|
125
|
+
},
|
|
105
126
|
},
|
|
106
127
|
{
|
|
107
128
|
re: /-----BEGIN (?:ENCRYPTED )?PRIVATE KEY-----/g,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
129
|
+
meta: {
|
|
130
|
+
id: "pem-pkcs8-private-key",
|
|
131
|
+
title: "Private key (PKCS#8 PEM)",
|
|
132
|
+
description: "PKCS#8 private key block",
|
|
133
|
+
category: "certificate",
|
|
134
|
+
severity: "critical",
|
|
135
|
+
confidence: "high",
|
|
136
|
+
algorithm: "unknown",
|
|
137
|
+
hndl: true,
|
|
138
|
+
cwe: CWE_HARDCODED_KEY,
|
|
139
|
+
sensitive: true,
|
|
140
|
+
message: "Embedded PKCS#8 private key; likely classical RSA/EC, not quantum-safe.",
|
|
141
|
+
remediation: "Migrate to PQC keys and remove embedded private keys from source.",
|
|
142
|
+
},
|
|
118
143
|
},
|
|
119
144
|
{
|
|
120
145
|
re: /-----BEGIN CERTIFICATE-----/g,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
146
|
+
meta: {
|
|
147
|
+
id: "pem-certificate",
|
|
148
|
+
title: "X.509 certificate (PEM)",
|
|
149
|
+
description: "X.509 certificate block",
|
|
150
|
+
category: "certificate",
|
|
151
|
+
severity: "low",
|
|
152
|
+
confidence: "high",
|
|
153
|
+
algorithm: "unknown",
|
|
154
|
+
hndl: false,
|
|
155
|
+
cwe: CWE_BROKEN_CRYPTO,
|
|
156
|
+
message: "Embedded X.509 certificate; almost certainly signed with classical RSA/ECDSA.",
|
|
157
|
+
remediation: "Plan re-issuance with PQC-capable CAs as ML-DSA certificate profiles mature.",
|
|
158
|
+
},
|
|
130
159
|
},
|
|
131
160
|
];
|
|
132
161
|
|
|
@@ -136,6 +165,7 @@ export const pemDetector: Detector = {
|
|
|
136
165
|
description: "PEM-encoded private keys and X.509 certificates in any file",
|
|
137
166
|
scope: "config",
|
|
138
167
|
language: "any",
|
|
168
|
+
rules: PEM_RULES.map((r) => r.meta),
|
|
139
169
|
// Applies to every text file; the walker already filters out binaries.
|
|
140
170
|
appliesTo: () => true,
|
|
141
171
|
detect({ file, content }): Finding[] {
|
|
@@ -146,18 +176,7 @@ export const pemDetector: Detector = {
|
|
|
146
176
|
for (const rule of PEM_RULES) {
|
|
147
177
|
eachMatch(rule.re, content, (m) => {
|
|
148
178
|
findings.push(
|
|
149
|
-
|
|
150
|
-
ruleId: rule.ruleId,
|
|
151
|
-
title: rule.title,
|
|
152
|
-
category: rule.category,
|
|
153
|
-
severity: rule.severity,
|
|
154
|
-
confidence: "high",
|
|
155
|
-
algorithm: rule.algorithm,
|
|
156
|
-
hndl: rule.hndl,
|
|
157
|
-
cwe: rule.cwe,
|
|
158
|
-
sensitive: rule.sensitive,
|
|
159
|
-
message: rule.message,
|
|
160
|
-
remediation: rule.remediation,
|
|
179
|
+
findingFromRule(rule.meta, {
|
|
161
180
|
file,
|
|
162
181
|
content,
|
|
163
182
|
index: m.index,
|