@contrast/contrast 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/report/commonReportingFunctions.js +175 -116
- package/dist/audit/report/models/reportSeverityModel.js +3 -3
- package/dist/audit/report/reportingFeature.js +1 -10
- package/dist/audit/report/utils/reportUtils.js +4 -4
- package/dist/audit/save.js +7 -2
- package/dist/commands/audit/help.js +3 -1
- package/dist/commands/scan/processScan.js +0 -6
- package/dist/commands/scan/sca/scaAnalysis.js +32 -15
- package/dist/common/HTTPClient.js +22 -3
- package/dist/common/errorHandling.js +1 -2
- package/dist/constants/constants.js +10 -2
- package/dist/constants/locales.js +17 -7
- package/dist/constants.js +31 -2
- package/dist/index.js +4 -2
- package/dist/lambda/lambda.js +1 -1
- package/dist/sbom/generateSbom.js +18 -1
- package/dist/scaAnalysis/common/auditReport.js +78 -0
- package/dist/scaAnalysis/common/scaServicesUpload.js +21 -13
- package/dist/scan/formatScanOutput.js +4 -29
- package/dist/utils/commonApi.js +1 -0
- package/dist/utils/settingsHelper.js +24 -0
- package/package.json +4 -1
- package/src/audit/report/commonReportingFunctions.js +432 -0
- package/src/audit/report/models/reportSeverityModel.ts +6 -6
- package/src/audit/report/reportingFeature.ts +2 -16
- package/src/audit/report/utils/reportUtils.ts +2 -8
- package/src/audit/save.js +14 -6
- package/src/commands/audit/help.ts +3 -1
- package/src/commands/scan/processScan.js +0 -8
- package/src/commands/scan/sca/scaAnalysis.js +52 -32
- package/src/common/HTTPClient.js +26 -3
- package/src/common/errorHandling.ts +1 -2
- package/src/constants/constants.js +12 -2
- package/src/constants/locales.js +19 -7
- package/src/constants.js +34 -2
- package/src/index.ts +4 -6
- package/src/lambda/lambda.ts +1 -1
- package/src/lambda/lambdaUtils.ts +1 -1
- package/src/sbom/generateSbom.ts +20 -0
- package/src/scaAnalysis/common/auditReport.js +108 -0
- package/src/scaAnalysis/common/scaServicesUpload.js +24 -14
- package/src/scan/formatScanOutput.ts +5 -42
- package/src/utils/commonApi.js +1 -0
- package/src/utils/settingsHelper.js +26 -0
- package/src/audit/report/commonReportingFunctions.ts +0 -355
|
@@ -12,7 +12,7 @@ const MEDIUM = 'MEDIUM';
|
|
|
12
12
|
const HIGH = 'HIGH';
|
|
13
13
|
const CRITICAL = 'CRITICAL';
|
|
14
14
|
const APP_NAME = 'contrast';
|
|
15
|
-
const APP_VERSION = '1.0.
|
|
15
|
+
const APP_VERSION = '1.0.15';
|
|
16
16
|
const TIMEOUT = 120000;
|
|
17
17
|
const HIGH_COLOUR = '#ff9900';
|
|
18
18
|
const CRITICAL_COLOUR = '#e35858';
|
|
@@ -30,6 +30,10 @@ const SARIF_FILE = 'SARIF';
|
|
|
30
30
|
const SBOM_CYCLONE_DX_FILE = 'cyclonedx';
|
|
31
31
|
const SBOM_SPDX_FILE = 'spdx';
|
|
32
32
|
const CE_URL = 'https://ce.contrastsecurity.com';
|
|
33
|
+
const SAAS = 'SAAS';
|
|
34
|
+
const EOP = 'EOP';
|
|
35
|
+
const MODE_BUILD = 'BUILD';
|
|
36
|
+
const MODE_REPO = 'REPO';
|
|
33
37
|
module.exports = {
|
|
34
38
|
supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
|
|
35
39
|
supportedLanguagesScan: { JAVASCRIPT, DOTNET, JAVA },
|
|
@@ -55,5 +59,9 @@ module.exports = {
|
|
|
55
59
|
LOW_PRIORITY,
|
|
56
60
|
NOTE_PRIORITY,
|
|
57
61
|
SBOM_CYCLONE_DX_FILE,
|
|
58
|
-
SBOM_SPDX_FILE
|
|
62
|
+
SBOM_SPDX_FILE,
|
|
63
|
+
SAAS,
|
|
64
|
+
EOP,
|
|
65
|
+
MODE_BUILD,
|
|
66
|
+
MODE_REPO
|
|
59
67
|
};
|
|
@@ -80,6 +80,7 @@ const en_locales = () => {
|
|
|
80
80
|
constantsApplicationName: 'The name of the application cataloged by Contrast UI',
|
|
81
81
|
constantsCatalogueApplication: 'Provide this if you want to catalogue an application',
|
|
82
82
|
failOptionErrorMessage: ' FAIL - CVEs have been detected that match at least the cve_severity option specified.',
|
|
83
|
+
failOptionMessage: ' Use with contrast scan or contrast audit. Detects failures based on the severity level specified with the --severity command. For example, "contrast scan --fail --severity high". Returns all failures if no severity level is specified.',
|
|
83
84
|
constantsLanguage: 'Valid values are JAVA, DOTNET, NODE, PYTHON and RUBY. If there are multiple project configuration files in the project_path, language is also required. Also, provide this when cataloguing an application',
|
|
84
85
|
constantsFilePath: `Specify a directory or the file where dependencies are declared. (By default, CodeSec will search for project files in the current directory.)`,
|
|
85
86
|
constantsSilent: 'Silences JSON output.',
|
|
@@ -96,7 +97,7 @@ const en_locales = () => {
|
|
|
96
97
|
constantsFail: 'Set the process to fail if this option is set in combination with --cve_severity.',
|
|
97
98
|
failThresholdOptionErrorMessage: 'More than 0 vulnerabilities found',
|
|
98
99
|
failSeverityOptionErrorMessage: ' FAIL - Results detected vulnerabilities over accepted severity level',
|
|
99
|
-
constantsSeverity: '
|
|
100
|
+
constantsSeverity: 'Use with "contrast scan --fail --severity high" or "contrast audit --fail --severity high". Set the severity level to detect vulnerabilities or dependencies. Severity levels are critical, high, medium, low or note.',
|
|
100
101
|
constantsCount: 'The number of CVEs that must be exceeded to fail a build',
|
|
101
102
|
constantsHeader: 'CodeSec by Contrast Security',
|
|
102
103
|
configHeader2: 'Config options',
|
|
@@ -113,7 +114,7 @@ const en_locales = () => {
|
|
|
113
114
|
configHeader: 'Config',
|
|
114
115
|
constantsConfigUsageContents: 'view / clear the configuration',
|
|
115
116
|
constantsPrerequisitesContent: 'To scan a Java project you will need a .jar or .war file for analysis\n' +
|
|
116
|
-
'To scan a Javascript project you will need a .js or.zip
|
|
117
|
+
'To scan a Javascript project you will need a single .js or a .zip of multiple .js files\n' +
|
|
117
118
|
'To scan a .NET c# webforms project you will need a .exe or a .zip file for analysis\n',
|
|
118
119
|
constantsUsage: 'Usage',
|
|
119
120
|
constantsUsageCommandExample: 'contrast [command] [options]',
|
|
@@ -212,17 +213,26 @@ const en_locales = () => {
|
|
|
212
213
|
scanOptionsTimeoutSummary: 'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
|
|
213
214
|
scanOptionsFileNameSummary: 'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
|
|
214
215
|
scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
|
|
216
|
+
auditOptionsTrackSummary: ' Save the results to the UI.',
|
|
217
|
+
auditOptionsBranchSummary: ' Set the branch name to associate the library results to.',
|
|
215
218
|
authSuccessMessage: 'Authentication successful',
|
|
216
|
-
runAuthSuccessMessage:
|
|
219
|
+
runAuthSuccessMessage: chalk.bold('CodeSec by Contrast') +
|
|
220
|
+
'\nScan, secure and ship your code in minutes for FREE. \n' +
|
|
221
|
+
chalk.bold('\nRun\n') +
|
|
222
|
+
chalk.bold('\ncontrast scan') +
|
|
223
|
+
" to run Contrast's industry leading SAST scanner. \nSupports Java, JavaScript and .Net \n" +
|
|
224
|
+
chalk.bold('\ncontrast audit') +
|
|
225
|
+
' to find vulnerabilities in your open source dependencies.\nSupports Java, .NET, Node, Ruby, Python, Go and PHP \n' +
|
|
226
|
+
chalk.bold('\ncontrast lambda') +
|
|
227
|
+
' to secure your AWS serverless functions. \nSupports Java and Python \n' +
|
|
228
|
+
chalk.bold('\ncontrast help') +
|
|
229
|
+
' to learn more about the capabilities.',
|
|
217
230
|
authWaitingMessage: 'Waiting for auth...',
|
|
218
231
|
authTimedOutMessage: 'Auth Timed out, try again',
|
|
219
232
|
zipErrorScan: 'We only support zip files for JAVASCRIPT language, please set the flag --language JAVASCRIPT',
|
|
220
233
|
unknownFileErrorScan: 'Unsupported file selected for Scan.',
|
|
221
234
|
foundScanFile: 'Found: %s',
|
|
222
|
-
foundDetailedVulnerabilities: chalk.bold('%s
|
|
223
|
-
' | ' +
|
|
224
|
-
chalk.bold('%s High') +
|
|
225
|
-
' | %s Medium | %s Low | %s Note',
|
|
235
|
+
foundDetailedVulnerabilities: chalk.bold('%s') + ' | ' + chalk.bold('%s') + ' | %s | %s | %s ',
|
|
226
236
|
requiredParams: 'All required parameters are not present.',
|
|
227
237
|
timeoutScan: 'Timeout set to 5 minutes.',
|
|
228
238
|
searchingScanFileDirectory: 'Searching for file to scan from %s...',
|
package/dist/constants.js
CHANGED
|
@@ -101,7 +101,7 @@ const scanOptionDefinitions = [
|
|
|
101
101
|
description: '{bold ' +
|
|
102
102
|
i18n.__('constantsOptional') +
|
|
103
103
|
'}: ' +
|
|
104
|
-
i18n.__('
|
|
104
|
+
i18n.__('failOptionMessage')
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
name: 'severity',
|
|
@@ -219,7 +219,7 @@ const auditOptionDefinitions = [
|
|
|
219
219
|
description: '{bold ' +
|
|
220
220
|
i18n.__('constantsOptional') +
|
|
221
221
|
'}: ' +
|
|
222
|
-
i18n.__('
|
|
222
|
+
i18n.__('failOptionMessage')
|
|
223
223
|
},
|
|
224
224
|
{
|
|
225
225
|
name: 'severity',
|
|
@@ -341,6 +341,35 @@ const auditOptionDefinitions = [
|
|
|
341
341
|
name: 'help',
|
|
342
342
|
alias: 'h',
|
|
343
343
|
type: Boolean
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
name: 'debug',
|
|
347
|
+
alias: 'd',
|
|
348
|
+
type: Boolean
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: 'verbose',
|
|
352
|
+
alias: 'v',
|
|
353
|
+
type: Boolean,
|
|
354
|
+
description: '{bold ' +
|
|
355
|
+
i18n.__('constantsOptional') +
|
|
356
|
+
'}:' +
|
|
357
|
+
i18n.__('scanOptionsVerboseSummary')
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
name: 'track',
|
|
361
|
+
type: Boolean,
|
|
362
|
+
description: '{bold ' +
|
|
363
|
+
i18n.__('constantsOptional') +
|
|
364
|
+
'}:' +
|
|
365
|
+
i18n.__('auditOptionsTrackSummary')
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'branch',
|
|
369
|
+
description: '{bold ' +
|
|
370
|
+
i18n.__('constantsOptional') +
|
|
371
|
+
'}:' +
|
|
372
|
+
i18n.__('auditOptionsBranchSummary')
|
|
344
373
|
}
|
|
345
374
|
];
|
|
346
375
|
const mainUsageGuide = commandLineUsage([
|
package/dist/index.js
CHANGED
|
@@ -73,11 +73,13 @@ const start = async () => {
|
|
|
73
73
|
const foundCommand = (0, errorHandling_1.findCommandOnError)(mainOptions._unknown);
|
|
74
74
|
foundCommand
|
|
75
75
|
? console.log(`Unknown Command: Did you mean "${foundCommand}"? \nUse "${foundCommand} --help" for the full list of options`)
|
|
76
|
-
: console.log(
|
|
76
|
+
: console.log(`\nUnknown Command: ${command} \n`);
|
|
77
|
+
console.log(mainUsageGuide);
|
|
77
78
|
await (0, telemetry_1.sendTelemetryConfigAsConfObj)(config, command, argvMain, 'FAILURE', 'undefined');
|
|
78
79
|
}
|
|
79
80
|
else {
|
|
80
|
-
console.log(
|
|
81
|
+
console.log(`\nUnknown Command: ${command}\n`);
|
|
82
|
+
console.log(mainUsageGuide);
|
|
81
83
|
await (0, telemetry_1.sendTelemetryConfigAsConfObj)(config, command, argvMain, 'FAILURE', 'undefined');
|
|
82
84
|
}
|
|
83
85
|
process.exit(9);
|
package/dist/lambda/lambda.js
CHANGED
|
@@ -119,7 +119,7 @@ const processLambda = async (argv) => {
|
|
|
119
119
|
exports.processLambda = processLambda;
|
|
120
120
|
const getAvailableFunctions = async (lambdaOptions) => {
|
|
121
121
|
const lambdas = await (0, lambdaUtils_1.getAllLambdas)(lambdaOptions);
|
|
122
|
-
(0, lambdaUtils_1.printAvailableLambdas)(lambdas, { runtimes: ['python', 'java'] });
|
|
122
|
+
(0, lambdaUtils_1.printAvailableLambdas)(lambdas, { runtimes: ['python', 'java', 'node'] });
|
|
123
123
|
};
|
|
124
124
|
exports.getAvailableFunctions = getAvailableFunctions;
|
|
125
125
|
const actualProcessLambda = async (lambdaOptions) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateSbom = void 0;
|
|
3
|
+
exports.generateSCASbom = exports.generateSbom = void 0;
|
|
4
4
|
const commonApi_1 = require("../utils/commonApi");
|
|
5
5
|
const generateSbom = (config, type) => {
|
|
6
6
|
const client = (0, commonApi_1.getHttpClient)(config);
|
|
@@ -19,3 +19,20 @@ const generateSbom = (config, type) => {
|
|
|
19
19
|
});
|
|
20
20
|
};
|
|
21
21
|
exports.generateSbom = generateSbom;
|
|
22
|
+
const generateSCASbom = (config, type, reportId) => {
|
|
23
|
+
const client = (0, commonApi_1.getHttpClient)(config);
|
|
24
|
+
return client
|
|
25
|
+
.getSCASbom(config, type, reportId)
|
|
26
|
+
.then((res) => {
|
|
27
|
+
if (res.statusCode === 200) {
|
|
28
|
+
return res.body;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log('Unable to retrieve Software Bill of Materials (SBOM)');
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.catch((err) => {
|
|
35
|
+
console.log(err);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
exports.generateSCASbom = generateSCASbom;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { getSeverityCounts, createSummaryMessageTop, printVulnInfo, getReportTable, getIssueRow, printNoVulnFoundMsg } = require('../../audit/report/commonReportingFunctions');
|
|
3
|
+
const { orderBy } = require('lodash');
|
|
4
|
+
const { assignBySeverity } = require('../../scan/formatScanOutput');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const { CE_URL } = require('../../constants/constants');
|
|
7
|
+
const common = require('../../common/fail');
|
|
8
|
+
const processAuditReport = (config, results) => {
|
|
9
|
+
let severityCounts = {};
|
|
10
|
+
if (results !== undefined) {
|
|
11
|
+
severityCounts = formatScaServicesReport(config, results);
|
|
12
|
+
}
|
|
13
|
+
if (config.fail) {
|
|
14
|
+
common.processFail(config, severityCounts);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const formatScaServicesReport = (config, results) => {
|
|
18
|
+
const projectOverviewCount = getSeverityCounts(results);
|
|
19
|
+
if (projectOverviewCount.total === 0) {
|
|
20
|
+
printNoVulnFoundMsg();
|
|
21
|
+
return projectOverviewCount;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
let total = 0;
|
|
25
|
+
const numberOfCves = results.length;
|
|
26
|
+
const table = getReportTable();
|
|
27
|
+
let contrastHeaderNumCounter = 0;
|
|
28
|
+
let assignPriorityToResults = results.map(result => assignBySeverity(result, result));
|
|
29
|
+
const numberOfVulns = results
|
|
30
|
+
.map(result => result.vulnerabilities)
|
|
31
|
+
.reduce((a, b) => {
|
|
32
|
+
return (total += b.length);
|
|
33
|
+
}, 0);
|
|
34
|
+
const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(assignPriorityToResults, [
|
|
35
|
+
reportListItem => {
|
|
36
|
+
return reportListItem.priority;
|
|
37
|
+
},
|
|
38
|
+
reportListItem => {
|
|
39
|
+
return reportListItem.vulnerabilities.length;
|
|
40
|
+
}
|
|
41
|
+
], ['asc', 'desc']);
|
|
42
|
+
for (const result of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
|
|
43
|
+
contrastHeaderNumCounter++;
|
|
44
|
+
const cvesNum = result.vulnerabilities.length;
|
|
45
|
+
const grammaticallyCorrectVul = result.vulnerabilities.length > 1 ? 'vulnerabilities' : 'vulnerability';
|
|
46
|
+
const headerColour = chalk.hex(result.colour);
|
|
47
|
+
const headerRow = [
|
|
48
|
+
headerColour(`CONTRAST-${contrastHeaderNumCounter.toString().padStart(3, '0')}`),
|
|
49
|
+
headerColour(`-`),
|
|
50
|
+
headerColour(`[${result.severity}] `) +
|
|
51
|
+
headerColour.bold(`${result.artifactName}`) +
|
|
52
|
+
` introduces ${cvesNum} ${grammaticallyCorrectVul}`
|
|
53
|
+
];
|
|
54
|
+
const adviceRow = [
|
|
55
|
+
chalk.bold(`Advice`),
|
|
56
|
+
chalk.bold(`:`),
|
|
57
|
+
`Change to version ${result.remediationAdvice.latestStableVersion}`
|
|
58
|
+
];
|
|
59
|
+
let assignPriorityToVulns = result.vulnerabilities.map(result => assignBySeverity(result, result));
|
|
60
|
+
const issueRow = getIssueRow(assignPriorityToVulns);
|
|
61
|
+
table.push(headerRow, issueRow, adviceRow);
|
|
62
|
+
console.log();
|
|
63
|
+
}
|
|
64
|
+
console.log();
|
|
65
|
+
createSummaryMessageTop(numberOfCves, numberOfVulns);
|
|
66
|
+
console.log(table.toString() + '\n');
|
|
67
|
+
printVulnInfo(projectOverviewCount);
|
|
68
|
+
if (config.host !== CE_URL) {
|
|
69
|
+
console.log('\n' + chalk.bold('View your full dependency tree in Contrast:'));
|
|
70
|
+
console.log(`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
|
|
71
|
+
}
|
|
72
|
+
return projectOverviewCount;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
module.exports = {
|
|
76
|
+
formatScaServicesReport,
|
|
77
|
+
processAuditReport
|
|
78
|
+
};
|
|
@@ -7,12 +7,15 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
7
7
|
applicationId: config.applicationId,
|
|
8
8
|
dependencyTree: analysis,
|
|
9
9
|
organizationId: config.organizationId,
|
|
10
|
-
language:
|
|
10
|
+
language: config.language,
|
|
11
11
|
tool: {
|
|
12
12
|
name: 'Contrast Codesec',
|
|
13
13
|
version: APP_VERSION
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
|
+
if (config.branch) {
|
|
17
|
+
requestBody.branchName = config.branch;
|
|
18
|
+
}
|
|
16
19
|
const client = commonApi.getHttpClient(config);
|
|
17
20
|
const reportID = await client
|
|
18
21
|
.scaServiceIngest(requestBody, config)
|
|
@@ -27,25 +30,30 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
27
30
|
.catch(err => {
|
|
28
31
|
throw err;
|
|
29
32
|
});
|
|
33
|
+
if (config.debug) {
|
|
34
|
+
console.log(' polling report', reportID);
|
|
35
|
+
}
|
|
30
36
|
let keepChecking = true;
|
|
37
|
+
let res;
|
|
31
38
|
while (keepChecking) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (res.body.status == 'COMPLETED') {
|
|
37
|
-
client.scaServiceReport(config, reportID).then(res => {
|
|
38
|
-
console.log(res.statusCode);
|
|
39
|
-
console.log(res.body);
|
|
40
|
-
});
|
|
41
|
-
return (keepChecking = false);
|
|
39
|
+
res = await client.scaServiceReportStatus(config, reportID).then(res => {
|
|
40
|
+
if (config.debug) {
|
|
41
|
+
console.log(res.statusCode);
|
|
42
|
+
console.log(res.body);
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
if (res.body.status === 'COMPLETED') {
|
|
45
|
+
keepChecking = false;
|
|
46
|
+
return client.scaServiceReport(config, reportID).then(res => {
|
|
47
|
+
return [res.body, reportID];
|
|
48
|
+
});
|
|
45
49
|
}
|
|
46
50
|
});
|
|
51
|
+
if (!keepChecking) {
|
|
52
|
+
return [res, reportID];
|
|
53
|
+
}
|
|
47
54
|
await requestUtils.sleep(5000);
|
|
48
55
|
}
|
|
56
|
+
return [res, reportID];
|
|
49
57
|
};
|
|
50
58
|
module.exports = {
|
|
51
59
|
scaTreeUpload
|
|
@@ -3,16 +3,17 @@ 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.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.getDefaultView = exports.formatLinks = exports.
|
|
6
|
+
exports.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
|
|
7
7
|
const i18n_1 = __importDefault(require("i18n"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const groupedResultsModel_1 = require("./models/groupedResultsModel");
|
|
10
10
|
const lodash_1 = require("lodash");
|
|
11
11
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
12
12
|
const constants_1 = require("../constants/constants");
|
|
13
|
+
const commonReportingFunctions_1 = require("../audit/report/commonReportingFunctions");
|
|
13
14
|
function formatScanOutput(scanResults) {
|
|
14
15
|
const { scanResultsInstances } = scanResults;
|
|
15
|
-
const projectOverview =
|
|
16
|
+
const projectOverview = (0, commonReportingFunctions_1.getSeverityCounts)(scanResultsInstances.content);
|
|
16
17
|
if (scanResultsInstances.content.length === 0) {
|
|
17
18
|
console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
|
|
18
19
|
console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
|
|
@@ -89,36 +90,10 @@ function formatScanOutput(scanResults) {
|
|
|
89
90
|
console.log();
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
|
-
printVulnInfo(projectOverview);
|
|
93
|
+
(0, commonReportingFunctions_1.printVulnInfo)(projectOverview);
|
|
93
94
|
return projectOverview;
|
|
94
95
|
}
|
|
95
96
|
exports.formatScanOutput = formatScanOutput;
|
|
96
|
-
function printVulnInfo(projectOverview) {
|
|
97
|
-
const totalVulnerabilities = projectOverview.total;
|
|
98
|
-
const vulMessage = totalVulnerabilities === 1 ? `vulnerability` : `vulnerabilities`;
|
|
99
|
-
console.log(chalk_1.default.bold(`Found ${totalVulnerabilities} ${vulMessage}`));
|
|
100
|
-
console.log(i18n_1.default.__('foundDetailedVulnerabilities', String(projectOverview.critical), String(projectOverview.high), String(projectOverview.medium), String(projectOverview.low), String(projectOverview.note)));
|
|
101
|
-
}
|
|
102
|
-
function getProjectOverview(scanResultsInstances) {
|
|
103
|
-
const acc = {
|
|
104
|
-
critical: 0,
|
|
105
|
-
high: 0,
|
|
106
|
-
medium: 0,
|
|
107
|
-
low: 0,
|
|
108
|
-
note: 0,
|
|
109
|
-
total: 0
|
|
110
|
-
};
|
|
111
|
-
if (scanResultsInstances?.content &&
|
|
112
|
-
scanResultsInstances.content.length > 0) {
|
|
113
|
-
scanResultsInstances.content.forEach((i) => {
|
|
114
|
-
acc[i.severity.toLowerCase()] += 1;
|
|
115
|
-
acc.total += 1;
|
|
116
|
-
return acc;
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
return acc;
|
|
120
|
-
}
|
|
121
|
-
exports.getProjectOverview = getProjectOverview;
|
|
122
97
|
function formatLinks(objName, entry) {
|
|
123
98
|
const line = chalk_1.default.bold(objName + ' : ');
|
|
124
99
|
if (entry.length === 1) {
|
package/dist/utils/commonApi.js
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const commonApi = require('./commonApi');
|
|
3
|
+
const { getMode } = require('./generalAPI');
|
|
4
|
+
const { SAAS, MODE_BUILD } = require('../constants/constants');
|
|
5
|
+
const getSettings = async (config) => {
|
|
6
|
+
config.isEOP = (await getMode(config)).toUpperCase() === SAAS ? false : true;
|
|
7
|
+
config.mode = MODE_BUILD;
|
|
8
|
+
config.scaServices = await isSCAServicesAvailable(config);
|
|
9
|
+
return config;
|
|
10
|
+
};
|
|
11
|
+
const isSCAServicesAvailable = async (config) => {
|
|
12
|
+
const client = commonApi.getHttpClient(config);
|
|
13
|
+
return client
|
|
14
|
+
.scaServiceIngests(config)
|
|
15
|
+
.then(res => {
|
|
16
|
+
return res.statusCode !== 403;
|
|
17
|
+
})
|
|
18
|
+
.catch(err => {
|
|
19
|
+
console.log(err);
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
module.exports = {
|
|
23
|
+
getSettings
|
|
24
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/contrast",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Contrast Security's command line tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,10 @@
|
|
|
25
25
|
"test-int-scan": "jest ./test-integration/scan",
|
|
26
26
|
"test-int-audit": "jest test-integration/audit",
|
|
27
27
|
"test-int-audit-reports": "jest test-integration/audit/audit-language-reports.spec.js",
|
|
28
|
+
"test-int-scan-errors": "jest test-integration/scan/scanLocalErrors.spec.js",
|
|
29
|
+
"test-int-scan-reports": "jest test-integration/scan/scanReport.spec.js",
|
|
28
30
|
"test-int-audit-features": "jest test-integration/audit/auditFeatures/",
|
|
31
|
+
"test-int-audit-experimental": "jest test-integration/audit/audit-experimental.spec.js",
|
|
29
32
|
"format": "prettier --write \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
30
33
|
"check-format": "prettier --check \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
31
34
|
"coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
|