@mitre/inspec-objects 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/e2e-test.yml +38 -0
- package/error.log +12 -0
- package/lib/objects/control.d.ts +7 -3
- package/lib/objects/control.js +8 -1
- package/lib/parsers/oval.d.ts +2 -0
- package/lib/parsers/oval.js +17 -0
- package/lib/parsers/xccdf.d.ts +7 -1
- package/lib/parsers/xccdf.js +198 -50
- package/lib/utilities/diff.d.ts +2 -0
- package/lib/utilities/diff.js +7 -3
- package/lib/utilities/global.d.ts +2 -0
- package/lib/utilities/global.js +24 -1
- package/lib/utilities/xccdf.d.ts +1 -1
- package/lib/utilities/xccdf.js +5 -2
- package/mitre-inspec-objects-v0.0.1.tgz +0 -0
- package/package-lock.json +219 -21
- package/package.json +2 -2
- package/src/objects/control.ts +15 -4
- package/src/parsers/oval.ts +18 -0
- package/src/parsers/xccdf.ts +200 -52
- package/src/types/oval.d.ts +609 -0
- package/src/types/xccdf.d.ts +830 -73
- package/src/utilities/diff.ts +9 -3
- package/src/utilities/global.ts +29 -0
- package/src/utilities/xccdf.ts +8 -3
- package/tsconfig.json +2 -1
- package/types/ionchannelAnalysis.d.ts +238 -0
- package/types/ionchannelProjects.d.ts +72 -0
- package/types/ionchannelTeams.d.ts +26 -0
- package/types/reverseMappedXCCDF.d.ts +67 -0
- package/types/splunk-sdk-no-env/index.d.ts +88 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Run TS-InSpec-Objects E2E Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-20.04
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v2
|
|
15
|
+
|
|
16
|
+
- name: Cache node modules
|
|
17
|
+
uses: actions/cache@v2
|
|
18
|
+
env:
|
|
19
|
+
cache-name: cache-node-modules
|
|
20
|
+
with:
|
|
21
|
+
# npm cache files are stored in `~/.npm` on Linux/macOS
|
|
22
|
+
path: ~/.npm
|
|
23
|
+
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
|
|
24
|
+
restore-keys: |
|
|
25
|
+
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
26
|
+
${{ runner.os }}-build-
|
|
27
|
+
${{ runner.os }}-
|
|
28
|
+
|
|
29
|
+
- name: Setup Node.js
|
|
30
|
+
uses: actions/setup-node@v1
|
|
31
|
+
with:
|
|
32
|
+
node-version: '16.x'
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: npm install
|
|
36
|
+
|
|
37
|
+
- name: Run e2e tests
|
|
38
|
+
run: yarn test
|
package/error.log
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
yarn run v1.22.19
|
|
2
|
+
$ jest 2
|
|
3
|
+
No tests found, exiting with code 1
|
|
4
|
+
Run with `--passWithNoTests` to exit with code 0
|
|
5
|
+
In /home/c/Documents/SAF/ts-inspec-objects
|
|
6
|
+
219 files checked.
|
|
7
|
+
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 4 matches
|
|
8
|
+
testPathIgnorePatterns: /node_modules/ - 219 matches
|
|
9
|
+
testRegex: - 0 matches
|
|
10
|
+
Pattern: 2 - 0 matches
|
|
11
|
+
error Command failed with exit code 1.
|
|
12
|
+
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
|
package/lib/objects/control.d.ts
CHANGED
|
@@ -5,11 +5,15 @@ export default class Control {
|
|
|
5
5
|
code?: string | null;
|
|
6
6
|
desc?: string | null;
|
|
7
7
|
descs?: ExecJSON.ControlDescription[] | {
|
|
8
|
-
[key: string]: string;
|
|
8
|
+
[key: string]: string | undefined;
|
|
9
9
|
} | null;
|
|
10
10
|
impact?: number;
|
|
11
11
|
ref?: string;
|
|
12
|
-
refs?: string
|
|
12
|
+
refs?: (string | {
|
|
13
|
+
ref?: string;
|
|
14
|
+
url?: string;
|
|
15
|
+
uri?: string;
|
|
16
|
+
})[];
|
|
13
17
|
tags: {
|
|
14
18
|
check?: string;
|
|
15
19
|
fix?: string;
|
|
@@ -19,7 +23,7 @@ export default class Control {
|
|
|
19
23
|
satisfies?: string[];
|
|
20
24
|
rid?: string;
|
|
21
25
|
stig_id?: string;
|
|
22
|
-
fix_id?: string;
|
|
26
|
+
fix_id?: string | null;
|
|
23
27
|
cci?: string[];
|
|
24
28
|
cis_controls?: Record<string, string[]>[];
|
|
25
29
|
nist?: string[];
|
package/lib/objects/control.js
CHANGED
|
@@ -6,6 +6,8 @@ const flat_1 = require("flat");
|
|
|
6
6
|
const global_1 = require("../utilities/global");
|
|
7
7
|
class Control {
|
|
8
8
|
constructor(data) {
|
|
9
|
+
this.tags = {};
|
|
10
|
+
this.refs = [];
|
|
9
11
|
this.tags = {};
|
|
10
12
|
if (data) {
|
|
11
13
|
Object.entries(data).forEach(([key, value]) => {
|
|
@@ -55,7 +57,12 @@ class Control {
|
|
|
55
57
|
}
|
|
56
58
|
if (this.refs) {
|
|
57
59
|
this.refs.forEach((ref) => {
|
|
58
|
-
|
|
60
|
+
if (typeof ref === 'string') {
|
|
61
|
+
result += ` ref '${(0, global_1.escapeQuotes)(ref)}'\n`;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
result += ` ref '${(0, global_1.escapeQuotes)(ref.ref || '')}', url: '${(0, global_1.escapeQuotes)(ref.url || '')}'`;
|
|
65
|
+
}
|
|
59
66
|
});
|
|
60
67
|
}
|
|
61
68
|
Object.entries(this.tags).forEach(([tag, value]) => {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processOVAL = void 0;
|
|
4
|
+
const xccdf_1 = require("../utilities/xccdf");
|
|
5
|
+
function processOVAL(oval) {
|
|
6
|
+
const parsed = (0, xccdf_1.convertEncodedXmlIntoJson)(oval);
|
|
7
|
+
const extractedDefinitions = {};
|
|
8
|
+
for (const ovalDefinitions of parsed.oval_definitions) {
|
|
9
|
+
for (const definitionList of ovalDefinitions.definitions) {
|
|
10
|
+
for (const definition of definitionList.definition) {
|
|
11
|
+
extractedDefinitions[definition["@_id"]] = definition;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return extractedDefinitions;
|
|
16
|
+
}
|
|
17
|
+
exports.processOVAL = processOVAL;
|
package/lib/parsers/xccdf.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import Profile from '../objects/profile';
|
|
2
|
-
|
|
2
|
+
import { BenchmarkGroup, BenchmarkRule } from '../types/xccdf';
|
|
3
|
+
import { OvalDefinitionValue } from '../types/oval';
|
|
4
|
+
export declare type GroupContextualizedRule = BenchmarkRule & {
|
|
5
|
+
group: Omit<BenchmarkGroup, 'Rule' | 'Group'>;
|
|
6
|
+
};
|
|
7
|
+
export declare function extractAllRules(groups: BenchmarkGroup[]): GroupContextualizedRule[];
|
|
8
|
+
export declare function processXCCDF(xml: string, ovalDefinitions?: Record<string, OvalDefinitionValue>): Profile;
|
package/lib/parsers/xccdf.js
CHANGED
|
@@ -1,67 +1,215 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.processXCCDF = void 0;
|
|
3
|
+
exports.processXCCDF = exports.extractAllRules = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const CciNistMappingData_1 = require("@mitre/hdf-converters/lib/src/mappings/CciNistMappingData");
|
|
6
5
|
const profile_1 = tslib_1.__importDefault(require("../objects/profile"));
|
|
7
6
|
const xccdf_1 = require("../utilities/xccdf");
|
|
8
7
|
const control_1 = tslib_1.__importDefault(require("../objects/control"));
|
|
9
8
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
10
|
-
|
|
9
|
+
const hdf_converters_1 = require("@mitre/hdf-converters");
|
|
10
|
+
function extractAllRules(groups) {
|
|
11
|
+
const rules = [];
|
|
12
|
+
groups.forEach((group) => {
|
|
13
|
+
if (group.Rule) {
|
|
14
|
+
rules.push(...(group.Rule.map((rule) => {
|
|
15
|
+
return {
|
|
16
|
+
...rule,
|
|
17
|
+
group: lodash_1.default.omit(group, ['Rule', 'Group'])
|
|
18
|
+
};
|
|
19
|
+
})));
|
|
20
|
+
}
|
|
21
|
+
if (group.Group) {
|
|
22
|
+
rules.push(...extractAllRules(group.Group));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return rules;
|
|
26
|
+
}
|
|
27
|
+
exports.extractAllRules = extractAllRules;
|
|
28
|
+
function processXCCDF(xml, ovalDefinitions) {
|
|
11
29
|
const parsedXML = (0, xccdf_1.convertEncodedXmlIntoJson)(xml);
|
|
12
|
-
const
|
|
30
|
+
const rules = extractAllRules(parsedXML.Benchmark[0].Group);
|
|
13
31
|
const profile = new profile_1.default({
|
|
14
|
-
name: parsedXML.Benchmark['@_id'],
|
|
15
|
-
title: parsedXML.Benchmark.title,
|
|
16
|
-
summary: parsedXML.Benchmark.description
|
|
32
|
+
name: parsedXML.Benchmark[0]['@_id'],
|
|
33
|
+
title: parsedXML.Benchmark[0].title[0]['#text'],
|
|
34
|
+
summary: parsedXML.Benchmark[0].description[0]['#text']
|
|
17
35
|
});
|
|
18
|
-
|
|
36
|
+
rules.forEach(rule => {
|
|
19
37
|
var _a, _b, _c;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
let extractedDescription;
|
|
39
|
+
if (Array.isArray(rule.description)) {
|
|
40
|
+
extractedDescription = rule.description[0]['#text'];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
extractedDescription = (0, xccdf_1.convertEncodedHTMLIntoJson)(rule.description);
|
|
44
|
+
}
|
|
45
|
+
const control = new control_1.default();
|
|
46
|
+
control.id = rule.group['@_id'];
|
|
47
|
+
control.title = rule['@_severity'] ? rule.title : `[[[MISSING SEVERITY FROM STIG]]] ${rule.title}`;
|
|
48
|
+
control.desc = typeof extractedDescription === 'string' ? extractedDescription : (_a = extractedDescription.VulnDiscussion) === null || _a === void 0 ? void 0 : _a.split('Satisfies: ')[0];
|
|
49
|
+
control.impact = (0, xccdf_1.severityStringToImpact)(rule['@_severity'] || 'critical', rule.group['@_id']);
|
|
50
|
+
if (!control.descs || Array.isArray(control.descs)) {
|
|
51
|
+
control.descs = {};
|
|
52
|
+
}
|
|
53
|
+
if (rule.check) {
|
|
54
|
+
if (rule.check.some((ruleValue) => 'check-content' in ruleValue)) {
|
|
55
|
+
control.descs.check = rule.check ? rule.check[0]['check-content'] : 'Missing description';
|
|
56
|
+
}
|
|
57
|
+
else if (rule.check.some((ruleValue) => 'check-content-ref' in ruleValue) && ovalDefinitions) {
|
|
58
|
+
let referenceID = null;
|
|
59
|
+
for (const checkContent of rule.check) {
|
|
60
|
+
if ('check-content-ref' in checkContent && checkContent['@_system'].includes('oval')) {
|
|
61
|
+
for (const checkContentRef of checkContent['check-content-ref']) {
|
|
62
|
+
if (checkContentRef['@_name']) {
|
|
63
|
+
referenceID = checkContentRef['@_name'];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (referenceID && referenceID in ovalDefinitions) {
|
|
69
|
+
control.descs.check = ovalDefinitions[referenceID].metadata[0].title;
|
|
70
|
+
}
|
|
71
|
+
else if (referenceID) {
|
|
72
|
+
console.warn(`Could not find OVAL definition for ${referenceID}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
control.descs.fix = rule.fixtext ? rule.fixtext[0]['#text'] : (rule.fix ? rule.fix[0]['#text'] || 'Missing fix text' : 'Missing fix text');
|
|
77
|
+
control.tags.severity = (0, xccdf_1.impactNumberToSeverityString)((0, xccdf_1.severityStringToImpact)(rule['@_severity'] || 'critical', control.id));
|
|
78
|
+
control.tags.gid = rule.group['@_id'],
|
|
79
|
+
control.tags.rid = rule['@_id'];
|
|
80
|
+
control.tags.stig_id = rule['version'];
|
|
81
|
+
if (typeof rule.group.title === "string") {
|
|
82
|
+
control.tags.gtitle = rule.group.title;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
control.tags.gtitle = lodash_1.default.get(rule.group, 'title[0].#text');
|
|
86
|
+
}
|
|
87
|
+
if (rule['fix'] && rule['fix'].length > 0) {
|
|
88
|
+
control.tags.fix_id = rule['fix'][0]['@_id'];
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
control.tags.fix_id = null;
|
|
92
|
+
}
|
|
93
|
+
if (rule['rationale']) {
|
|
94
|
+
control.tags.rationale = rule['rationale'][0]['#text'];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
control.tags.rationale = null;
|
|
98
|
+
}
|
|
99
|
+
if (typeof extractedDescription === 'object') {
|
|
100
|
+
control.tags.satisfies = ((_b = extractedDescription.VulnDiscussion) === null || _b === void 0 ? void 0 : _b.includes('Satisfies: ')) && extractedDescription.VulnDiscussion.split('Satisfies: ').length >= 1 ? extractedDescription.VulnDiscussion.split('Satisfies: ')[1].split(',').map(satisfaction => satisfaction.trim()) : undefined;
|
|
101
|
+
control.tags.false_negatives = extractedDescription.FalseNegatives || undefined;
|
|
102
|
+
control.tags.false_positives = extractedDescription.FalsePositives || undefined;
|
|
103
|
+
control.tags.documentable = typeof extractedDescription.Documentable === 'boolean' ? extractedDescription.Documentable : undefined;
|
|
104
|
+
control.tags.mitigations = extractedDescription.Mitigations || undefined;
|
|
105
|
+
control.tags.severity_override_guidance = extractedDescription.SeverityOverrideGuidance || undefined;
|
|
106
|
+
control.tags.potential_impacts = extractedDescription.PotentialImpacts || undefined;
|
|
107
|
+
control.tags.third_party_tools = extractedDescription.ThirdPartyTools || undefined;
|
|
108
|
+
control.tags.mitigation_control = extractedDescription.MitigationControl || undefined;
|
|
109
|
+
control.tags.mitigation_controls = extractedDescription.MitigationControls || undefined;
|
|
110
|
+
control.tags.responsibility = extractedDescription.Responsibility || undefined;
|
|
111
|
+
control.tags.ia_controls = extractedDescription.IAControls || undefined;
|
|
112
|
+
}
|
|
113
|
+
control.tags = lodash_1.default.omitBy(control.tags, (value) => value === undefined);
|
|
114
|
+
// Get all identifiers from the rule
|
|
115
|
+
if (rule.ident) {
|
|
116
|
+
rule.ident.forEach((identifier) => {
|
|
55
117
|
var _a, _b, _c;
|
|
56
|
-
|
|
57
|
-
if (identifier['@_system'].toLowerCase().
|
|
58
|
-
(
|
|
59
|
-
|
|
60
|
-
|
|
118
|
+
// Get CCIs
|
|
119
|
+
if (identifier['@_system'].toLowerCase().includes('cci')) {
|
|
120
|
+
if (!('cci' in control.tags)) {
|
|
121
|
+
control.tags.cci = [];
|
|
122
|
+
}
|
|
123
|
+
(_a = control.tags.cci) === null || _a === void 0 ? void 0 : _a.push(identifier['#text']);
|
|
124
|
+
}
|
|
125
|
+
// Get legacy identifiers
|
|
126
|
+
else if (identifier['@_system'].toLowerCase().includes('legacy')) {
|
|
127
|
+
if (!('legacy' in control.tags)) {
|
|
128
|
+
control.tags.legacy = [];
|
|
61
129
|
}
|
|
130
|
+
(_b = control.tags.legacy) === null || _b === void 0 ? void 0 : _b.push(identifier['#text']);
|
|
131
|
+
}
|
|
132
|
+
// Get NIST identifiers
|
|
133
|
+
else if (identifier['@_system'].toLowerCase().includes('nist')) {
|
|
134
|
+
if (!('nist' in control.tags)) {
|
|
135
|
+
control.tags.nist = [];
|
|
136
|
+
}
|
|
137
|
+
(_c = control.tags.nist) === null || _c === void 0 ? void 0 : _c.push(identifier['#text']);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
// console.log('Alert')
|
|
141
|
+
// console.log(identifier['@_system'])
|
|
142
|
+
// console.log(identifier['#text'])
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
(_c = rule.reference) === null || _c === void 0 ? void 0 : _c.forEach((reference) => {
|
|
147
|
+
var _a, _b, _c, _d;
|
|
148
|
+
if (lodash_1.default.get(reference, '@_href') === '') {
|
|
149
|
+
(_a = control.refs) === null || _a === void 0 ? void 0 : _a.push(lodash_1.default.get(reference, '#text'));
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
try {
|
|
153
|
+
const referenceText = lodash_1.default.get(reference, '#text') || '';
|
|
154
|
+
const referenceURL = lodash_1.default.get(reference, '@_href') || '';
|
|
155
|
+
if (referenceURL) {
|
|
156
|
+
const parsedURL = new URL(lodash_1.default.get(reference, '@_href'));
|
|
157
|
+
if (parsedURL.protocol.toLowerCase().includes('http') || parsedURL.protocol.toLowerCase().includes('https')) {
|
|
158
|
+
(_b = control.refs) === null || _b === void 0 ? void 0 : _b.push({
|
|
159
|
+
ref: referenceText,
|
|
160
|
+
url: referenceURL
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
(_c = control.refs) === null || _c === void 0 ? void 0 : _c.push({
|
|
165
|
+
ref: referenceText,
|
|
166
|
+
uri: referenceURL
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
if ('title' in reference) {
|
|
172
|
+
(_d = control.refs) === null || _d === void 0 ? void 0 : _d.push(lodash_1.default.get(reference, 'title'));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Add the reference to the control tags when seperated by §
|
|
176
|
+
if (typeof referenceText === 'string' && referenceText.indexOf('§') !== -1) {
|
|
177
|
+
const referenceParts = referenceText.split('§');
|
|
178
|
+
if (referenceParts.length == 2) {
|
|
179
|
+
let [identifierType, identifier] = referenceText.split('§');
|
|
180
|
+
identifierType = identifierType.toLowerCase();
|
|
181
|
+
if (!(identifierType in control.tags)) {
|
|
182
|
+
control.tags[identifierType] = [identifier];
|
|
183
|
+
}
|
|
184
|
+
else if (Array.isArray(control.tags[identifierType])) {
|
|
185
|
+
control.tags[identifierType] = lodash_1.default.union(control.tags[identifierType], [identifier]);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.warn(`Attempted to push identifier to control tags when identifier already exists: ${identifierType}: ${identifier}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.warn("Reference parts of invalid length:");
|
|
193
|
+
console.log(referenceParts);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
console.warn(`Error parsing ref for control ${control.id}: `);
|
|
199
|
+
console.warn(JSON.stringify(reference, null, 2));
|
|
200
|
+
console.warn(e);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
// Associate any CCIs with NIST tags
|
|
205
|
+
if (control.tags.cci) {
|
|
206
|
+
control.tags.cci.forEach((cci) => {
|
|
207
|
+
var _a;
|
|
208
|
+
if (!('nist' in control.tags)) {
|
|
209
|
+
control.tags.nist = [];
|
|
62
210
|
}
|
|
63
|
-
if (
|
|
64
|
-
(
|
|
211
|
+
if (cci in hdf_converters_1.CciNistMappingData.data) {
|
|
212
|
+
(_a = control.tags.nist) === null || _a === void 0 ? void 0 : _a.push(lodash_1.default.get(hdf_converters_1.CciNistMappingData.data, cci));
|
|
65
213
|
}
|
|
66
214
|
});
|
|
67
215
|
}
|
package/lib/utilities/diff.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import Profile from '../objects/profile';
|
|
2
2
|
import { ProfileDiff } from '../types/diff';
|
|
3
|
+
import Control from '../objects/control';
|
|
4
|
+
export declare function updateControl(originalControlString: string, originalControl: Control, updatedControl: Control): void;
|
|
3
5
|
export declare function diffProfile(fromProfile: Profile, toProfile: Profile): ProfileDiff;
|
package/lib/utilities/diff.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.diffProfile = void 0;
|
|
3
|
+
exports.diffProfile = exports.updateControl = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const json_diff_1 = require("json-diff");
|
|
6
6
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
+
function updateControl(originalControlString, originalControl, updatedControl) {
|
|
8
|
+
console.log('Here is the original control:');
|
|
9
|
+
}
|
|
10
|
+
exports.updateControl = updateControl;
|
|
7
11
|
function diffProfile(fromProfile, toProfile) {
|
|
8
12
|
const profileDiff = {
|
|
9
13
|
addedControlIDs: [],
|
|
@@ -14,7 +18,7 @@ function diffProfile(fromProfile, toProfile) {
|
|
|
14
18
|
const toControlIDs = toProfile.controls.map((control) => control.id).sort();
|
|
15
19
|
// Find new controls
|
|
16
20
|
const controlIDDiff = (0, json_diff_1.diff)(fromControlIDs, toControlIDs);
|
|
17
|
-
controlIDDiff.forEach((diffValue) => {
|
|
21
|
+
controlIDDiff === null || controlIDDiff === void 0 ? void 0 : controlIDDiff.forEach((diffValue) => {
|
|
18
22
|
if (diffValue[0] === '-') {
|
|
19
23
|
profileDiff.removedControlIDs.push(diffValue[1]);
|
|
20
24
|
}
|
|
@@ -40,7 +44,7 @@ function diffProfile(fromProfile, toProfile) {
|
|
|
40
44
|
lodash_1.default.set(profileDiff, 'changedControls.' + fromControl.id + '.' + key.replace('.', '\\.'), lodash_1.default.get(controlDiff, key + '.__new'));
|
|
41
45
|
}
|
|
42
46
|
else if (typeof value === 'object') {
|
|
43
|
-
Object.entries(value).forEach(([subKey
|
|
47
|
+
Object.entries(value).forEach(([subKey]) => {
|
|
44
48
|
lodash_1.default.set(profileDiff, 'changedControls.' + fromControl.id + '.' + key.replace('.', '\\.') + '.' + subKey.replace('.', '\\.'), lodash_1.default.get(controlDiff, key + '.' + subKey + '.__new'));
|
|
45
49
|
});
|
|
46
50
|
}
|
|
@@ -4,3 +4,5 @@ declare const escapeQuotes: (s: string) => string;
|
|
|
4
4
|
declare const escapeDoubleQuotes: (s: string) => string;
|
|
5
5
|
declare const wrapAndEscapeQuotes: (s: string, lineLength?: number) => string;
|
|
6
6
|
export { escapeQuotes, escapeDoubleQuotes, wrapAndEscapeQuotes };
|
|
7
|
+
export declare function getFirstPath(object: Record<string, unknown>, paths: string[]): string;
|
|
8
|
+
export declare function hasPath(file: Record<string, unknown>, path: string | string[]): boolean;
|
package/lib/utilities/global.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.wrapAndEscapeQuotes = exports.escapeDoubleQuotes = exports.escapeQuotes = exports.unformatText = exports.wrap = void 0;
|
|
3
|
+
exports.hasPath = exports.getFirstPath = exports.wrapAndEscapeQuotes = exports.escapeDoubleQuotes = exports.escapeQuotes = exports.unformatText = exports.wrap = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
4
6
|
// Breaks lines down to lineLength number of characters
|
|
5
7
|
function wrap(s, lineLength = 80) {
|
|
6
8
|
return s.replace(new RegExp(`(?![^\n]{1,${lineLength}}$)([^\n]{1,${lineLength}})`, "g"), "$1\n");
|
|
@@ -16,3 +18,24 @@ const escapeDoubleQuotes = (s) => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
|
16
18
|
exports.escapeDoubleQuotes = escapeDoubleQuotes;
|
|
17
19
|
const wrapAndEscapeQuotes = (s, lineLength) => escapeDoubleQuotes(wrap(s, lineLength)); // Escape backslashes and quotes, and wrap long lines
|
|
18
20
|
exports.wrapAndEscapeQuotes = wrapAndEscapeQuotes;
|
|
21
|
+
function getFirstPath(object, paths) {
|
|
22
|
+
const index = lodash_1.default.findIndex(paths, (p) => hasPath(object, p));
|
|
23
|
+
if (index === -1) {
|
|
24
|
+
throw new Error(`Attestation is missing one of these paths: ${paths.join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return lodash_1.default.get(object, paths[index]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.getFirstPath = getFirstPath;
|
|
31
|
+
function hasPath(file, path) {
|
|
32
|
+
let pathArray;
|
|
33
|
+
if (typeof path === 'string') {
|
|
34
|
+
pathArray = [path];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
pathArray = path;
|
|
38
|
+
}
|
|
39
|
+
return lodash_1.default.some(pathArray, (p) => lodash_1.default.has(file, p));
|
|
40
|
+
}
|
|
41
|
+
exports.hasPath = hasPath;
|
package/lib/utilities/xccdf.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DecodedDescription } from '../types/xccdf';
|
|
2
2
|
export declare function convertEncodedXmlIntoJson(encodedXml: string): any;
|
|
3
|
-
export declare function severityStringToImpact(string: string): number;
|
|
3
|
+
export declare function severityStringToImpact(string: string, id: string): number;
|
|
4
4
|
export declare function impactNumberToSeverityString(impact: number): string;
|
|
5
5
|
export declare function convertEncodedHTMLIntoJson(encodedHTML?: string): DecodedDescription;
|
package/lib/utilities/xccdf.js
CHANGED
|
@@ -8,11 +8,13 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
|
8
8
|
function convertEncodedXmlIntoJson(encodedXml) {
|
|
9
9
|
return fast_xml_parser_1.default.parse(encodedXml, {
|
|
10
10
|
ignoreAttributes: false,
|
|
11
|
+
ignoreNameSpace: true,
|
|
11
12
|
attributeNamePrefix: '@_',
|
|
13
|
+
arrayMode: true
|
|
12
14
|
});
|
|
13
15
|
}
|
|
14
16
|
exports.convertEncodedXmlIntoJson = convertEncodedXmlIntoJson;
|
|
15
|
-
function severityStringToImpact(string) {
|
|
17
|
+
function severityStringToImpact(string, id) {
|
|
16
18
|
var _a, _b, _c, _d, _e;
|
|
17
19
|
if ((_a = string.match(/none|na|n\/a|not[\s()*_|]?applicable/i)) === null || _a === void 0 ? void 0 : _a.length) {
|
|
18
20
|
return 0.0;
|
|
@@ -29,7 +31,8 @@ function severityStringToImpact(string) {
|
|
|
29
31
|
if ((_e = string.match(/crit(ical)?|severe/)) === null || _e === void 0 ? void 0 : _e.length) {
|
|
30
32
|
return 1.0;
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
console.log(`${string} is not a valid severity value. It should be one of the approved keywords. ${id} will be treated as medium severity`);
|
|
35
|
+
return 0.5;
|
|
33
36
|
}
|
|
34
37
|
exports.severityStringToImpact = severityStringToImpact;
|
|
35
38
|
function impactNumberToSeverityString(impact) {
|
|
Binary file
|