@contrast/contrast 1.0.7 → 1.0.10
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 +1 -1
- package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +17 -26
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +98 -37
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +4 -3
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +3 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +87 -19
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +40 -7
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +6 -30
- package/dist/audit/save.js +37 -0
- package/dist/commands/audit/auditConfig.js +0 -16
- package/dist/commands/audit/auditController.js +18 -11
- package/dist/commands/audit/help.js +31 -25
- package/dist/commands/audit/processAudit.js +2 -2
- package/dist/commands/audit/saveFile.js +8 -4
- package/dist/commands/scan/sca/scaAnalysis.js +54 -16
- package/dist/common/HTTPClient.js +14 -8
- package/dist/common/errorHandling.js +2 -2
- package/dist/common/versionChecker.js +19 -4
- package/dist/constants/constants.js +7 -2
- package/dist/constants/locales.js +44 -44
- package/dist/constants.js +31 -14
- package/dist/index.js +55 -45
- package/dist/lambda/lambda.js +5 -2
- package/dist/sbom/generateSbom.js +5 -4
- package/dist/scaAnalysis/common/formatMessage.js +33 -6
- package/dist/scaAnalysis/common/treeUpload.js +4 -6
- package/dist/scaAnalysis/dotnet/analysis.js +43 -0
- package/dist/scaAnalysis/dotnet/index.js +10 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +1 -3
- package/dist/scaAnalysis/java/analysis.js +5 -5
- package/dist/scaAnalysis/javascript/analysis.js +107 -0
- package/dist/scaAnalysis/javascript/index.js +53 -0
- package/dist/scaAnalysis/php/analysis.js +70 -0
- package/dist/scaAnalysis/php/index.js +17 -0
- package/dist/scaAnalysis/python/analysis.js +8 -7
- package/dist/scaAnalysis/ruby/analysis.js +8 -16
- package/dist/scaAnalysis/ruby/index.js +2 -2
- package/dist/scan/autoDetection.js +13 -24
- package/dist/scan/fileUtils.js +44 -14
- package/dist/scan/formatScanOutput.js +3 -3
- package/dist/scan/scanConfig.js +2 -2
- package/dist/utils/commonApi.js +1 -1
- package/dist/utils/filterProjectPath.js +7 -2
- package/dist/utils/getConfig.js +1 -6
- package/package.json +2 -3
- package/src/audit/catalogueApplication/catalogueApplication.js +28 -6
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +22 -58
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +157 -47
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +4 -1
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +11 -5
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +4 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +86 -32
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +44 -5
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +6 -32
- package/src/audit/save.js +48 -0
- package/src/commands/audit/auditConfig.ts +0 -25
- package/src/commands/audit/auditController.ts +18 -20
- package/src/commands/audit/help.ts +31 -25
- package/src/commands/audit/processAudit.ts +2 -5
- package/src/commands/audit/saveFile.ts +6 -2
- package/src/commands/scan/processScan.js +0 -1
- package/src/commands/scan/sca/scaAnalysis.js +87 -32
- package/src/common/HTTPClient.js +16 -9
- package/src/common/errorHandling.ts +2 -3
- package/src/common/versionChecker.ts +23 -4
- package/src/constants/constants.js +9 -3
- package/src/constants/locales.js +72 -50
- package/src/constants.js +32 -15
- package/src/index.ts +70 -58
- package/src/lambda/lambda.ts +5 -2
- package/src/lambda/types.ts +1 -0
- package/src/sbom/generateSbom.ts +2 -2
- package/src/scaAnalysis/common/formatMessage.js +35 -6
- package/src/scaAnalysis/common/treeUpload.js +4 -6
- package/src/scaAnalysis/dotnet/analysis.js +54 -0
- package/src/scaAnalysis/dotnet/index.js +11 -0
- package/src/scaAnalysis/go/goReadDepFile.js +1 -3
- package/src/scaAnalysis/java/analysis.js +5 -5
- package/src/scaAnalysis/javascript/analysis.js +126 -0
- package/src/scaAnalysis/javascript/index.js +75 -0
- package/src/scaAnalysis/php/analysis.js +78 -0
- package/src/scaAnalysis/php/index.js +22 -0
- package/src/scaAnalysis/python/analysis.js +8 -7
- package/src/scaAnalysis/ruby/analysis.js +8 -17
- package/src/scaAnalysis/ruby/index.js +2 -2
- package/src/scan/autoDetection.js +14 -27
- package/src/scan/fileUtils.js +46 -14
- package/src/scan/formatScanOutput.ts +3 -3
- package/src/scan/scanConfig.js +2 -4
- package/src/utils/commonApi.js +1 -1
- package/src/utils/filterProjectPath.js +6 -2
- package/src/utils/getConfig.ts +1 -12
- package/dist/audit/AnalysisEngine.js +0 -37
- package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
- package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
- package/dist/audit/goAnalysisEngine/index.js +0 -17
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
- package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/javaAnalysisEngine/index.js +0 -34
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -155
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
- package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -25
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -25
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -24
- package/dist/audit/languageAnalysisEngine/constants.js +0 -20
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
- package/dist/audit/languageAnalysisEngine/index.js +0 -39
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -89
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -159
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
- package/dist/audit/nodeAnalysisEngine/index.js +0 -31
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
- package/dist/audit/phpAnalysisEngine/index.js +0 -23
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
- package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/pythonAnalysisEngine/index.js +0 -25
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
- package/dist/audit/rubyAnalysisEngine/index.js +0 -25
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
- package/src/audit/AnalysisEngine.js +0 -103
- package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
- package/src/audit/dotnetAnalysisEngine/index.js +0 -26
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
- package/src/audit/goAnalysisEngine/index.js +0 -18
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
- package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
- package/src/audit/javaAnalysisEngine/index.js +0 -41
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -225
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
- package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -36
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -42
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -33
- package/src/audit/languageAnalysisEngine/constants.js +0 -23
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
- package/src/audit/languageAnalysisEngine/index.js +0 -45
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -124
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -250
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
- package/src/audit/nodeAnalysisEngine/index.js +0 -35
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
- package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
- package/src/audit/phpAnalysisEngine/index.js +0 -27
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
- package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
- package/src/audit/pythonAnalysisEngine/index.js +0 -55
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
- package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
- package/src/audit/rubyAnalysisEngine/index.js +0 -30
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
- package/src/audit/rubyAnalysisEngine/sanitizer.js +0 -8
package/dist/utils/getConfig.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.setConfigValues = exports.
|
|
6
|
+
exports.setConfigValues = exports.localConfig = void 0;
|
|
7
7
|
const conf_1 = __importDefault(require("conf"));
|
|
8
8
|
const localConfig = (name, version) => {
|
|
9
9
|
const config = new conf_1.default({
|
|
@@ -19,11 +19,6 @@ const localConfig = (name, version) => {
|
|
|
19
19
|
return config;
|
|
20
20
|
};
|
|
21
21
|
exports.localConfig = localConfig;
|
|
22
|
-
const createConfigFromYaml = (yamlPath) => {
|
|
23
|
-
const yamlConfig = {};
|
|
24
|
-
return yamlConfig;
|
|
25
|
-
};
|
|
26
|
-
exports.createConfigFromYaml = createConfigFromYaml;
|
|
27
22
|
const setConfigValues = (config, values) => {
|
|
28
23
|
config.set('apiKey', values.apiKey);
|
|
29
24
|
config.set('organizationId', values.orgId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/contrast",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Contrast Security's command line tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"test": "jest --testPathIgnorePatterns=./test-integration/",
|
|
24
24
|
"test-int": "jest ./test-integration/",
|
|
25
25
|
"test-int-scan": "jest ./test-integration/scan",
|
|
26
|
-
"test-int-audit": "jest
|
|
26
|
+
"test-int-audit": "jest test-integration/audit/audit-int.spec.js",
|
|
27
27
|
"format": "prettier --write \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
28
28
|
"check-format": "prettier --check \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
29
29
|
"coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
|
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"fast-glob": "^3.2.11",
|
|
54
54
|
"i18n": "^0.14.2",
|
|
55
55
|
"js-yaml": "^4.1.0",
|
|
56
|
-
"latest-version": "5.1.0",
|
|
57
56
|
"lodash": "^4.17.21",
|
|
58
57
|
"log-symbols": "^4.1.0",
|
|
59
58
|
"open": "^8.4.0",
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
const i18n = require('i18n')
|
|
2
1
|
const { getHttpClient, handleResponseErrors } = require('../../utils/commonApi')
|
|
3
2
|
|
|
4
|
-
const displaySuccessMessage = () => {
|
|
5
|
-
console.log(i18n.__('catalogueSuccessCommand'))
|
|
6
|
-
}
|
|
7
|
-
|
|
8
3
|
const catalogueApplication = async config => {
|
|
9
4
|
const client = getHttpClient(config)
|
|
10
5
|
let appId
|
|
@@ -14,6 +9,8 @@ const catalogueApplication = async config => {
|
|
|
14
9
|
if (res.statusCode === 201) {
|
|
15
10
|
//displaySuccessMessage(config, res.body.application.app_id)
|
|
16
11
|
appId = res.body.application.app_id
|
|
12
|
+
} else if (doesMessagesContainAppId(res)) {
|
|
13
|
+
appId = tryRetrieveAppIdFromMessages(res.body.messages)
|
|
17
14
|
} else {
|
|
18
15
|
handleResponseErrors(res, 'catalogue')
|
|
19
16
|
}
|
|
@@ -24,6 +21,31 @@ const catalogueApplication = async config => {
|
|
|
24
21
|
return appId
|
|
25
22
|
}
|
|
26
23
|
|
|
24
|
+
const doesMessagesContainAppId = res => {
|
|
25
|
+
const regex = /(Application ID =)/
|
|
26
|
+
if (
|
|
27
|
+
res.statusCode === 400 &&
|
|
28
|
+
res.body.messages.filter(message => regex.exec(message))[0]
|
|
29
|
+
) {
|
|
30
|
+
return true
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const tryRetrieveAppIdFromMessages = messages => {
|
|
37
|
+
let appId
|
|
38
|
+
messages.forEach(message => {
|
|
39
|
+
if (message.includes('Application ID')) {
|
|
40
|
+
appId = message.split('=')[1].replace(/\s+/g, '')
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
return appId
|
|
45
|
+
}
|
|
46
|
+
|
|
27
47
|
module.exports = {
|
|
28
|
-
catalogueApplication: catalogueApplication
|
|
48
|
+
catalogueApplication: catalogueApplication,
|
|
49
|
+
doesMessagesContainAppId,
|
|
50
|
+
tryRetrieveAppIdFromMessages
|
|
29
51
|
}
|
|
@@ -1,72 +1,36 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const i18n = require('i18n')
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* @return {string[]} List of filenames associated with a projects root
|
|
16
|
-
* directory or the name of the specific project file if that was provided to
|
|
17
|
-
* the 'projectPath' parameter
|
|
18
|
-
*
|
|
19
|
-
* @throws {Error} If the project path doesn't exist
|
|
20
|
-
* @throws {Error} If the project path information can't be collected
|
|
21
|
-
* @throws {Error} If a non-file or non-directory inspected
|
|
22
|
-
*/
|
|
23
|
-
module.exports = exports = (analysis, next) => {
|
|
24
|
-
const { projectPath, languageAnalysis } = analysis
|
|
25
|
-
try {
|
|
26
|
-
languageAnalysis.projectRootFilenames = getProjectRootFilenames(projectPath)
|
|
27
|
-
} catch (err) {
|
|
28
|
-
next(err)
|
|
29
|
-
return
|
|
4
|
+
|
|
5
|
+
const getDirectoryFromPathGiven = file => {
|
|
6
|
+
let projectStats = getProjectStats(file)
|
|
7
|
+
|
|
8
|
+
if (projectStats.isFile()) {
|
|
9
|
+
let newPath = path.resolve(file)
|
|
10
|
+
return path.dirname(newPath)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (projectStats.isDirectory()) {
|
|
14
|
+
return file
|
|
30
15
|
}
|
|
31
|
-
next()
|
|
32
16
|
}
|
|
33
17
|
|
|
34
|
-
const
|
|
35
|
-
let projectStats = null
|
|
18
|
+
const getProjectStats = file => {
|
|
36
19
|
try {
|
|
37
|
-
|
|
20
|
+
//might not need this
|
|
21
|
+
if (file.endsWith('/')) {
|
|
22
|
+
file = file.slice(0, -1)
|
|
23
|
+
}
|
|
24
|
+
return fs.statSync(file)
|
|
38
25
|
} catch (err) {
|
|
39
26
|
throw new Error(
|
|
40
|
-
i18n.__('languageAnalysisProjectRootFileNameFailure',
|
|
27
|
+
i18n.__('languageAnalysisProjectRootFileNameFailure', file) +
|
|
41
28
|
`${err.message}`
|
|
42
29
|
)
|
|
43
30
|
}
|
|
44
|
-
|
|
45
|
-
// Return the contents of a directory...
|
|
46
|
-
if (projectStats.isDirectory()) {
|
|
47
|
-
try {
|
|
48
|
-
return fs.readdirSync(projectPath)
|
|
49
|
-
} catch (err) {
|
|
50
|
-
throw new Error(
|
|
51
|
-
i18n.__('languageAnalysisProjectRootFileNameReadError', projectPath) +
|
|
52
|
-
`${err.message}`
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// If we are working with a file return it in a list as we do when we work
|
|
58
|
-
// with a directory...
|
|
59
|
-
if (projectStats.isFile()) {
|
|
60
|
-
return [path.basename(projectPath)]
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Error out if we are working with something like a socket file or some
|
|
64
|
-
// other craziness...
|
|
65
|
-
throw new Error(
|
|
66
|
-
i18n.__('languageAnalysisProjectRootFileNameMissingError'),
|
|
67
|
-
projectPath
|
|
68
|
-
)
|
|
69
31
|
}
|
|
70
32
|
|
|
71
|
-
|
|
72
|
-
|
|
33
|
+
module.exports = {
|
|
34
|
+
getProjectStats,
|
|
35
|
+
getDirectoryFromPathGiven: getDirectoryFromPathGiven
|
|
36
|
+
}
|
|
@@ -9,6 +9,7 @@ import { orderBy } from 'lodash'
|
|
|
9
9
|
import chalk from 'chalk'
|
|
10
10
|
import { ReportCVEModel, ReportLibraryModel } from './models/reportLibraryModel'
|
|
11
11
|
import {
|
|
12
|
+
countVulnerableLibrariesBySeverity,
|
|
12
13
|
findCVESeveritiesAndOrderByHighestPriority,
|
|
13
14
|
findHighestSeverityCVE,
|
|
14
15
|
findNameAndVersion,
|
|
@@ -20,18 +21,23 @@ import {
|
|
|
20
21
|
ReportOutputHeaderModel,
|
|
21
22
|
ReportOutputModel
|
|
22
23
|
} from './models/reportOutputModel'
|
|
24
|
+
import {
|
|
25
|
+
CRITICAL_COLOUR,
|
|
26
|
+
HIGH_COLOUR,
|
|
27
|
+
LOW_COLOUR,
|
|
28
|
+
MEDIUM_COLOUR,
|
|
29
|
+
NOTE_COLOUR
|
|
30
|
+
} from '../../../constants/constants'
|
|
31
|
+
import Table from 'cli-table3'
|
|
23
32
|
|
|
24
|
-
export const
|
|
25
|
-
id: string,
|
|
33
|
+
export const createSummaryMessage = (
|
|
26
34
|
numberOfVulnerableLibraries: number,
|
|
27
35
|
numberOfCves: number
|
|
28
36
|
) => {
|
|
29
37
|
numberOfVulnerableLibraries === 1
|
|
30
|
-
? console.log(
|
|
31
|
-
` Found 1 vulnerable library containing ${numberOfCves} CVE's`
|
|
32
|
-
)
|
|
38
|
+
? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
|
|
33
39
|
: console.log(
|
|
34
|
-
`
|
|
40
|
+
`Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`
|
|
35
41
|
)
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -43,10 +49,6 @@ export const getReport = async (config: any, reportId: string) => {
|
|
|
43
49
|
if (res.statusCode === 200) {
|
|
44
50
|
return res.body
|
|
45
51
|
} else {
|
|
46
|
-
console.log('config-------------------')
|
|
47
|
-
console.log(config)
|
|
48
|
-
console.log('reportId----------------')
|
|
49
|
-
console.log(reportId)
|
|
50
52
|
console.log(JSON.stringify(res))
|
|
51
53
|
handleResponseErrors(res, 'report')
|
|
52
54
|
}
|
|
@@ -57,21 +59,35 @@ export const getReport = async (config: any, reportId: string) => {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
export const printVulnerabilityResponse = (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
config: any,
|
|
63
|
+
vulnerableLibraries: ReportLibraryModel[],
|
|
64
|
+
numberOfVulnerableLibraries: number,
|
|
65
|
+
numberOfCves: number,
|
|
66
|
+
guidance: any
|
|
62
67
|
) => {
|
|
63
68
|
let hasSomeVulnerabilitiesReported = false
|
|
64
|
-
printFormattedOutput(
|
|
65
|
-
|
|
69
|
+
printFormattedOutput(
|
|
70
|
+
config,
|
|
71
|
+
vulnerableLibraries,
|
|
72
|
+
numberOfVulnerableLibraries,
|
|
73
|
+
numberOfCves,
|
|
74
|
+
guidance
|
|
75
|
+
)
|
|
76
|
+
if (Object.keys(vulnerableLibraries).length > 0) {
|
|
66
77
|
hasSomeVulnerabilitiesReported = true
|
|
67
78
|
}
|
|
68
79
|
return hasSomeVulnerabilitiesReported
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
export const printFormattedOutput = (
|
|
83
|
+
config: any,
|
|
72
84
|
libraries: ReportLibraryModel[],
|
|
73
|
-
|
|
85
|
+
numberOfVulnerableLibraries: number,
|
|
86
|
+
numberOfCves: number,
|
|
87
|
+
guidance: any
|
|
74
88
|
) => {
|
|
89
|
+
createSummaryMessage(numberOfVulnerableLibraries, numberOfCves)
|
|
90
|
+
console.log()
|
|
75
91
|
const report = new ReportList()
|
|
76
92
|
|
|
77
93
|
for (const library of libraries) {
|
|
@@ -81,27 +97,61 @@ export const printFormattedOutput = (
|
|
|
81
97
|
new ReportCompositeKey(
|
|
82
98
|
name,
|
|
83
99
|
version,
|
|
84
|
-
findHighestSeverityCVE(library.cveArray) as ReportSeverityModel
|
|
100
|
+
findHighestSeverityCVE(library.cveArray) as ReportSeverityModel,
|
|
101
|
+
severityCountAllCVEs(
|
|
102
|
+
library.cveArray,
|
|
103
|
+
new SeverityCountModel()
|
|
104
|
+
).getTotal
|
|
85
105
|
),
|
|
86
106
|
library.cveArray
|
|
87
107
|
)
|
|
88
|
-
|
|
89
108
|
report.reportOutputList.push(newOutputModel)
|
|
90
109
|
}
|
|
91
110
|
|
|
92
|
-
const
|
|
111
|
+
const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
|
|
93
112
|
report.reportOutputList,
|
|
94
|
-
|
|
95
|
-
|
|
113
|
+
[
|
|
114
|
+
(reportListItem: ReportModelStructure) => {
|
|
115
|
+
return reportListItem.compositeKey.highestSeverity.priority
|
|
116
|
+
},
|
|
117
|
+
(reportListItem: ReportModelStructure) => {
|
|
118
|
+
return reportListItem.compositeKey.numberOfSeverities
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
['asc', 'desc']
|
|
96
122
|
)
|
|
97
123
|
|
|
98
124
|
let contrastHeaderNumCounter = 0
|
|
99
|
-
for (const reportModel of
|
|
125
|
+
for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
|
|
100
126
|
contrastHeaderNumCounter++
|
|
101
127
|
const { libraryName, libraryVersion, highestSeverity } =
|
|
102
128
|
reportModel.compositeKey
|
|
103
129
|
const numOfCVEs = reportModel.cveArray.length
|
|
104
130
|
|
|
131
|
+
const table = new Table({
|
|
132
|
+
chars: {
|
|
133
|
+
top: '',
|
|
134
|
+
'top-mid': '',
|
|
135
|
+
'top-left': '',
|
|
136
|
+
'top-right': '',
|
|
137
|
+
bottom: '',
|
|
138
|
+
'bottom-mid': '',
|
|
139
|
+
'bottom-left': '',
|
|
140
|
+
'bottom-right': '',
|
|
141
|
+
left: '',
|
|
142
|
+
'left-mid': '',
|
|
143
|
+
mid: '',
|
|
144
|
+
'mid-mid': '',
|
|
145
|
+
right: '',
|
|
146
|
+
'right-mid': '',
|
|
147
|
+
middle: ' '
|
|
148
|
+
},
|
|
149
|
+
style: { 'padding-left': 0, 'padding-right': 0 },
|
|
150
|
+
colAligns: ['right'],
|
|
151
|
+
wordWrap: true,
|
|
152
|
+
colWidths: [12, 1, 100]
|
|
153
|
+
})
|
|
154
|
+
|
|
105
155
|
const header = buildHeader(
|
|
106
156
|
highestSeverity,
|
|
107
157
|
contrastHeaderNumCounter,
|
|
@@ -110,16 +160,36 @@ export const printFormattedOutput = (
|
|
|
110
160
|
numOfCVEs
|
|
111
161
|
)
|
|
112
162
|
|
|
113
|
-
const
|
|
163
|
+
const advice = gatherRemediationAdvice(guidance, reportModel)
|
|
164
|
+
|
|
165
|
+
const body = buildBody(reportModel.cveArray, advice)
|
|
114
166
|
|
|
115
167
|
const reportOutputModel = new ReportOutputModel(header, body)
|
|
168
|
+
|
|
169
|
+
table.push(
|
|
170
|
+
reportOutputModel.body.issueMessage,
|
|
171
|
+
reportOutputModel.body.issueMessageCves,
|
|
172
|
+
reportOutputModel.body.adviceMessage
|
|
173
|
+
)
|
|
174
|
+
|
|
116
175
|
console.log(
|
|
117
176
|
reportOutputModel.header.vulnMessage,
|
|
118
177
|
reportOutputModel.header.introducesMessage
|
|
119
178
|
)
|
|
120
|
-
console.log(
|
|
121
|
-
console.log(reportOutputModel.body.adviceMessage)
|
|
179
|
+
console.log(table.toString() + '\n')
|
|
122
180
|
}
|
|
181
|
+
|
|
182
|
+
createSummaryMessage(numberOfVulnerableLibraries, numberOfCves)
|
|
183
|
+
const {
|
|
184
|
+
criticalMessage,
|
|
185
|
+
highMessage,
|
|
186
|
+
mediumMessage,
|
|
187
|
+
lowMessage,
|
|
188
|
+
noteMessage
|
|
189
|
+
} = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst)
|
|
190
|
+
console.log(
|
|
191
|
+
`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
|
|
192
|
+
)
|
|
123
193
|
}
|
|
124
194
|
|
|
125
195
|
export function buildHeader(
|
|
@@ -130,7 +200,7 @@ export function buildHeader(
|
|
|
130
200
|
numOfCVEs: number
|
|
131
201
|
) {
|
|
132
202
|
const vulnerabilityPluralised =
|
|
133
|
-
numOfCVEs > 1 ? '
|
|
203
|
+
numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
|
|
134
204
|
const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
|
|
135
205
|
|
|
136
206
|
const vulnMessage = chalk
|
|
@@ -139,14 +209,12 @@ export function buildHeader(
|
|
|
139
209
|
`${formattedHeaderNum} - [${highestSeverity.severity}] ${libraryName}-${version}`
|
|
140
210
|
)
|
|
141
211
|
|
|
142
|
-
const introducesMessage =
|
|
143
|
-
`introduces ${numOfCVEs} ${vulnerabilityPluralised}`
|
|
144
|
-
)
|
|
212
|
+
const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
|
|
145
213
|
|
|
146
214
|
return new ReportOutputHeaderModel(vulnMessage, introducesMessage)
|
|
147
215
|
}
|
|
148
216
|
|
|
149
|
-
export function buildBody(cveArray: ReportCVEModel[]) {
|
|
217
|
+
export function buildBody(cveArray: ReportCVEModel[], advice: any) {
|
|
150
218
|
const cveMessages: string[] = []
|
|
151
219
|
|
|
152
220
|
findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(
|
|
@@ -158,36 +226,57 @@ export function buildBody(cveArray: ReportCVEModel[]) {
|
|
|
158
226
|
.hex(outputColour)
|
|
159
227
|
.bold(`[${severity.charAt(0).toUpperCase()}]`)
|
|
160
228
|
|
|
161
|
-
const builtMessage =
|
|
229
|
+
const builtMessage = severityShorthand + cveName
|
|
162
230
|
cveMessages.push(builtMessage)
|
|
163
231
|
}
|
|
164
232
|
)
|
|
165
233
|
|
|
166
234
|
const numAndSeverityType = getNumOfAndSeverityType(cveArray)
|
|
167
235
|
|
|
168
|
-
const issueMessage =
|
|
169
|
-
'Issue'
|
|
170
|
-
)} : ${numAndSeverityType} ${cveMessages.join(', ')}.`
|
|
236
|
+
const issueMessage = [chalk.bold('Issue'), ':', `${numAndSeverityType}`]
|
|
171
237
|
|
|
172
|
-
const
|
|
173
|
-
'Update to latest version'
|
|
174
|
-
)}.`
|
|
238
|
+
const issueMessageCves = ['', '', cveMessages.join(', ')]
|
|
175
239
|
|
|
176
|
-
|
|
240
|
+
//todo different advice based on remediationGuidance being available or now
|
|
241
|
+
// console.log(advice)
|
|
242
|
+
|
|
243
|
+
const displayAdvice = advice?.minimum
|
|
244
|
+
? `Update to version ${chalk.bold(advice.minimum)}`
|
|
245
|
+
: `Update to latest version`
|
|
246
|
+
|
|
247
|
+
const adviceMessage = [chalk.bold('Advice'), ':', displayAdvice]
|
|
248
|
+
|
|
249
|
+
return new ReportOutputBodyModel(
|
|
250
|
+
issueMessage,
|
|
251
|
+
issueMessageCves,
|
|
252
|
+
adviceMessage
|
|
253
|
+
)
|
|
177
254
|
}
|
|
178
255
|
|
|
179
|
-
export function
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
256
|
+
export function gatherRemediationAdvice(guidance: any, reportModel: any) {
|
|
257
|
+
const guidanceData = {
|
|
258
|
+
minimum: undefined,
|
|
259
|
+
maximum: undefined,
|
|
260
|
+
latest: undefined
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const data =
|
|
264
|
+
guidance[
|
|
265
|
+
reportModel.compositeKey.libraryName +
|
|
266
|
+
'@' +
|
|
267
|
+
reportModel.compositeKey.libraryVersion
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
if (data) {
|
|
271
|
+
guidanceData.minimum = data.minUpgradeVersion
|
|
272
|
+
guidanceData.maximum = data.maxUpgradeVersion
|
|
188
273
|
}
|
|
189
274
|
|
|
190
|
-
return
|
|
275
|
+
return guidanceData
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function buildFormattedHeaderNum(contrastHeaderNum: number) {
|
|
279
|
+
return `CONTRAST-${contrastHeaderNum.toString().padStart(3, '0')}`
|
|
191
280
|
}
|
|
192
281
|
|
|
193
282
|
export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
|
|
@@ -207,3 +296,24 @@ export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
|
|
|
207
296
|
.replace(/\s+/g, ' ')
|
|
208
297
|
.trim()
|
|
209
298
|
}
|
|
299
|
+
|
|
300
|
+
const buildFooter = (reportModelStructure: ReportModelStructure[]) => {
|
|
301
|
+
const { critical, high, medium, low, note } =
|
|
302
|
+
countVulnerableLibrariesBySeverity(reportModelStructure)
|
|
303
|
+
|
|
304
|
+
const criticalMessage = chalk
|
|
305
|
+
.hex(CRITICAL_COLOUR)
|
|
306
|
+
.bold(`${critical} Critical`)
|
|
307
|
+
const highMessage = chalk.hex(HIGH_COLOUR).bold(`${high} High`)
|
|
308
|
+
const mediumMessage = chalk.hex(MEDIUM_COLOUR).bold(`${medium} Medium`)
|
|
309
|
+
const lowMessage = chalk.hex(LOW_COLOUR).bold(`${low} Low`)
|
|
310
|
+
const noteMessage = chalk.hex(NOTE_COLOUR).bold(`${note} Note`)
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
criticalMessage,
|
|
314
|
+
highMessage,
|
|
315
|
+
mediumMessage,
|
|
316
|
+
lowMessage,
|
|
317
|
+
noteMessage
|
|
318
|
+
}
|
|
319
|
+
}
|
|
@@ -23,14 +23,17 @@ export class ReportCompositeKey {
|
|
|
23
23
|
libraryName!: string
|
|
24
24
|
libraryVersion!: string
|
|
25
25
|
highestSeverity!: ReportSeverityModel
|
|
26
|
+
numberOfSeverities!: number
|
|
26
27
|
|
|
27
28
|
constructor(
|
|
28
29
|
libraryName: string,
|
|
29
30
|
libraryVersion: string,
|
|
30
|
-
highestSeverity: ReportSeverityModel
|
|
31
|
+
highestSeverity: ReportSeverityModel,
|
|
32
|
+
numberOfSeverities: number
|
|
31
33
|
) {
|
|
32
34
|
this.libraryName = libraryName
|
|
33
35
|
this.libraryVersion = libraryVersion
|
|
34
36
|
this.highestSeverity = highestSeverity
|
|
37
|
+
this.numberOfSeverities = numberOfSeverities
|
|
35
38
|
}
|
|
36
39
|
}
|
|
@@ -19,11 +19,17 @@ export class ReportOutputHeaderModel {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export class ReportOutputBodyModel {
|
|
22
|
-
issueMessage: string
|
|
23
|
-
|
|
22
|
+
issueMessage: string[]
|
|
23
|
+
issueMessageCves: string[]
|
|
24
|
+
adviceMessage: string[]
|
|
24
25
|
|
|
25
|
-
constructor(
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
constructor(
|
|
27
|
+
issueMessage: string[],
|
|
28
|
+
issueMessageCves: string[],
|
|
29
|
+
adviceMessage: string[]
|
|
30
|
+
) {
|
|
31
|
+
this.issueMessage = issueMessage
|
|
32
|
+
this.issueMessageCves = issueMessageCves
|
|
33
|
+
this.adviceMessage = adviceMessage
|
|
28
34
|
}
|
|
29
35
|
}
|