@mitre/hdf-schema 3.4.4 → 3.5.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/README.md +15 -2
- package/dist/go/hdf.go +535 -271
- package/dist/helpers.d.ts +56 -1
- package/dist/helpers.js +98 -38
- package/dist/index.d.ts +2 -0
- package/dist/index.js +28 -26
- package/dist/schemas/hdf-amendments.schema.json +235 -48
- package/dist/schemas/hdf-baseline.schema.json +240 -53
- package/dist/schemas/hdf-comparison.schema.json +1948 -1504
- package/dist/schemas/hdf-evidence-package.schema.json +242 -48
- package/dist/schemas/hdf-plan.schema.json +692 -498
- package/dist/schemas/hdf-requirement-change-event.schema.json +5290 -0
- package/dist/schemas/hdf-results.schema.json +1650 -1215
- package/dist/schemas/hdf-system.schema.json +262 -68
- package/dist/ts/hdf.d.ts +420 -73
- package/dist/ts/hdf.js +65 -30
- package/dist/ts/hdf.ts +428 -77
- package/package.json +2 -2
package/dist/helpers.d.ts
CHANGED
|
@@ -14,8 +14,19 @@ import type {
|
|
|
14
14
|
ResultStatus,
|
|
15
15
|
SupportedPlatform,
|
|
16
16
|
RequirementGroup,
|
|
17
|
+
StatusOverride,
|
|
18
|
+
Poam,
|
|
19
|
+
Cvss,
|
|
20
|
+
Reference,
|
|
21
|
+
AffectedPackage,
|
|
22
|
+
Epss,
|
|
23
|
+
Kev,
|
|
24
|
+
OverrideType,
|
|
17
25
|
} from '../dist/ts/hdf.js';
|
|
18
26
|
|
|
27
|
+
/** Minimal identity shape used by amendment appliedBy fields. */
|
|
28
|
+
type Identity = { type: string; identifier: string; description?: string };
|
|
29
|
+
|
|
19
30
|
export function createMinimalBaseline(
|
|
20
31
|
name: string,
|
|
21
32
|
requirements: EvaluatedRequirement[],
|
|
@@ -35,13 +46,27 @@ export function createMinimalBaseline(
|
|
|
35
46
|
|
|
36
47
|
export function createRequirement(
|
|
37
48
|
id: string,
|
|
38
|
-
title: string,
|
|
49
|
+
title: string | null | undefined,
|
|
39
50
|
descriptions: Description[],
|
|
40
51
|
impact: number,
|
|
41
52
|
results: RequirementResult[],
|
|
42
53
|
options?: {
|
|
43
54
|
sourceLocation?: SourceLocation;
|
|
44
55
|
tags?: Record<string, unknown>;
|
|
56
|
+
code?: string;
|
|
57
|
+
// Amendment fields
|
|
58
|
+
effectiveStatus?: ResultStatus;
|
|
59
|
+
effectiveImpact?: number;
|
|
60
|
+
disposition?: OverrideType;
|
|
61
|
+
statusOverrides?: StatusOverride[];
|
|
62
|
+
poams?: Poam[];
|
|
63
|
+
// Vulnerability fields
|
|
64
|
+
cwe?: string[];
|
|
65
|
+
cvss?: Cvss[];
|
|
66
|
+
refs?: Reference[];
|
|
67
|
+
affectedPackages?: AffectedPackage[];
|
|
68
|
+
epss?: Epss;
|
|
69
|
+
kev?: Kev;
|
|
45
70
|
}
|
|
46
71
|
): EvaluatedRequirement;
|
|
47
72
|
|
|
@@ -56,6 +81,8 @@ export function createResult(
|
|
|
56
81
|
runTime?: number;
|
|
57
82
|
backtrace?: string[];
|
|
58
83
|
exception?: string;
|
|
84
|
+
resource?: string;
|
|
85
|
+
resourceId?: string;
|
|
59
86
|
}
|
|
60
87
|
): RequirementResult;
|
|
61
88
|
|
|
@@ -68,6 +95,34 @@ export function createSupportedPlatform(
|
|
|
68
95
|
|
|
69
96
|
export function createSourceLocation(ref: string, line: number): SourceLocation;
|
|
70
97
|
|
|
98
|
+
export function createStatusOverride(
|
|
99
|
+
type: OverrideType | string,
|
|
100
|
+
options?: {
|
|
101
|
+
reason?: string;
|
|
102
|
+
appliedBy?: Identity;
|
|
103
|
+
appliedAt?: string;
|
|
104
|
+
expiresAt?: string;
|
|
105
|
+
status?: ResultStatus;
|
|
106
|
+
impact?: { value: number };
|
|
107
|
+
}
|
|
108
|
+
): StatusOverride;
|
|
109
|
+
|
|
110
|
+
export function createPoam(
|
|
111
|
+
type: 'remediation' | 'mitigation' | 'riskAcceptance' | 'vendorDependency' | string,
|
|
112
|
+
options?: {
|
|
113
|
+
explanation?: string;
|
|
114
|
+
appliedBy?: Identity;
|
|
115
|
+
appliedAt?: string;
|
|
116
|
+
expiresAt?: string;
|
|
117
|
+
milestones?: Array<Record<string, unknown>>;
|
|
118
|
+
}
|
|
119
|
+
): Poam;
|
|
120
|
+
|
|
121
|
+
export function createCvss(
|
|
122
|
+
version: string,
|
|
123
|
+
options?: Partial<Omit<Cvss, 'version'>>
|
|
124
|
+
): Cvss;
|
|
125
|
+
|
|
71
126
|
export function severityToImpact(severity: null): null;
|
|
72
127
|
export function severityToImpact(severity: string): number;
|
|
73
128
|
export function severityToImpact(severity: string | null): number | null;
|
package/dist/helpers.js
CHANGED
|
@@ -54,27 +54,43 @@ export function createMinimalBaseline(name, requirements, options = {}) {
|
|
|
54
54
|
/**
|
|
55
55
|
* Create a minimal valid EvaluatedRequirement
|
|
56
56
|
* @param {string} id - Unique requirement identifier
|
|
57
|
-
* @param {string} title - Human-readable title
|
|
57
|
+
* @param {string|null|undefined} title - Human-readable title. Pass null/undefined
|
|
58
|
+
* to omit it (some controls legitimately have no title).
|
|
58
59
|
* @param {import('../dist/ts/hdf-results.js').Description[]} descriptions - Array of descriptions
|
|
59
60
|
* @param {number} impact - Impact score (0.0 to 1.0)
|
|
60
61
|
* @param {import('../dist/ts/hdf-results.js').RequirementResult[]} results - Array of test results
|
|
61
|
-
* @param {Object} [options] - Optional fields
|
|
62
|
+
* @param {Object} [options] - Optional fields: sourceLocation, code, tags;
|
|
63
|
+
* amendment fields (effectiveStatus, effectiveImpact, disposition, statusOverrides, poams);
|
|
64
|
+
* vulnerability fields (cwe, cvss, refs, affectedPackages, epss, kev).
|
|
62
65
|
* @returns {import('../dist/ts/hdf-results.js').EvaluatedRequirement}
|
|
63
66
|
*/
|
|
64
67
|
export function createRequirement(id, title, descriptions, impact, results, options = {}) {
|
|
65
68
|
const req = {
|
|
66
69
|
id,
|
|
67
|
-
title,
|
|
68
70
|
descriptions,
|
|
69
71
|
impact,
|
|
70
72
|
results,
|
|
71
73
|
tags: options.tags || {},
|
|
72
74
|
};
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
if (options.sourceLocation)
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
if (title != null) req.title = title;
|
|
77
|
+
if (options.sourceLocation) req.sourceLocation = options.sourceLocation;
|
|
78
|
+
if (options.code != null) req.code = options.code;
|
|
79
|
+
|
|
80
|
+
// Amendment fields
|
|
81
|
+
if (options.effectiveStatus) req.effectiveStatus = options.effectiveStatus;
|
|
82
|
+
if (options.effectiveImpact != null) req.effectiveImpact = options.effectiveImpact;
|
|
83
|
+
if (options.disposition) req.disposition = options.disposition;
|
|
84
|
+
if (options.statusOverrides) req.statusOverrides = options.statusOverrides;
|
|
85
|
+
if (options.poams) req.poams = options.poams;
|
|
86
|
+
|
|
87
|
+
// Vulnerability fields
|
|
88
|
+
if (options.cwe) req.cwe = options.cwe;
|
|
89
|
+
if (options.cvss) req.cvss = options.cvss;
|
|
90
|
+
if (options.refs) req.refs = options.refs;
|
|
91
|
+
if (options.affectedPackages) req.affectedPackages = options.affectedPackages;
|
|
92
|
+
if (options.epss) req.epss = options.epss;
|
|
93
|
+
if (options.kev) req.kev = options.kev;
|
|
78
94
|
|
|
79
95
|
return req;
|
|
80
96
|
}
|
|
@@ -107,6 +123,8 @@ export function createResult(status, message, options = {}) {
|
|
|
107
123
|
runTime: options.runTime,
|
|
108
124
|
backtrace: options.backtrace,
|
|
109
125
|
exception: options.exception,
|
|
126
|
+
...(options.resource ? { resource: options.resource } : {}),
|
|
127
|
+
...(options.resourceId ? { resourceId: options.resourceId } : {}),
|
|
110
128
|
};
|
|
111
129
|
}
|
|
112
130
|
|
|
@@ -144,11 +162,75 @@ export function createSourceLocation(ref, line) {
|
|
|
144
162
|
return { ref, line };
|
|
145
163
|
}
|
|
146
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Create a minimal valid inline Status_Override (requirement.statusOverrides[]).
|
|
167
|
+
* The schema requires one of status/impact; when neither is supplied this
|
|
168
|
+
* defaults status to 'notApplicable' so the built override stays valid.
|
|
169
|
+
* @param {string} type - Override_Type (waiver, attestation, falsePositive, riskAdjustment, ...)
|
|
170
|
+
* @param {Object} [options] - reason, appliedBy, appliedAt, expiresAt, status, impact
|
|
171
|
+
* @returns {Object}
|
|
172
|
+
*/
|
|
173
|
+
export function createStatusOverride(type, options = {}) {
|
|
174
|
+
const override = {
|
|
175
|
+
type,
|
|
176
|
+
reason: options.reason || 'Test override',
|
|
177
|
+
appliedBy: options.appliedBy || { type: 'simple', identifier: 'test' },
|
|
178
|
+
appliedAt: options.appliedAt || '2025-01-01T00:00:00Z',
|
|
179
|
+
expiresAt: options.expiresAt || '2099-12-31T00:00:00Z',
|
|
180
|
+
};
|
|
181
|
+
if (options.status) override.status = options.status;
|
|
182
|
+
if (options.impact) override.impact = options.impact;
|
|
183
|
+
if (!override.status && !override.impact) override.status = 'notApplicable';
|
|
184
|
+
return override;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Create a minimal valid POA&M (requirement.poams[]). expiresAt is schema-
|
|
189
|
+
* required (a POA&M is time-boxed) and defaults to a far-future constant.
|
|
190
|
+
* @param {string} type - remediation | mitigation | riskAcceptance | vendorDependency
|
|
191
|
+
* @param {Object} [options] - explanation, appliedBy, appliedAt, expiresAt, milestones
|
|
192
|
+
* @returns {Object}
|
|
193
|
+
*/
|
|
194
|
+
export function createPoam(type, options = {}) {
|
|
195
|
+
const poam = {
|
|
196
|
+
type,
|
|
197
|
+
explanation: options.explanation || 'Remediation planned',
|
|
198
|
+
appliedBy: options.appliedBy || { type: 'simple', identifier: 'test' },
|
|
199
|
+
appliedAt: options.appliedAt || '2025-01-01T00:00:00Z',
|
|
200
|
+
expiresAt: options.expiresAt || '2099-12-31T00:00:00Z',
|
|
201
|
+
};
|
|
202
|
+
if (options.milestones) poam.milestones = options.milestones;
|
|
203
|
+
return poam;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Create a Cvss primitive. Only `version` is schema-required; every other CVSS
|
|
208
|
+
* field is passed through from options when present.
|
|
209
|
+
* @param {string} version - CVSS version (e.g. '3.1', '4.0')
|
|
210
|
+
* @param {Object} [options] - source, baseVector, baseScore, baseSeverity, threatVector,
|
|
211
|
+
* threatScore, environmentalVector, environmentalScore, supplementalVector, computedScore, computedSeverity
|
|
212
|
+
* @returns {Object}
|
|
213
|
+
*/
|
|
214
|
+
export function createCvss(version, options = {}) {
|
|
215
|
+
const cvss = { version };
|
|
216
|
+
const fields = [
|
|
217
|
+
'source', 'baseVector', 'baseScore', 'baseSeverity',
|
|
218
|
+
'threatVector', 'threatScore', 'environmentalVector', 'environmentalScore',
|
|
219
|
+
'supplementalVector', 'computedScore', 'computedSeverity',
|
|
220
|
+
];
|
|
221
|
+
for (const f of fields) {
|
|
222
|
+
if (options[f] != null) cvss[f] = options[f];
|
|
223
|
+
}
|
|
224
|
+
return cvss;
|
|
225
|
+
}
|
|
226
|
+
|
|
147
227
|
// Re-export severity mapping from @mitre/hdf-utilities (canonical location).
|
|
148
228
|
// Kept here for backwards compatibility — consumers importing from
|
|
149
229
|
// @mitre/hdf-schema/helpers still get these functions.
|
|
150
230
|
export { severityToImpact, impactToSeverity } from '@mitre/hdf-utilities';
|
|
151
231
|
|
|
232
|
+
import { worstStatus } from '@mitre/hdf-utilities';
|
|
233
|
+
|
|
152
234
|
/**
|
|
153
235
|
* Compute the effective status of a requirement from its results and impact.
|
|
154
236
|
*
|
|
@@ -157,10 +239,8 @@ export { severityToImpact, impactToSeverity } from '@mitre/hdf-utilities';
|
|
|
157
239
|
* 1. effectiveStatus already set → return it
|
|
158
240
|
* 2. impact === 0 → notApplicable
|
|
159
241
|
* 3. No results → notReviewed
|
|
160
|
-
* 4.
|
|
161
|
-
*
|
|
162
|
-
* 6. All "passed" → passed
|
|
163
|
-
* 7. Otherwise → notReviewed
|
|
242
|
+
* 4. Worst-wins roll-up of results via the canonical shared ordering
|
|
243
|
+
* (error > failed > passed > notApplicable > notReviewed)
|
|
164
244
|
*
|
|
165
245
|
* @param {import('../dist/ts/hdf-results.js').EvaluatedRequirement} requirement
|
|
166
246
|
* @returns {import('../dist/ts/hdf-results.js').ResultStatus}
|
|
@@ -174,31 +254,11 @@ export function computeEffectiveStatus(requirement) {
|
|
|
174
254
|
return 'notApplicable';
|
|
175
255
|
}
|
|
176
256
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
let hasPassed = false;
|
|
185
|
-
|
|
186
|
-
for (const result of results) {
|
|
187
|
-
switch (result.status) {
|
|
188
|
-
case 'error':
|
|
189
|
-
hasError = true;
|
|
190
|
-
break;
|
|
191
|
-
case 'failed':
|
|
192
|
-
hasFailed = true;
|
|
193
|
-
break;
|
|
194
|
-
case 'passed':
|
|
195
|
-
hasPassed = true;
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (hasError) return 'error';
|
|
201
|
-
if (hasFailed) return 'failed';
|
|
202
|
-
if (hasPassed) return 'passed';
|
|
203
|
-
return 'notReviewed';
|
|
257
|
+
// Worst-wins roll-up via the canonical shared ordering (error > failed >
|
|
258
|
+
// passed > notApplicable > notReviewed); empty results -> notReviewed.
|
|
259
|
+
// NOTE: unlike the full effective-status computation in @mitre/hdf-utilities,
|
|
260
|
+
// this helper deliberately honors an already-set effectiveStatus first (its
|
|
261
|
+
// documented back-compat contract) and does not consult statusOverrides.
|
|
262
|
+
const results = requirement.results ?? [];
|
|
263
|
+
return worstStatus(results.map((result) => result.status));
|
|
204
264
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare const hdfBaselineSchema: Readonly<Record<string, unknown>>;
|
|
|
11
11
|
export declare const hdfComparisonSchema: Readonly<Record<string, unknown>>;
|
|
12
12
|
export declare const hdfEvidencePackageSchema: Readonly<Record<string, unknown>>;
|
|
13
13
|
export declare const hdfPlanSchema: Readonly<Record<string, unknown>>;
|
|
14
|
+
export declare const hdfRequirementChangeEventSchema: Readonly<Record<string, unknown>>;
|
|
14
15
|
export declare const hdfResultsSchema: Readonly<Record<string, unknown>>;
|
|
15
16
|
export declare const hdfSystemSchema: Readonly<Record<string, unknown>>;
|
|
16
17
|
export declare const affectedPackageSchema: Readonly<Record<string, unknown>>;
|
|
@@ -22,6 +23,7 @@ export declare const componentSchema: Readonly<Record<string, unknown>>;
|
|
|
22
23
|
export declare const cvssSchema: Readonly<Record<string, unknown>>;
|
|
23
24
|
export declare const dataFlowSchema: Readonly<Record<string, unknown>>;
|
|
24
25
|
export declare const epssSchema: Readonly<Record<string, unknown>>;
|
|
26
|
+
export declare const eventsSchema: Readonly<Record<string, unknown>>;
|
|
25
27
|
export declare const extensionsSchema: Readonly<Record<string, unknown>>;
|
|
26
28
|
export declare const kevSchema: Readonly<Record<string, unknown>>;
|
|
27
29
|
export declare const parameterSchema: Readonly<Record<string, unknown>>;
|