@mitre/hdf-converters 2.6.20 → 2.6.21
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/lib/package.json +1 -1
- package/lib/src/asff-mapper.d.ts +20 -10
- package/lib/src/asff-mapper.js +481 -173
- package/lib/src/asff-mapper.js.map +1 -1
- package/lib/src/base-converter.d.ts +5 -4
- package/lib/src/base-converter.js +41 -22
- package/lib/src/base-converter.js.map +1 -1
- package/lib/src/converters-from-hdf/asff/transformers.d.ts +1 -1
- package/lib/src/converters-from-hdf/asff/transformers.js +64 -62
- package/lib/src/converters-from-hdf/asff/transformers.js.map +1 -1
- package/lib/src/converters-from-hdf/reverse-any-base-converter.d.ts +2 -2
- package/lib/src/converters-from-hdf/reverse-any-base-converter.js.map +1 -1
- package/lib/src/converters-from-hdf/reverse-base-converter.d.ts +2 -2
- package/lib/src/converters-from-hdf/reverse-base-converter.js.map +1 -1
- package/package.json +1 -1
package/lib/src/asff-mapper.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ASFFMapper = void 0;
|
|
6
|
+
exports.ASFFResults = exports.ASFFMapper = void 0;
|
|
7
7
|
const html_entities_1 = require("html-entities");
|
|
8
8
|
const inspecjs_1 = require("inspecjs");
|
|
9
9
|
const lodash_1 = __importDefault(require("lodash"));
|
|
@@ -20,63 +20,189 @@ const IMPACT_MAPPING = new Map([
|
|
|
20
20
|
const DEFAULT_NIST_TAG = ['SA-11', 'RA-5'];
|
|
21
21
|
const SEVERITY_LABEL = 'Severity.Label';
|
|
22
22
|
const COMPLIANCE_STATUS = 'Compliance.Status';
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
[
|
|
30
|
-
[
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
var SpecialCasing;
|
|
24
|
+
(function (SpecialCasing) {
|
|
25
|
+
SpecialCasing["FirewallManager"] = "AWS Firewall Manager";
|
|
26
|
+
SpecialCasing["Prowler"] = "Prowler";
|
|
27
|
+
SpecialCasing["SecurityHub"] = "AWS Security Hub";
|
|
28
|
+
SpecialCasing["Trivy"] = "Aqua Trivy";
|
|
29
|
+
SpecialCasing["HDF2ASFF"] = "MITRE SAF HDF2ASFF";
|
|
30
|
+
SpecialCasing["Default"] = "Default";
|
|
31
|
+
})(SpecialCasing || (SpecialCasing = {}));
|
|
32
|
+
function whichSpecialCase(finding) {
|
|
33
|
+
const productArn = lodash_1.default.get(finding, 'ProductArn');
|
|
34
|
+
if (!productArn) {
|
|
35
|
+
console.trace(finding, productArn);
|
|
36
|
+
}
|
|
37
|
+
if (productArn.match(/^arn:[^:]+:securityhub:[^:]+:[^:]*:product\/aws\/firewall-manager$/)) {
|
|
38
|
+
return SpecialCasing.FirewallManager;
|
|
39
|
+
}
|
|
40
|
+
else if (productArn.match(/^arn:[^:]+:securityhub:[^:]+:[^:]*:product\/prowler\/prowler$/)) {
|
|
41
|
+
return SpecialCasing.Prowler;
|
|
42
|
+
}
|
|
43
|
+
else if (productArn.match(/^arn:[^:]+:securityhub:[^:]+:[^:]*:product\/aws\/securityhub$/)) {
|
|
44
|
+
return SpecialCasing.SecurityHub;
|
|
45
|
+
}
|
|
46
|
+
else if (productArn.match(/^arn:[^:]+:securityhub:[^:]+:[^:]*:product\/aquasecurity\/aquasecurity$/)) {
|
|
47
|
+
return SpecialCasing.Trivy;
|
|
48
|
+
}
|
|
49
|
+
else if (lodash_1.default.some(lodash_1.default.get(finding, 'FindingProviderFields.Types'), (type) => {
|
|
50
|
+
const version = type.split('/')[2].split('-')[0];
|
|
51
|
+
const [major, minor, patch] = version.split('.');
|
|
52
|
+
if (parseInt(major) > 1 &&
|
|
53
|
+
parseInt(minor) > 5 &&
|
|
54
|
+
parseInt(patch) > 20) {
|
|
55
|
+
return lodash_1.default.startsWith(type, 'MITRE/SAF/');
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
})) {
|
|
61
|
+
return SpecialCasing.HDF2ASFF;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return SpecialCasing.Default;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const SPECIAL_CASE_MAPPING = new Map([
|
|
68
|
+
[SpecialCasing.FirewallManager, getFirewallManager()],
|
|
69
|
+
[SpecialCasing.Prowler, getProwler()],
|
|
70
|
+
[SpecialCasing.SecurityHub, getSecurityHub()],
|
|
71
|
+
[SpecialCasing.Trivy, getTrivy()],
|
|
72
|
+
[SpecialCasing.HDF2ASFF, getHDF2ASFF()]
|
|
33
73
|
]);
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
74
|
+
function externalProductHandler(context, product, data, func, defaultVal) {
|
|
75
|
+
var _a;
|
|
76
|
+
if (product !== SpecialCasing.Default &&
|
|
77
|
+
lodash_1.default.has(SPECIAL_CASE_MAPPING.get(product), func)) {
|
|
78
|
+
let keywords = {};
|
|
79
|
+
if (context.supportingDocs.has(product)) {
|
|
80
|
+
keywords = { ...context.supportingDocs.get(product) };
|
|
81
|
+
}
|
|
82
|
+
return (_a = lodash_1.default.get(SPECIAL_CASE_MAPPING.get(product), func)) === null || _a === void 0 ? void 0 : _a.apply(context, [
|
|
83
|
+
data,
|
|
84
|
+
keywords
|
|
85
|
+
]);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
if (typeof defaultVal === 'function') {
|
|
89
|
+
return defaultVal();
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return defaultVal;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function consolidate(context, input, file) {
|
|
97
|
+
const allFindings = lodash_1.default.get(file, 'Findings');
|
|
98
|
+
if (input.length !== allFindings.length) {
|
|
99
|
+
throw new Error('The number of generated controls should be the same as the number of findings at this point in the process.');
|
|
100
|
+
}
|
|
101
|
+
const idGroups = lodash_1.default.groupBy(lodash_1.default.zip(input, allFindings), (value) => {
|
|
102
|
+
const [hdfControl, asffFinding] = value;
|
|
103
|
+
return externalProductHandler(context, whichSpecialCase(asffFinding), asffFinding, 'subfindingsId', lodash_1.default.get(hdfControl, 'id'));
|
|
104
|
+
});
|
|
105
|
+
const output = [];
|
|
106
|
+
Object.entries(idGroups || {}).forEach((idGroup) => {
|
|
107
|
+
const [id, data] = idGroup;
|
|
108
|
+
const group = data.map((d) => d[0]);
|
|
109
|
+
const findings = data.map((d) => d[1]);
|
|
110
|
+
const productInfo = lodash_1.default.get(findings[0], 'ProductArn')
|
|
111
|
+
.split(':')
|
|
112
|
+
.slice(-1)[0]
|
|
113
|
+
.split('/');
|
|
114
|
+
const productName = externalProductHandler(context, whichSpecialCase(findings[0]), findings, 'productName', (0, html_entities_1.encode)(`${productInfo[1]}/${productInfo[2]}`));
|
|
115
|
+
const hasNoTitlePrefix = externalProductHandler(context, whichSpecialCase(findings[0]), null, 'doesNotHaveFindingTitlePrefix', false);
|
|
116
|
+
const titlePrefix = hasNoTitlePrefix ? '' : `${productName}: `;
|
|
117
|
+
const waiverData = externalProductHandler(context, whichSpecialCase(findings[0]), group, 'waiverData', {});
|
|
118
|
+
const item = {
|
|
119
|
+
id: id,
|
|
120
|
+
title: `${titlePrefix}${lodash_1.default.uniq(group.map((d) => d.title)).join(';')}`,
|
|
121
|
+
tags: lodash_1.default.mergeWith({}, ...group.map((d) => d.tags), (acc, cur) => {
|
|
122
|
+
if (acc === undefined || cur === undefined) {
|
|
123
|
+
return acc || cur;
|
|
124
|
+
}
|
|
125
|
+
else if (lodash_1.default.isEqual(acc, cur)) {
|
|
126
|
+
return acc;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
return lodash_1.default.uniq(lodash_1.default.concat([], acc, cur));
|
|
130
|
+
}
|
|
131
|
+
}),
|
|
132
|
+
impact: Math.max(...group.map((d) => d.impact)),
|
|
133
|
+
desc: externalProductHandler(context, whichSpecialCase(findings[0]), group, 'desc', lodash_1.default.uniq(group.map((d) => d.desc)).join('\n')),
|
|
134
|
+
descriptions: group
|
|
135
|
+
.map((d) => d.descriptions)
|
|
136
|
+
.flat()
|
|
137
|
+
.filter((element, index, arr) => element !== null &&
|
|
138
|
+
element !== undefined &&
|
|
139
|
+
element.data !== '' &&
|
|
140
|
+
index ===
|
|
141
|
+
arr.findIndex((e) => e !== null && e !== undefined && e.data === element.data)),
|
|
142
|
+
refs: group
|
|
143
|
+
.map((d) => d.refs)
|
|
144
|
+
.flat()
|
|
145
|
+
.filter((element) => lodash_1.default.get(element, 'url') !== undefined),
|
|
146
|
+
source_location: (() => {
|
|
147
|
+
const locs = lodash_1.default.uniq(group.map((d) => d.source_location)).filter((loc) => Object.keys(loc || {}).length !== 0);
|
|
148
|
+
if (locs.length === 0) {
|
|
149
|
+
return {};
|
|
150
|
+
}
|
|
151
|
+
else if (locs.length === 1) {
|
|
152
|
+
return locs[0];
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return { ref: JSON.stringify(locs) };
|
|
156
|
+
}
|
|
157
|
+
})(),
|
|
158
|
+
...(Object.keys(waiverData || {}).length !== 0 && {
|
|
159
|
+
waiver_data: waiverData
|
|
160
|
+
}),
|
|
161
|
+
code: externalProductHandler(context, whichSpecialCase(findings[0]), group, 'code', JSON.stringify({ Findings: findings }, null, 2)),
|
|
162
|
+
results: group.map((d) => d.results).flat()
|
|
40
163
|
};
|
|
164
|
+
output.push(item);
|
|
41
165
|
});
|
|
42
|
-
return
|
|
166
|
+
return output;
|
|
167
|
+
}
|
|
168
|
+
function wrapWithFindingsObject(output) {
|
|
169
|
+
if (!lodash_1.default.has(output, 'Findings')) {
|
|
170
|
+
if (Array.isArray(output)) {
|
|
171
|
+
output = { Findings: output };
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
output = { Findings: [output] };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return output;
|
|
43
178
|
}
|
|
44
179
|
function fixFileInput(asffJson) {
|
|
180
|
+
let output = {};
|
|
45
181
|
try {
|
|
46
|
-
|
|
47
|
-
if (!lodash_1.default.has(output, 'Findings')) {
|
|
48
|
-
if (Array.isArray(output)) {
|
|
49
|
-
output = { Findings: output };
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
output = { Findings: [output] };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return replaceTypesSlashes(output);
|
|
182
|
+
output = JSON.parse(asffJson);
|
|
56
183
|
}
|
|
57
184
|
catch {
|
|
58
185
|
const fixedInput = `[${asffJson
|
|
59
186
|
.trim()
|
|
60
187
|
.replace(/}\n/g, '},\n')
|
|
61
188
|
.replace(/\},\n\$/g, '')}]`;
|
|
62
|
-
|
|
63
|
-
if (!lodash_1.default.has(output, 'Findings')) {
|
|
64
|
-
if (Array.isArray(output)) {
|
|
65
|
-
output = { Findings: output };
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
output = { Findings: [output] };
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return replaceTypesSlashes(output);
|
|
189
|
+
output = JSON.parse(fixedInput);
|
|
72
190
|
}
|
|
191
|
+
return wrapWithFindingsObject(output);
|
|
73
192
|
}
|
|
74
193
|
function getFirewallManager() {
|
|
75
194
|
const findingId = (finding) => (0, html_entities_1.encode)(lodash_1.default.get(finding, 'Title'));
|
|
76
|
-
const productName = (findings) =>
|
|
195
|
+
const productName = (findings) => {
|
|
196
|
+
const finding = Array.isArray(findings) ? findings[0] : findings;
|
|
197
|
+
return (0, html_entities_1.encode)(`${lodash_1.default.get(finding, 'ProductFields.aws/securityhub/CompanyName')} ${lodash_1.default.get(finding, 'ProductFields.aws/securityhub/ProductName')}`);
|
|
198
|
+
};
|
|
199
|
+
const filename = (findingInfo) => {
|
|
200
|
+
return `${productName(findingInfo[1])}.json`;
|
|
201
|
+
};
|
|
77
202
|
return {
|
|
78
203
|
findingId,
|
|
79
|
-
productName
|
|
204
|
+
productName,
|
|
205
|
+
filename
|
|
80
206
|
};
|
|
81
207
|
}
|
|
82
208
|
function getProwler() {
|
|
@@ -86,13 +212,24 @@ function getProwler() {
|
|
|
86
212
|
const hyphenIndex = generatorId.indexOf('-');
|
|
87
213
|
return (0, html_entities_1.encode)(generatorId.slice(hyphenIndex + 1));
|
|
88
214
|
};
|
|
89
|
-
const productName = (findings) =>
|
|
215
|
+
const productName = (findings) => {
|
|
216
|
+
const finding = Array.isArray(findings) ? findings[0] : findings;
|
|
217
|
+
return (0, html_entities_1.encode)(lodash_1.default.get(finding, 'ProductFields.ProviderName'));
|
|
218
|
+
};
|
|
90
219
|
const desc = () => ' ';
|
|
220
|
+
const filename = (findingInfo) => {
|
|
221
|
+
return `${productName(findingInfo[1])}.json`;
|
|
222
|
+
};
|
|
223
|
+
const meta = () => {
|
|
224
|
+
return { name: 'Prowler', title: 'Prowler Findings' };
|
|
225
|
+
};
|
|
91
226
|
return {
|
|
92
227
|
subfindingsCodeDesc,
|
|
93
228
|
findingId,
|
|
94
229
|
productName,
|
|
95
|
-
desc
|
|
230
|
+
desc,
|
|
231
|
+
filename,
|
|
232
|
+
meta
|
|
96
233
|
};
|
|
97
234
|
}
|
|
98
235
|
function getSecurityHub() {
|
|
@@ -101,7 +238,7 @@ function getSecurityHub() {
|
|
|
101
238
|
return controls.find((control) => lodash_1.default.get(control, 'StandardsControlArn') ===
|
|
102
239
|
lodash_1.default.get(finding, FINDING_STANDARDS_CONTROL_ARN));
|
|
103
240
|
};
|
|
104
|
-
const
|
|
241
|
+
const securityhubSupportingDocs = (standards) => {
|
|
105
242
|
let controls;
|
|
106
243
|
try {
|
|
107
244
|
if (Array.isArray(standards)) {
|
|
@@ -177,24 +314,25 @@ function getSecurityHub() {
|
|
|
177
314
|
}
|
|
178
315
|
};
|
|
179
316
|
const productName = (findings) => {
|
|
317
|
+
const finding = Array.isArray(findings) ? findings[0] : findings;
|
|
180
318
|
let standardName;
|
|
181
|
-
if (lodash_1.default.get(
|
|
319
|
+
if (lodash_1.default.get(finding, 'Types[0]')
|
|
182
320
|
.split('/')
|
|
183
321
|
.slice(-1)[0]
|
|
184
322
|
.replace(/-/gi, ' ')
|
|
185
323
|
.toLowerCase() ===
|
|
186
|
-
lodash_1.default.get(
|
|
324
|
+
lodash_1.default.get(finding, FINDING_STANDARDS_CONTROL_ARN)
|
|
187
325
|
.split('/')
|
|
188
326
|
.slice(-4)[0]
|
|
189
327
|
.replace(/-/gi, ' ')
|
|
190
328
|
.toLowerCase()) {
|
|
191
|
-
standardName = lodash_1.default.get(
|
|
329
|
+
standardName = lodash_1.default.get(finding, 'Types[0]')
|
|
192
330
|
.split('/')
|
|
193
331
|
.slice(-1)[0]
|
|
194
332
|
.replace(/-/gi, ' ');
|
|
195
333
|
}
|
|
196
334
|
else {
|
|
197
|
-
standardName = lodash_1.default.get(
|
|
335
|
+
standardName = lodash_1.default.get(finding, FINDING_STANDARDS_CONTROL_ARN)
|
|
198
336
|
.split('/')
|
|
199
337
|
.slice(-4)[0]
|
|
200
338
|
.replace(/-/gi, ' ')
|
|
@@ -204,17 +342,21 @@ function getSecurityHub() {
|
|
|
204
342
|
})
|
|
205
343
|
.join(' ');
|
|
206
344
|
}
|
|
207
|
-
return (0, html_entities_1.encode)(`${standardName} v${lodash_1.default.get(
|
|
345
|
+
return (0, html_entities_1.encode)(`${standardName} v${lodash_1.default.get(finding, FINDING_STANDARDS_CONTROL_ARN)
|
|
208
346
|
.split('/')
|
|
209
347
|
.slice(-2)[0]}`);
|
|
210
348
|
};
|
|
349
|
+
const filename = (findingInfo) => {
|
|
350
|
+
return `${productName(findingInfo[0])}.json`;
|
|
351
|
+
};
|
|
211
352
|
return {
|
|
212
|
-
|
|
353
|
+
securityhubSupportingDocs,
|
|
213
354
|
findingId,
|
|
214
355
|
findingImpact,
|
|
215
356
|
findingNistTag,
|
|
216
357
|
findingTitle,
|
|
217
|
-
productName
|
|
358
|
+
productName,
|
|
359
|
+
filename
|
|
218
360
|
};
|
|
219
361
|
}
|
|
220
362
|
function getTrivy() {
|
|
@@ -254,21 +396,251 @@ function getTrivy() {
|
|
|
254
396
|
return undefined;
|
|
255
397
|
}
|
|
256
398
|
};
|
|
399
|
+
const productName = () => {
|
|
400
|
+
return 'Aqua Security - Trivy';
|
|
401
|
+
};
|
|
402
|
+
const doesNotHaveFindingTitlePrefix = () => true;
|
|
403
|
+
const filename = () => {
|
|
404
|
+
return `${productName()}.json`;
|
|
405
|
+
};
|
|
406
|
+
const meta = () => {
|
|
407
|
+
return { name: 'Trivy', title: 'Trivy Findings' };
|
|
408
|
+
};
|
|
257
409
|
return {
|
|
258
410
|
findingId,
|
|
259
411
|
findingNistTag,
|
|
260
412
|
subfindingsStatus,
|
|
261
|
-
subfindingsMessage
|
|
413
|
+
subfindingsMessage,
|
|
414
|
+
doesNotHaveFindingTitlePrefix,
|
|
415
|
+
productName,
|
|
416
|
+
filename,
|
|
417
|
+
meta
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function getHDF2ASFF() {
|
|
421
|
+
const replaceTypesSlashes = (type) => {
|
|
422
|
+
if (!lodash_1.default.isString(type)) {
|
|
423
|
+
return type;
|
|
424
|
+
}
|
|
425
|
+
const FROM_ASFF_TYPES_SLASH_REPLACEMENT = /{{{SLASH}}}/gi;
|
|
426
|
+
return type.replace(FROM_ASFF_TYPES_SLASH_REPLACEMENT, '/');
|
|
427
|
+
};
|
|
428
|
+
const objectifyTypesArray = (typesArray) => {
|
|
429
|
+
if (!Array.isArray(typesArray)) {
|
|
430
|
+
typesArray = lodash_1.default.get(typesArray, 'FindingProviderFields.Types');
|
|
431
|
+
}
|
|
432
|
+
const ret = {};
|
|
433
|
+
for (const typeString of typesArray) {
|
|
434
|
+
lodash_1.default.merge(ret, (() => {
|
|
435
|
+
const [type, attribute, value] = typeString.split('/');
|
|
436
|
+
let parsed = replaceTypesSlashes(value);
|
|
437
|
+
try {
|
|
438
|
+
parsed = JSON.parse(parsed);
|
|
439
|
+
}
|
|
440
|
+
catch { }
|
|
441
|
+
return { [type]: { [attribute]: parsed } };
|
|
442
|
+
})());
|
|
443
|
+
}
|
|
444
|
+
return ret;
|
|
445
|
+
};
|
|
446
|
+
const findExecutionFindingIndex = (asffOrFindings, asffFindingToMatch) => {
|
|
447
|
+
if (asffFindingToMatch) {
|
|
448
|
+
const targetToMatch = asffFindingToMatch.Id.split('/')[0];
|
|
449
|
+
return lodash_1.default.findIndex(Array.isArray(asffOrFindings)
|
|
450
|
+
? asffOrFindings
|
|
451
|
+
: lodash_1.default.get(asffOrFindings, 'Findings'), (finding) => lodash_1.default.get(finding, 'Id').split('/').length === 2 &&
|
|
452
|
+
lodash_1.default.get(finding, 'Id').startsWith(targetToMatch));
|
|
453
|
+
}
|
|
454
|
+
return lodash_1.default.findIndex(Array.isArray(asffOrFindings)
|
|
455
|
+
? asffOrFindings
|
|
456
|
+
: lodash_1.default.get(asffOrFindings, 'Findings'), (finding) => lodash_1.default.get(finding, 'Id').split('/').length === 2);
|
|
457
|
+
};
|
|
458
|
+
const preprocessingASFF = (asff) => {
|
|
459
|
+
const clone = lodash_1.default.cloneDeep(asff);
|
|
460
|
+
const index = findExecutionFindingIndex(clone);
|
|
461
|
+
lodash_1.default.pullAt(lodash_1.default.get(clone, 'Findings'), index);
|
|
462
|
+
return clone;
|
|
463
|
+
};
|
|
464
|
+
const supportingDocs = (input) => {
|
|
465
|
+
const [asff, docs] = input;
|
|
466
|
+
const index = findExecutionFindingIndex(asff);
|
|
467
|
+
const docsClone = lodash_1.default.cloneDeep(docs);
|
|
468
|
+
docsClone.set(SpecialCasing.HDF2ASFF, {
|
|
469
|
+
execution: lodash_1.default.get(asff, `Findings[${index}]`)
|
|
470
|
+
});
|
|
471
|
+
return docsClone;
|
|
472
|
+
};
|
|
473
|
+
const productName = (findings) => {
|
|
474
|
+
const finding = Array.isArray(findings) ? findings[0] : findings;
|
|
475
|
+
const name = lodash_1.default.get(finding, 'Id');
|
|
476
|
+
return (0, html_entities_1.encode)(name.split('/').slice(0, 2).join(' - '));
|
|
477
|
+
};
|
|
478
|
+
const doesNotHaveFindingTitlePrefix = () => true;
|
|
479
|
+
const code = (group) => {
|
|
480
|
+
return group[0].code || '';
|
|
481
|
+
};
|
|
482
|
+
const waiverData = (group) => {
|
|
483
|
+
return group[0].waiver_data || {};
|
|
484
|
+
};
|
|
485
|
+
const filename = (findingInfo) => {
|
|
486
|
+
const index = findExecutionFindingIndex(findingInfo[1], findingInfo[0]);
|
|
487
|
+
const target = replaceTypesSlashes(lodash_1.default.get(findingInfo[1][index], 'Id').split('/')[0]);
|
|
488
|
+
const finding = findingInfo[0];
|
|
489
|
+
return `${lodash_1.default.get(objectifyTypesArray(finding), 'File.Input')}-${target}.json`;
|
|
490
|
+
};
|
|
491
|
+
const mapping = (context) => {
|
|
492
|
+
var _a;
|
|
493
|
+
const execution = lodash_1.default.get(context.supportingDocs.get(SpecialCasing.HDF2ASFF), 'execution');
|
|
494
|
+
const executionTypes = objectifyTypesArray(execution);
|
|
495
|
+
const profileNames = Object.keys(executionTypes || {}).filter((type) => !['MITRE', 'File', 'Execution'].includes(type));
|
|
496
|
+
return {
|
|
497
|
+
shortcircuit: true,
|
|
498
|
+
platform: {
|
|
499
|
+
...lodash_1.default.get(executionTypes, 'Execution.platform'),
|
|
500
|
+
target_id: ((_a = context.supportingDocs.get(SpecialCasing.HDF2ASFF)) === null || _a === void 0 ? void 0 : _a.execution.Id).split('/')[0]
|
|
501
|
+
},
|
|
502
|
+
version: lodash_1.default.get(executionTypes, 'Execution.version'),
|
|
503
|
+
statistics: lodash_1.default.get(executionTypes, 'Execution.statistics'),
|
|
504
|
+
profiles: lodash_1.default.map(profileNames, (profileName, index) => {
|
|
505
|
+
return {
|
|
506
|
+
name: lodash_1.default.get(executionTypes, `${profileName}.name`),
|
|
507
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.version`) && {
|
|
508
|
+
version: lodash_1.default.get(executionTypes, `${profileName}.version`)
|
|
509
|
+
}),
|
|
510
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.title`) && {
|
|
511
|
+
title: lodash_1.default.get(executionTypes, `${profileName}.title`)
|
|
512
|
+
}),
|
|
513
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.maintainer`) && {
|
|
514
|
+
maintainer: lodash_1.default.get(executionTypes, `${profileName}.maintainer`)
|
|
515
|
+
}),
|
|
516
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.summary`) && {
|
|
517
|
+
summary: lodash_1.default.get(executionTypes, `${profileName}.summary`)
|
|
518
|
+
}),
|
|
519
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.license`) && {
|
|
520
|
+
license: lodash_1.default.get(executionTypes, `${profileName}.license`)
|
|
521
|
+
}),
|
|
522
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.copyright`) && {
|
|
523
|
+
copyright: lodash_1.default.get(executionTypes, `${profileName}.copyright`)
|
|
524
|
+
}),
|
|
525
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.copyright_email`) && {
|
|
526
|
+
copyright_email: lodash_1.default.get(executionTypes, `${profileName}.copyright_email`)
|
|
527
|
+
}),
|
|
528
|
+
supports: lodash_1.default.get(executionTypes, `${profileName}.supports`, []),
|
|
529
|
+
attributes: lodash_1.default.get(executionTypes, `${profileName}.attributes`, []),
|
|
530
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.depends`) && {
|
|
531
|
+
depends: lodash_1.default.get(executionTypes, `${profileName}.depends`)
|
|
532
|
+
}),
|
|
533
|
+
groups: [],
|
|
534
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.status`) && {
|
|
535
|
+
status: lodash_1.default.get(executionTypes, `${profileName}.status`)
|
|
536
|
+
}),
|
|
537
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.description`) && {
|
|
538
|
+
description: lodash_1.default.get(executionTypes, `${profileName}.description`)
|
|
539
|
+
}),
|
|
540
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.inspec_version`) && {
|
|
541
|
+
inspec_version: lodash_1.default.get(executionTypes, `${profileName}.inspec_version`)
|
|
542
|
+
}),
|
|
543
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.parent_profile`) && {
|
|
544
|
+
parent_profile: lodash_1.default.get(executionTypes, `${profileName}.parent_profile`)
|
|
545
|
+
}),
|
|
546
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.skip_message`) && {
|
|
547
|
+
skip_message: lodash_1.default.get(executionTypes, `${profileName}.skip_message`)
|
|
548
|
+
}),
|
|
549
|
+
...(lodash_1.default.has(executionTypes, `${profileName}.status_message`) && {
|
|
550
|
+
status_message: lodash_1.default.get(executionTypes, `${profileName}.status_message`)
|
|
551
|
+
}),
|
|
552
|
+
controls: consolidate(context, (() => {
|
|
553
|
+
console.log('findings length', lodash_1.default.get(context.data, 'Findings')
|
|
554
|
+
.length);
|
|
555
|
+
return lodash_1.default.map(lodash_1.default.get(context.data, 'Findings'), (finding) => {
|
|
556
|
+
const findingTypes = objectifyTypesArray(finding);
|
|
557
|
+
return {
|
|
558
|
+
id: lodash_1.default.get(findingTypes, 'Control.ID'),
|
|
559
|
+
...(lodash_1.default.has(findingTypes, 'Control.Title') && {
|
|
560
|
+
title: lodash_1.default.get(findingTypes, 'Control.Title')
|
|
561
|
+
}),
|
|
562
|
+
...(lodash_1.default.has(findingTypes, 'Control.Desc') && {
|
|
563
|
+
desc: lodash_1.default.get(findingTypes, 'Control.Desc')
|
|
564
|
+
}),
|
|
565
|
+
impact: lodash_1.default.get(findingTypes, 'Control.Impact'),
|
|
566
|
+
tags: {
|
|
567
|
+
...lodash_1.default.omit(lodash_1.default.get(findingTypes, 'Tags'), ['nist']),
|
|
568
|
+
nist: (() => {
|
|
569
|
+
const nisttags = lodash_1.default.get(findingTypes, 'Tags.nist');
|
|
570
|
+
if (nisttags === undefined || nisttags.length === 0) {
|
|
571
|
+
return DEFAULT_NIST_TAG;
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
return nisttags;
|
|
575
|
+
}
|
|
576
|
+
})()
|
|
577
|
+
},
|
|
578
|
+
descriptions: lodash_1.default.map(Object.entries(lodash_1.default.get(findingTypes, 'Descriptions') || {}), ([key, value]) => ({ label: key, data: value })),
|
|
579
|
+
refs: lodash_1.default.get(findingTypes, 'Control.Refs', []),
|
|
580
|
+
source_location: lodash_1.default.get(findingTypes, 'Control.Source_Location', {}),
|
|
581
|
+
...(lodash_1.default.has(findingTypes, 'Control.Waiver_Data') && {
|
|
582
|
+
waiver_data: lodash_1.default.get(findingTypes, 'Control.Waiver_Data')
|
|
583
|
+
}),
|
|
584
|
+
code: '',
|
|
585
|
+
results: index === profileNames.length - 1
|
|
586
|
+
? [
|
|
587
|
+
{
|
|
588
|
+
code_desc: lodash_1.default.get(findingTypes, 'Segment.code_desc'),
|
|
589
|
+
start_time: lodash_1.default.get(findingTypes, 'Segment.start_time'),
|
|
590
|
+
...lodash_1.default.omit(lodash_1.default.get(findingTypes, 'Segment'), [
|
|
591
|
+
'code_desc',
|
|
592
|
+
'start_time'
|
|
593
|
+
])
|
|
594
|
+
}
|
|
595
|
+
]
|
|
596
|
+
: []
|
|
597
|
+
};
|
|
598
|
+
});
|
|
599
|
+
})(), context.data),
|
|
600
|
+
sha256: lodash_1.default.get(executionTypes, `${profileName}.sha256`)
|
|
601
|
+
};
|
|
602
|
+
})
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
return {
|
|
606
|
+
preprocessingASFF,
|
|
607
|
+
supportingDocs,
|
|
608
|
+
productName,
|
|
609
|
+
doesNotHaveFindingTitlePrefix,
|
|
610
|
+
code,
|
|
611
|
+
waiverData,
|
|
612
|
+
filename,
|
|
613
|
+
mapping
|
|
262
614
|
};
|
|
263
615
|
}
|
|
264
616
|
class ASFFMapper extends base_converter_1.BaseConverter {
|
|
265
|
-
constructor(
|
|
266
|
-
super(
|
|
267
|
-
this.
|
|
617
|
+
constructor(asff, supportingDocs, meta = undefined) {
|
|
618
|
+
super(asff);
|
|
619
|
+
this.meta = meta;
|
|
620
|
+
this.supportingDocs = supportingDocs;
|
|
621
|
+
this.setMappings();
|
|
622
|
+
}
|
|
623
|
+
statusReason(finding) {
|
|
624
|
+
var _a;
|
|
625
|
+
return (_a = lodash_1.default.get(finding, 'Compliance.StatusReasons')) === null || _a === void 0 ? void 0 : _a.map((reason) => Object.entries(reason || {}).map(([key, value]) => {
|
|
626
|
+
return `${(0, html_entities_1.encode)(key)}: ${(0, html_entities_1.encode)(value)}`;
|
|
627
|
+
})).flat().join('\n');
|
|
628
|
+
}
|
|
629
|
+
setMappings() {
|
|
630
|
+
this.mappings = externalProductHandler(this, whichSpecialCase(lodash_1.default.get(this.data, 'Findings[0]')), this, 'mapping', {
|
|
268
631
|
platform: {
|
|
269
632
|
name: 'Heimdall Tools',
|
|
270
633
|
release: package_json_1.version,
|
|
271
|
-
target_id:
|
|
634
|
+
target_id: {
|
|
635
|
+
transformer: (record) => {
|
|
636
|
+
const productInfo = lodash_1.default.get(record, 'Findings[0].ProductArn')
|
|
637
|
+
.split(':')
|
|
638
|
+
.slice(-1)[0]
|
|
639
|
+
.split('/');
|
|
640
|
+
const defaultTargetId = `${productInfo[1]} | ${productInfo[2]}`;
|
|
641
|
+
return externalProductHandler(this, whichSpecialCase(lodash_1.default.get(record, 'Findings[0]')), [lodash_1.default.get(record, 'Findings[0]'), record.Findings], 'productName', (0, html_entities_1.encode)(defaultTargetId));
|
|
642
|
+
}
|
|
643
|
+
}
|
|
272
644
|
},
|
|
273
645
|
version: package_json_1.version,
|
|
274
646
|
statistics: {
|
|
@@ -302,12 +674,12 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
302
674
|
{
|
|
303
675
|
path: 'Findings',
|
|
304
676
|
key: 'id',
|
|
305
|
-
arrayTransformer: this
|
|
677
|
+
arrayTransformer: consolidate.bind(this, this),
|
|
306
678
|
id: {
|
|
307
|
-
transformer: (finding) =>
|
|
679
|
+
transformer: (finding) => externalProductHandler(this, whichSpecialCase(finding), finding, 'findingId', (0, html_entities_1.encode)(lodash_1.default.get(finding, 'GeneratorId')))
|
|
308
680
|
},
|
|
309
681
|
title: {
|
|
310
|
-
transformer: (finding) =>
|
|
682
|
+
transformer: (finding) => externalProductHandler(this, whichSpecialCase(finding), finding, 'findingTitle', (0, html_entities_1.encode)(lodash_1.default.get(finding, 'Title')))
|
|
311
683
|
},
|
|
312
684
|
desc: {
|
|
313
685
|
path: 'Description',
|
|
@@ -322,8 +694,9 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
322
694
|
else {
|
|
323
695
|
const defaultFunc = () => lodash_1.default.get(finding, SEVERITY_LABEL)
|
|
324
696
|
? lodash_1.default.get(finding, SEVERITY_LABEL)
|
|
325
|
-
: lodash_1.default.get(finding, 'Severity.Normalized') /
|
|
326
|
-
|
|
697
|
+
: lodash_1.default.get(finding, 'Severity.Normalized') /
|
|
698
|
+
100.0;
|
|
699
|
+
impact = externalProductHandler(this, whichSpecialCase(finding), finding, 'findingImpact', defaultFunc);
|
|
327
700
|
}
|
|
328
701
|
return typeof impact === 'string'
|
|
329
702
|
? IMPACT_MAPPING.get(impact) || 0
|
|
@@ -331,9 +704,10 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
331
704
|
}
|
|
332
705
|
},
|
|
333
706
|
tags: {
|
|
707
|
+
transformer: (finding) => externalProductHandler(this, whichSpecialCase(finding), finding, 'findingTags', {}),
|
|
334
708
|
nist: {
|
|
335
709
|
transformer: (finding) => {
|
|
336
|
-
const tags =
|
|
710
|
+
const tags = externalProductHandler(this, whichSpecialCase(finding), finding, 'findingNistTag', []);
|
|
337
711
|
if (tags.length === 0) {
|
|
338
712
|
return DEFAULT_NIST_TAG;
|
|
339
713
|
}
|
|
@@ -363,9 +737,14 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
363
737
|
],
|
|
364
738
|
refs: [
|
|
365
739
|
{
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
740
|
+
transformer: (finding) => {
|
|
741
|
+
return {
|
|
742
|
+
...(lodash_1.default.has(finding, 'SourceUrl') && {
|
|
743
|
+
url: {
|
|
744
|
+
path: 'SourceUrl'
|
|
745
|
+
}
|
|
746
|
+
})
|
|
747
|
+
};
|
|
369
748
|
}
|
|
370
749
|
}
|
|
371
750
|
],
|
|
@@ -394,12 +773,12 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
394
773
|
return inspecjs_1.ExecJSON.ControlResultStatus.Skipped;
|
|
395
774
|
}
|
|
396
775
|
};
|
|
397
|
-
return
|
|
776
|
+
return externalProductHandler(this, whichSpecialCase(finding), finding, 'subfindingsStatus', defaultFunc);
|
|
398
777
|
}
|
|
399
778
|
},
|
|
400
779
|
code_desc: {
|
|
401
780
|
transformer: (finding) => {
|
|
402
|
-
let output =
|
|
781
|
+
let output = externalProductHandler(this, whichSpecialCase(finding), finding, 'subfindingsCodeDesc', '');
|
|
403
782
|
if (output) {
|
|
404
783
|
output += '; ';
|
|
405
784
|
}
|
|
@@ -419,8 +798,8 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
419
798
|
return output;
|
|
420
799
|
}
|
|
421
800
|
},
|
|
422
|
-
|
|
423
|
-
|
|
801
|
+
transformer: (finding) => {
|
|
802
|
+
const message = (() => {
|
|
424
803
|
const defaultFunc = () => {
|
|
425
804
|
const statusReason = this.statusReason(finding);
|
|
426
805
|
switch (lodash_1.default.get(finding, COMPLIANCE_STATUS)) {
|
|
@@ -438,11 +817,9 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
438
817
|
return statusReason;
|
|
439
818
|
}
|
|
440
819
|
};
|
|
441
|
-
return
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
skip_message: {
|
|
445
|
-
transformer: (finding) => {
|
|
820
|
+
return externalProductHandler(this, whichSpecialCase(finding), finding, 'subfindingsMessage', defaultFunc);
|
|
821
|
+
})();
|
|
822
|
+
const skipMessage = (() => {
|
|
446
823
|
const statusReason = this.statusReason(finding);
|
|
447
824
|
switch (lodash_1.default.get(finding, COMPLIANCE_STATUS)) {
|
|
448
825
|
case undefined:
|
|
@@ -458,7 +835,13 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
458
835
|
default:
|
|
459
836
|
return undefined;
|
|
460
837
|
}
|
|
461
|
-
}
|
|
838
|
+
})();
|
|
839
|
+
return {
|
|
840
|
+
...(message !== undefined && { message }),
|
|
841
|
+
...(skipMessage !== undefined && {
|
|
842
|
+
skip_message: skipMessage
|
|
843
|
+
})
|
|
844
|
+
};
|
|
462
845
|
},
|
|
463
846
|
start_time: {
|
|
464
847
|
transformer: (finding) => lodash_1.default.get(finding, 'LastObservedAt') ||
|
|
@@ -471,109 +854,34 @@ class ASFFMapper extends base_converter_1.BaseConverter {
|
|
|
471
854
|
sha256: ''
|
|
472
855
|
}
|
|
473
856
|
]
|
|
474
|
-
};
|
|
475
|
-
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
exports.ASFFMapper = ASFFMapper;
|
|
861
|
+
class ASFFResults {
|
|
862
|
+
constructor(asffJson, securityhubStandardsJsonArray = undefined, meta = undefined) {
|
|
476
863
|
this.meta = meta;
|
|
477
864
|
this.supportingDocs = new Map();
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
externalProductHandler(product, data, func, defaultVal) {
|
|
490
|
-
var _a;
|
|
491
|
-
let arn = null;
|
|
492
|
-
let mapping;
|
|
493
|
-
if ((product instanceof RegExp ||
|
|
494
|
-
(arn = Array.from(PRODUCT_ARN_MAPPING.keys()).find((regex) => regex.test(product)))) &&
|
|
495
|
-
(mapping = PRODUCT_ARN_MAPPING.get(arn || product)) !==
|
|
496
|
-
undefined &&
|
|
497
|
-
func in mapping) {
|
|
498
|
-
let keywords = {};
|
|
499
|
-
if (this.supportingDocs.has(arn || product)) {
|
|
500
|
-
keywords = { ...this.supportingDocs.get(arn || product) };
|
|
501
|
-
}
|
|
502
|
-
return (_a = lodash_1.default.get(PRODUCT_ARN_MAPPING.get(arn || product), func)) === null || _a === void 0 ? void 0 : _a.apply(this, [data, keywords]);
|
|
503
|
-
}
|
|
504
|
-
else {
|
|
505
|
-
if (typeof defaultVal === 'function') {
|
|
506
|
-
return defaultVal();
|
|
507
|
-
}
|
|
508
|
-
else {
|
|
509
|
-
return defaultVal;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
consolidate(input, file) {
|
|
514
|
-
const allFindings = lodash_1.default.get(file, 'Findings');
|
|
515
|
-
const productGroups = new Map();
|
|
516
|
-
input.forEach((item, index) => {
|
|
517
|
-
var _a, _b, _c, _d;
|
|
518
|
-
let arn = Array.from(PRODUCT_ARN_MAPPING.keys()).find((regex) => lodash_1.default.get(allFindings[index], 'ProductArn').match(regex));
|
|
519
|
-
if (!arn) {
|
|
520
|
-
const productInfo = lodash_1.default.get(allFindings[index], 'ProductArn')
|
|
521
|
-
.split(':')
|
|
522
|
-
.slice(-1)[0];
|
|
523
|
-
arn = new RegExp(`arn:.+:securityhub:.+:.*:product/${productInfo.split('/')[1]}/${productInfo.split('/')[2]}`);
|
|
524
|
-
}
|
|
525
|
-
if (!productGroups.has(arn)) {
|
|
526
|
-
productGroups.set(arn, new Map());
|
|
527
|
-
}
|
|
528
|
-
if (!((_a = productGroups.get(arn)) === null || _a === void 0 ? void 0 : _a.has(lodash_1.default.get(item, 'id')))) {
|
|
529
|
-
(_b = productGroups.get(arn)) === null || _b === void 0 ? void 0 : _b.set(lodash_1.default.get(item, 'id'), []);
|
|
530
|
-
}
|
|
531
|
-
(_d = (_c = productGroups
|
|
532
|
-
.get(arn)) === null || _c === void 0 ? void 0 : _c.get(lodash_1.default.get(item, 'id'))) === null || _d === void 0 ? void 0 : _d.push([item, allFindings[index]]);
|
|
533
|
-
});
|
|
534
|
-
const output = [];
|
|
535
|
-
productGroups.forEach((idGroups, product) => {
|
|
536
|
-
idGroups.forEach((data, id) => {
|
|
537
|
-
const group = data.map((d) => d[0]);
|
|
538
|
-
const findings = data.map((d) => d[1]);
|
|
539
|
-
const productInfo = lodash_1.default.get(findings[0], 'ProductArn')
|
|
540
|
-
.split(':')
|
|
541
|
-
.slice(-1)[0]
|
|
542
|
-
.split('/');
|
|
543
|
-
const productName = this.externalProductHandler(product, findings, 'productName', (0, html_entities_1.encode)(`${productInfo[1]}/${productInfo[2]}`));
|
|
544
|
-
const item = {
|
|
545
|
-
id: Array.from(new Map([...productGroups].filter(([pg]) => pg !== product)).values()).find((ig) => Array.from(ig.keys()).includes(id)) !== undefined
|
|
546
|
-
? `[${productName}] ${id}`
|
|
547
|
-
: id,
|
|
548
|
-
title: `${productName}: ${lodash_1.default.uniq(group.map((d) => lodash_1.default.get(d, 'title'))).join(';')}`,
|
|
549
|
-
tags: {
|
|
550
|
-
nist: lodash_1.default.uniq(group.map((d) => lodash_1.default.get(d, 'tags.nist')).flat())
|
|
551
|
-
},
|
|
552
|
-
impact: Math.max(...group.map((d) => lodash_1.default.get(d, 'impact'))),
|
|
553
|
-
desc: this.externalProductHandler(product, group, 'desc', lodash_1.default.uniq(group.map((d) => lodash_1.default.get(d, 'desc'))).join('\n')),
|
|
554
|
-
descriptions: group
|
|
555
|
-
.map((d) => lodash_1.default.get(d, 'descriptions'))
|
|
556
|
-
.flat()
|
|
557
|
-
.filter((element, index, arr) => element.data !== '' &&
|
|
558
|
-
index === arr.findIndex((e) => e.data === element.data)),
|
|
559
|
-
refs: group
|
|
560
|
-
.map((d) => lodash_1.default.get(d, 'refs'))
|
|
561
|
-
.flat()
|
|
562
|
-
.filter((element) => lodash_1.default.get(element, 'url') !== undefined),
|
|
563
|
-
source_location: {},
|
|
564
|
-
code: JSON.stringify({ Findings: findings }, null, 2),
|
|
565
|
-
results: group
|
|
566
|
-
.map((d) => lodash_1.default.get(d, 'results'))
|
|
567
|
-
.flat()
|
|
568
|
-
};
|
|
569
|
-
output.push(item);
|
|
570
|
-
});
|
|
865
|
+
this.supportingDocs.set(SpecialCasing.SecurityHub, lodash_1.default.get(SPECIAL_CASE_MAPPING.get(SpecialCasing.SecurityHub), 'securityhubSupportingDocs', (standards) => {
|
|
866
|
+
throw new Error(`supportingDocs function should've been defined: ${standards}`);
|
|
867
|
+
})(securityhubStandardsJsonArray));
|
|
868
|
+
const findings = lodash_1.default.get(fixFileInput(asffJson), 'Findings');
|
|
869
|
+
this.data = lodash_1.default.groupBy(findings, (finding) => {
|
|
870
|
+
const productInfo = lodash_1.default.get(finding, 'ProductArn')
|
|
871
|
+
.split(':')
|
|
872
|
+
.slice(-1)[0]
|
|
873
|
+
.split('/');
|
|
874
|
+
const defaultFilename = `${productInfo[1]} | ${productInfo[2]}.json`;
|
|
875
|
+
return externalProductHandler(this, whichSpecialCase(finding), [finding, findings], 'filename', (0, html_entities_1.encode)(defaultFilename));
|
|
571
876
|
});
|
|
572
|
-
return output;
|
|
573
877
|
}
|
|
574
|
-
|
|
575
|
-
|
|
878
|
+
toHdf() {
|
|
879
|
+
return lodash_1.default.mapValues(this.data, (val) => {
|
|
880
|
+
const wrapped = wrapWithFindingsObject(val);
|
|
881
|
+
const ret = new ASFFMapper(externalProductHandler(this, whichSpecialCase(lodash_1.default.get(wrapped, 'Findings[0]')), wrapped, 'preprocessingASFF', wrapped), externalProductHandler(this, whichSpecialCase(lodash_1.default.get(wrapped, 'Findings[0]')), [wrapped, this.supportingDocs], 'supportingDocs', this.supportingDocs), externalProductHandler(this, whichSpecialCase(lodash_1.default.get(wrapped, 'Findings[0]')), undefined, 'meta', this.meta)).toHdf();
|
|
882
|
+
return ret;
|
|
883
|
+
});
|
|
576
884
|
}
|
|
577
885
|
}
|
|
578
|
-
exports.
|
|
886
|
+
exports.ASFFResults = ASFFResults;
|
|
579
887
|
//# sourceMappingURL=asff-mapper.js.map
|