@contrast/contrast 1.0.22 → 1.0.23
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 +1 -1
- package/dist/audit/save.js +10 -4
- package/dist/commands/audit/help.js +0 -1
- package/dist/commands/audit/processAudit.js +1 -1
- package/dist/constants/constants.js +1 -1
- package/dist/sbom/generateSbom.js +7 -0
- package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +3 -3
- package/dist/scaAnalysis/common/treeUpload.js +5 -19
- package/dist/scaAnalysis/go/goAnalysis.js +1 -6
- package/dist/scaAnalysis/java/analysis.js +24 -32
- package/dist/scaAnalysis/java/index.js +1 -6
- package/dist/scaAnalysis/javascript/index.js +1 -4
- package/dist/scaAnalysis/php/index.js +2 -8
- package/dist/scaAnalysis/python/analysis.js +4 -10
- package/dist/scaAnalysis/python/index.js +1 -6
- package/dist/scaAnalysis/ruby/analysis.js +1 -10
- package/dist/scaAnalysis/ruby/index.js +1 -6
- package/dist/scaAnalysis/scaAnalysis.js +17 -59
- package/package.json +2 -5
- package/src/audit/report/commonReportingFunctions.js +1 -1
- package/src/audit/save.js +11 -9
- package/src/commands/audit/help.js +0 -1
- package/src/commands/audit/processAudit.js +2 -5
- package/src/constants/constants.js +1 -1
- package/src/sbom/generateSbom.ts +8 -0
- package/src/scaAnalysis/common/commonReportingFunctionsSca.js +3 -3
- package/src/scaAnalysis/common/treeUpload.js +5 -20
- package/src/scaAnalysis/go/goAnalysis.js +1 -6
- package/src/scaAnalysis/java/analysis.js +29 -34
- package/src/scaAnalysis/java/index.js +1 -6
- package/src/scaAnalysis/javascript/index.js +1 -6
- package/src/scaAnalysis/php/index.js +2 -8
- package/src/scaAnalysis/python/analysis.js +4 -10
- package/src/scaAnalysis/python/index.js +1 -6
- package/src/scaAnalysis/ruby/analysis.js +1 -11
- package/src/scaAnalysis/ruby/index.js +1 -6
- package/src/scaAnalysis/scaAnalysis.js +25 -85
- package/dist/utils/settingsHelper.js +0 -24
- package/src/utils/settingsHelper.js +0 -26
|
@@ -122,7 +122,7 @@ function buildHeader(highestSeverity, contrastHeaderNum, libraryName, version, n
|
|
|
122
122
|
function buildBody(cveArray, advice) {
|
|
123
123
|
const orderedCvesWithSeverityAssigned = orderByHighestPriority(cveArray.map(cve => findCVESeverity(cve)));
|
|
124
124
|
const issueMessage = getIssueRow(orderedCvesWithSeverityAssigned);
|
|
125
|
-
const minOrMax = advice.
|
|
125
|
+
const minOrMax = advice.minimum ? advice.minimum : advice.maximum;
|
|
126
126
|
const displayAdvice = minOrMax
|
|
127
127
|
? `Change to version ${chalk.bold(minOrMax)}`
|
|
128
128
|
: 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.';
|
package/dist/audit/save.js
CHANGED
|
@@ -19,18 +19,24 @@ async function auditSave(config, reportId) {
|
|
|
19
19
|
break;
|
|
20
20
|
}
|
|
21
21
|
if (fileFormat) {
|
|
22
|
-
if (config.
|
|
23
|
-
|
|
22
|
+
if (config.legacy === false) {
|
|
23
|
+
const sbomResponse = await sbom.generateSCASbom(config, fileFormat, reportId);
|
|
24
|
+
if (sbomResponse) {
|
|
25
|
+
save.saveFile(config, fileFormat, sbomResponse);
|
|
26
|
+
}
|
|
24
27
|
}
|
|
25
28
|
else {
|
|
26
|
-
|
|
29
|
+
const sbomResponse = await sbom.generateSbom(config, fileFormat);
|
|
30
|
+
if (sbomResponse) {
|
|
31
|
+
save.saveFile(config, fileFormat, sbomResponse);
|
|
32
|
+
}
|
|
27
33
|
}
|
|
28
34
|
const filename = `${config.applicationId}-sbom-${fileFormat}.json`;
|
|
29
35
|
if (fs.existsSync(filename)) {
|
|
30
36
|
console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`);
|
|
31
37
|
}
|
|
32
38
|
else {
|
|
33
|
-
console.log(chalk.yellow.bold(`\
|
|
39
|
+
console.log(chalk.yellow.bold(`\nUnable to save ${filename} Software Bill of Materials (SBOM)`));
|
|
34
40
|
}
|
|
35
41
|
}
|
|
36
42
|
else {
|
|
@@ -9,7 +9,7 @@ const processAudit = async (contrastConf, argvMain) => {
|
|
|
9
9
|
printHelpMessage();
|
|
10
10
|
process.exit(0);
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
let config = await auditConfig.getAuditConfig(contrastConf, 'audit', argvMain);
|
|
13
13
|
await scaController.processSca(config);
|
|
14
14
|
if (!config.fingerprint) {
|
|
15
15
|
postRunMessage('audit');
|
|
@@ -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.23';
|
|
16
16
|
const TIMEOUT = 120000;
|
|
17
17
|
const HIGH_COLOUR = '#ff9900';
|
|
18
18
|
const CRITICAL_COLOUR = '#e35858';
|
|
@@ -10,8 +10,14 @@ const generateSbom = (config, type) => {
|
|
|
10
10
|
if (res.statusCode === 200) {
|
|
11
11
|
return res.body;
|
|
12
12
|
}
|
|
13
|
+
else if (res.statusCode === 403) {
|
|
14
|
+
console.log('\nUnable to retrieve Software Bill of Materials (SBOM)');
|
|
15
|
+
console.log(`Please ensure OSS is enabled for your organization - org-id ${config.organizationId} and app ${config.applicationId}`);
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
13
18
|
else {
|
|
14
19
|
console.log('Unable to retrieve Software Bill of Materials (SBOM)');
|
|
20
|
+
return undefined;
|
|
15
21
|
}
|
|
16
22
|
})
|
|
17
23
|
.catch((err) => {
|
|
@@ -29,6 +35,7 @@ const generateSCASbom = (config, type, reportId) => {
|
|
|
29
35
|
}
|
|
30
36
|
else {
|
|
31
37
|
console.log('Unable to retrieve Software Bill of Materials (SBOM)');
|
|
38
|
+
return undefined;
|
|
32
39
|
}
|
|
33
40
|
})
|
|
34
41
|
.catch((err) => {
|
|
@@ -104,9 +104,9 @@ function getIssueRow(cveArray) {
|
|
|
104
104
|
return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`];
|
|
105
105
|
}
|
|
106
106
|
function getAdviceRow(advice) {
|
|
107
|
-
const latestOrClosest = advice.
|
|
108
|
-
? advice.
|
|
109
|
-
: advice.
|
|
107
|
+
const latestOrClosest = advice.closestStableVersion
|
|
108
|
+
? advice.closestStableVersion
|
|
109
|
+
: advice.latestStableVersion;
|
|
110
110
|
const displayAdvice = latestOrClosest
|
|
111
111
|
? `Change to version ${chalk.bold(latestOrClosest)}`
|
|
112
112
|
: 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.';
|
|
@@ -3,13 +3,11 @@ const commonApi = require('../../utils/commonApi');
|
|
|
3
3
|
const { APP_VERSION } = require('../../constants/constants');
|
|
4
4
|
const commonSendSnapShot = async (analysis, config) => {
|
|
5
5
|
let requestBody = {};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
snapshot: analysis
|
|
12
|
-
});
|
|
6
|
+
requestBody = {
|
|
7
|
+
appID: config.applicationId,
|
|
8
|
+
cliVersion: APP_VERSION,
|
|
9
|
+
snapshot: analysis
|
|
10
|
+
};
|
|
13
11
|
const client = commonApi.getHttpClient(config);
|
|
14
12
|
return client
|
|
15
13
|
.sendSnapshot(requestBody, config)
|
|
@@ -28,18 +26,6 @@ const commonSendSnapShot = async (analysis, config) => {
|
|
|
28
26
|
throw err;
|
|
29
27
|
});
|
|
30
28
|
};
|
|
31
|
-
const sendToSCAServices = (config, analysis) => {
|
|
32
|
-
return {
|
|
33
|
-
applicationId: config.applicationId,
|
|
34
|
-
dependencyTree: analysis,
|
|
35
|
-
organizationId: config.organizationId,
|
|
36
|
-
language: config.language,
|
|
37
|
-
tool: {
|
|
38
|
-
name: 'Contrast Codesec',
|
|
39
|
-
version: APP_VERSION
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
29
|
module.exports = {
|
|
44
30
|
commonSendSnapShot
|
|
45
31
|
};
|
|
@@ -7,12 +7,7 @@ const goAnalysis = config => {
|
|
|
7
7
|
try {
|
|
8
8
|
const rawGoDependencies = goReadDepFile.getGoDependencies(config);
|
|
9
9
|
const parsedGoDependencies = goParseDeps.parseGoDependencies(rawGoDependencies);
|
|
10
|
-
|
|
11
|
-
return parseDependenciesForSCAServices(parsedGoDependencies);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
return createGoTSMessage(parsedGoDependencies);
|
|
15
|
-
}
|
|
10
|
+
return createGoTSMessage(parsedGoDependencies);
|
|
16
11
|
}
|
|
17
12
|
catch (e) {
|
|
18
13
|
console.log(e.message.toString());
|
|
@@ -4,8 +4,6 @@ const spawn = require('cross-spawn');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const i18n = require('i18n');
|
|
6
6
|
const fs = require('fs');
|
|
7
|
-
const readLine = require('readline');
|
|
8
|
-
const paramHandler = require('../../utils/paramsUtil/paramHandler');
|
|
9
7
|
const MAVEN = 'maven';
|
|
10
8
|
const GRADLE = 'gradle';
|
|
11
9
|
const determineProjectTypeAndCwd = (files, config) => {
|
|
@@ -25,26 +23,25 @@ const determineProjectTypeAndCwd = (files, config) => {
|
|
|
25
23
|
return projectData;
|
|
26
24
|
};
|
|
27
25
|
const buildMaven = (config, projectData, timeout) => {
|
|
28
|
-
let
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
args.push('-s');
|
|
34
|
-
args.push(config.mavenSettingsPath);
|
|
35
|
-
}
|
|
36
|
-
cmdStdout = spawn
|
|
37
|
-
.sync(command, args, {
|
|
38
|
-
env: process.env,
|
|
39
|
-
cwd: projectData.cwd,
|
|
40
|
-
timeout
|
|
41
|
-
})
|
|
42
|
-
.stdout.toString();
|
|
43
|
-
return cmdStdout.toString();
|
|
26
|
+
let command = 'mvn';
|
|
27
|
+
let args = ['dependency:tree', '-B'];
|
|
28
|
+
if (config.mavenSettingsPath) {
|
|
29
|
+
args.push('-s');
|
|
30
|
+
args.push(config.mavenSettingsPath);
|
|
44
31
|
}
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
const cmdDepTree = spawn.sync(command, args, {
|
|
33
|
+
env: process.env,
|
|
34
|
+
cwd: projectData.cwd,
|
|
35
|
+
timeout
|
|
36
|
+
});
|
|
37
|
+
if (cmdDepTree.status !== 0) {
|
|
38
|
+
if (config.debug && cmdDepTree.error.code === 'ENOENT') {
|
|
39
|
+
console.log(`ERROR: mvn not found`);
|
|
40
|
+
console.log('Please make sure mvn is installed and accessible');
|
|
41
|
+
}
|
|
42
|
+
throw new Error(i18n.__('mavenDependencyTreeNonZero', projectData.cwd));
|
|
47
43
|
}
|
|
44
|
+
return cmdDepTree.stdout.toString();
|
|
48
45
|
};
|
|
49
46
|
const buildGradle = (config, projectData, timeout) => {
|
|
50
47
|
let cmdStdout;
|
|
@@ -96,20 +93,15 @@ const getJavaBuildDeps = (config, files) => {
|
|
|
96
93
|
mvnDependancyTreeOutput: undefined,
|
|
97
94
|
projectType: undefined
|
|
98
95
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout);
|
|
103
|
-
}
|
|
104
|
-
else if (projectData.projectType === GRADLE) {
|
|
105
|
-
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout);
|
|
106
|
-
}
|
|
107
|
-
output.projectType = projectData.projectType;
|
|
108
|
-
return output;
|
|
96
|
+
const projectData = determineProjectTypeAndCwd(files, config);
|
|
97
|
+
if (projectData.projectType === MAVEN) {
|
|
98
|
+
output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout);
|
|
109
99
|
}
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
else if (projectData.projectType === GRADLE) {
|
|
101
|
+
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout);
|
|
112
102
|
}
|
|
103
|
+
output.projectType = projectData.projectType;
|
|
104
|
+
return output;
|
|
113
105
|
};
|
|
114
106
|
module.exports = {
|
|
115
107
|
getJavaBuildDeps,
|
|
@@ -8,12 +8,7 @@ const javaAnalysis = async (config, languageFiles) => {
|
|
|
8
8
|
file.replace('build.gradle.kts', 'build.gradle');
|
|
9
9
|
});
|
|
10
10
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA);
|
|
11
|
-
|
|
12
|
-
return parseDependenciesForSCAServices(javaDeps);
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return createJavaTSMessage(javaDeps);
|
|
16
|
-
}
|
|
11
|
+
return createJavaTSMessage(javaDeps);
|
|
17
12
|
};
|
|
18
13
|
const buildJavaTree = (config, files) => {
|
|
19
14
|
const javaBuildDeps = analysis.getJavaBuildDeps(config, files);
|
|
@@ -13,9 +13,6 @@ const jsAnalysis = async (config, languageFiles) => {
|
|
|
13
13
|
const buildNodeTree = async (config, files) => {
|
|
14
14
|
let analysis = await readFiles(config, files);
|
|
15
15
|
const rawNode = await parseFiles(config, files, analysis);
|
|
16
|
-
if (config.experimental) {
|
|
17
|
-
return scaServiceParser.parseJS(rawNode);
|
|
18
|
-
}
|
|
19
16
|
return formatMessage.createJavaScriptTSMessage(rawNode);
|
|
20
17
|
};
|
|
21
18
|
const readFiles = async (config, files) => {
|
|
@@ -42,7 +39,7 @@ const parseFiles = async (config, files, js) => {
|
|
|
42
39
|
if (!currentLockFileVersion || !npmLockFile.packages) {
|
|
43
40
|
throw new Error(`package-lock.json needs to be in the NPM v2 or v3 format. \n ${generalRebuildMessage}`);
|
|
44
41
|
}
|
|
45
|
-
if (currentLockFileVersion === 3
|
|
42
|
+
if (currentLockFileVersion === 3) {
|
|
46
43
|
throw new Error(`NPM lockfileVersion 3 is only supported when using the '-e' flag.`);
|
|
47
44
|
}
|
|
48
45
|
js.npmLockFile = await analysis.parseNpmLockFile(npmLockFile);
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const { readFile, parseProjectFiles } = require('./analysis');
|
|
3
3
|
const { createPhpTSMessage } = require('../common/formatMessage');
|
|
4
|
-
const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper');
|
|
5
4
|
const phpAnalysis = config => {
|
|
6
5
|
let analysis = readFiles(config);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
const phpDep = parseProjectFiles(analysis);
|
|
12
|
-
return createPhpTSMessage(phpDep);
|
|
13
|
-
}
|
|
6
|
+
const phpDep = parseProjectFiles(analysis);
|
|
7
|
+
return createPhpTSMessage(phpDep);
|
|
14
8
|
};
|
|
15
9
|
const readFiles = config => {
|
|
16
10
|
let php = {};
|
|
@@ -48,16 +48,10 @@ const checkForCorrectFiles = languageFiles => {
|
|
|
48
48
|
};
|
|
49
49
|
const getPythonDeps = (config, languageFiles) => {
|
|
50
50
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
checkForCorrectFiles(languageFiles);
|
|
57
|
-
const parseProject = readAndParseProjectFile(config.file);
|
|
58
|
-
const parsePip = readAndParseLockFile(config.file);
|
|
59
|
-
return { pipfileLock: parsePip, pipfilDependanceies: parseProject };
|
|
60
|
-
}
|
|
51
|
+
checkForCorrectFiles(languageFiles);
|
|
52
|
+
const parseProject = readAndParseProjectFile(config.file);
|
|
53
|
+
const parsePip = readAndParseLockFile(config.file);
|
|
54
|
+
return { pipfileLock: parsePip, pipfilDependanceies: parseProject };
|
|
61
55
|
}
|
|
62
56
|
catch (err) {
|
|
63
57
|
console.log(err.message.toString());
|
|
@@ -3,12 +3,7 @@ const { createPythonTSMessage } = require('../common/formatMessage');
|
|
|
3
3
|
const { getPythonDeps, secondaryParser } = require('./analysis');
|
|
4
4
|
const pythonAnalysis = (config, languageFiles) => {
|
|
5
5
|
const pythonDeps = getPythonDeps(config, languageFiles.PYTHON);
|
|
6
|
-
|
|
7
|
-
return pythonDeps;
|
|
8
|
-
}
|
|
9
|
-
else {
|
|
10
|
-
return createPythonTSMessage(pythonDeps);
|
|
11
|
-
}
|
|
6
|
+
return createPythonTSMessage(pythonDeps);
|
|
12
7
|
};
|
|
13
8
|
module.exports = {
|
|
14
9
|
pythonAnalysis
|
|
@@ -6,16 +6,7 @@ const getRubyDeps = (config, languageFiles) => {
|
|
|
6
6
|
checkForCorrectFiles(languageFiles);
|
|
7
7
|
const parsedGem = readAndParseGemfile(config.file);
|
|
8
8
|
const parsedLock = readAndParseGemLockFile(config.file);
|
|
9
|
-
|
|
10
|
-
const rubyArray = removeRedundantAndPopulateDefinedElements(parsedLock.sources);
|
|
11
|
-
let rubyTree = createRubyTree(rubyArray);
|
|
12
|
-
findChildrenDependencies(rubyTree);
|
|
13
|
-
processRootDependencies(parsedLock.dependencies, rubyTree);
|
|
14
|
-
return rubyTree;
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock };
|
|
18
|
-
}
|
|
9
|
+
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock };
|
|
19
10
|
}
|
|
20
11
|
catch (err) {
|
|
21
12
|
throw err;
|
|
@@ -3,12 +3,7 @@ const analysis = require('./analysis');
|
|
|
3
3
|
const { createRubyTSMessage } = require('../common/formatMessage');
|
|
4
4
|
const rubyAnalysis = (config, languageFiles) => {
|
|
5
5
|
const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY);
|
|
6
|
-
|
|
7
|
-
return rubyDeps;
|
|
8
|
-
}
|
|
9
|
-
else {
|
|
10
|
-
return createRubyTSMessage(rubyDeps);
|
|
11
|
-
}
|
|
6
|
+
return createRubyTSMessage(rubyDeps);
|
|
12
7
|
};
|
|
13
8
|
module.exports = {
|
|
14
9
|
rubyAnalysis
|
|
@@ -19,14 +19,8 @@ const { rubyAnalysis } = require('./ruby');
|
|
|
19
19
|
const { pythonAnalysis } = require('./python');
|
|
20
20
|
const javaAnalysis = require('./java');
|
|
21
21
|
const jsAnalysis = require('./javascript');
|
|
22
|
-
const auditReport = require('./common/auditReport');
|
|
23
|
-
const scaUpload = require('./common/scaServicesUpload');
|
|
24
|
-
const settingsHelper = require('../utils/settingsHelper');
|
|
25
22
|
const chalk = require('chalk');
|
|
26
|
-
const saveResults = require('../scan/saveResults');
|
|
27
|
-
const { convertGenericToTypedReportModelSca } = require('./common/utils/reportUtilsSca');
|
|
28
23
|
const processSca = async (config) => {
|
|
29
|
-
config = await settingsHelper.getSettings(config);
|
|
30
24
|
const startTime = performance.now();
|
|
31
25
|
let filesFound;
|
|
32
26
|
if (config.help) {
|
|
@@ -49,17 +43,7 @@ const processSca = async (config) => {
|
|
|
49
43
|
switch (Object.keys(filesFound[0])[0]) {
|
|
50
44
|
case JAVA:
|
|
51
45
|
config.language = JAVA;
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
return repoMode.buildRepo(config, filesFound[0]);
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
throw new Error('Unable to build in repository mode. Check your project file');
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
|
|
62
|
-
}
|
|
46
|
+
messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
|
|
63
47
|
break;
|
|
64
48
|
case JAVASCRIPT:
|
|
65
49
|
messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
|
|
@@ -82,15 +66,9 @@ const processSca = async (config) => {
|
|
|
82
66
|
config.language = GO;
|
|
83
67
|
break;
|
|
84
68
|
case DOTNET:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
messageToSend = dotNetAnalysis(config, filesFound[0]);
|
|
91
|
-
config.language = DOTNET;
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
69
|
+
messageToSend = dotNetAnalysis(config, filesFound[0]);
|
|
70
|
+
config.language = DOTNET;
|
|
71
|
+
break;
|
|
94
72
|
default:
|
|
95
73
|
console.log('No supported language detected in project path');
|
|
96
74
|
return;
|
|
@@ -98,42 +76,22 @@ const processSca = async (config) => {
|
|
|
98
76
|
if (!config.applicationId) {
|
|
99
77
|
config.applicationId = await auditController.dealWithNoAppId(config);
|
|
100
78
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await auditSave.auditSave(config, reportId);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
console.log('Use contrast audit --save to generate an SBOM');
|
|
114
|
-
}
|
|
115
|
-
const endTime = performance.now() - startTime;
|
|
116
|
-
const scanDurationMs = endTime - startTime;
|
|
117
|
-
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
79
|
+
console.log('');
|
|
80
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
|
|
81
|
+
startSpinner(reportSpinner);
|
|
82
|
+
const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
|
|
83
|
+
await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
|
|
84
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
|
|
85
|
+
await vulnerabilityReportV2(config, snapshotResponse.id);
|
|
86
|
+
if (config.save !== undefined) {
|
|
87
|
+
await auditSave.auditSave(config);
|
|
118
88
|
}
|
|
119
89
|
else {
|
|
120
|
-
console.log('');
|
|
121
|
-
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
|
|
122
|
-
startSpinner(reportSpinner);
|
|
123
|
-
const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
|
|
124
|
-
await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
|
|
125
|
-
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
|
|
126
|
-
await vulnerabilityReportV2(config, snapshotResponse.id);
|
|
127
|
-
if (config.save !== undefined) {
|
|
128
|
-
await auditSave.auditSave(config);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
console.log('\nUse contrast audit --save to generate an SBOM');
|
|
132
|
-
}
|
|
133
|
-
const endTime = performance.now() - startTime;
|
|
134
|
-
const scanDurationMs = endTime - startTime;
|
|
135
|
-
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
90
|
+
console.log('\nUse contrast audit --save to generate an SBOM');
|
|
136
91
|
}
|
|
92
|
+
const endTime = performance.now() - startTime;
|
|
93
|
+
const scanDurationMs = endTime - startTime;
|
|
94
|
+
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
137
95
|
}
|
|
138
96
|
else {
|
|
139
97
|
if (filesFound.length === 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/contrast",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.23",
|
|
4
4
|
"description": "Contrast Security's command line tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,12 +27,9 @@
|
|
|
27
27
|
"test": "jest --testPathIgnorePatterns=./test-integration/",
|
|
28
28
|
"test-int": "jest ./test-integration/",
|
|
29
29
|
"test-int-scan": "jest ./test-integration/scan",
|
|
30
|
-
"test-int-audit": "jest test-integration/audit",
|
|
31
|
-
"test-int-audit-reports": "jest test-integration/audit/audit-language-reports.spec.js",
|
|
32
30
|
"test-int-scan-errors": "jest test-integration/scan/scanLocalErrors.spec.js",
|
|
33
31
|
"test-int-scan-reports": "jest test-integration/scan/scanReport.spec.js",
|
|
34
|
-
"test-int-audit-features": "jest test-integration/audit/auditFeatures
|
|
35
|
-
"test-int-audit-experimental": "jest test-integration/audit/audit-experimental.spec.js",
|
|
32
|
+
"test-int-audit-features": "jest test-integration/audit/auditFeatures",
|
|
36
33
|
"format": "prettier --write \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
37
34
|
"check-format": "prettier --check \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
38
35
|
"coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
|
|
@@ -247,7 +247,7 @@ function buildBody(cveArray, advice) {
|
|
|
247
247
|
//todo different advice based on remediationGuidance being available or now
|
|
248
248
|
// console.log(advice)
|
|
249
249
|
|
|
250
|
-
const minOrMax = advice.
|
|
250
|
+
const minOrMax = advice.minimum ? advice.minimum : advice.maximum
|
|
251
251
|
const displayAdvice = minOrMax
|
|
252
252
|
? `Change to version ${chalk.bold(minOrMax)}`
|
|
253
253
|
: 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.'
|
package/src/audit/save.js
CHANGED
|
@@ -23,18 +23,20 @@ async function auditSave(config, reportId) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
if (fileFormat) {
|
|
26
|
-
if (config.
|
|
27
|
-
|
|
26
|
+
if (config.legacy === false) {
|
|
27
|
+
const sbomResponse = await sbom.generateSCASbom(
|
|
28
28
|
config,
|
|
29
29
|
fileFormat,
|
|
30
|
-
|
|
30
|
+
reportId
|
|
31
31
|
)
|
|
32
|
+
if (sbomResponse) {
|
|
33
|
+
save.saveFile(config, fileFormat, sbomResponse)
|
|
34
|
+
}
|
|
32
35
|
} else {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
fileFormat,
|
|
36
|
-
|
|
37
|
-
)
|
|
36
|
+
const sbomResponse = await sbom.generateSbom(config, fileFormat)
|
|
37
|
+
if (sbomResponse) {
|
|
38
|
+
save.saveFile(config, fileFormat, sbomResponse)
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
41
|
const filename = `${config.applicationId}-sbom-${fileFormat}.json`
|
|
40
42
|
if (fs.existsSync(filename)) {
|
|
@@ -42,7 +44,7 @@ async function auditSave(config, reportId) {
|
|
|
42
44
|
} else {
|
|
43
45
|
console.log(
|
|
44
46
|
chalk.yellow.bold(
|
|
45
|
-
`\
|
|
47
|
+
`\nUnable to save ${filename} Software Bill of Materials (SBOM)`
|
|
46
48
|
)
|
|
47
49
|
)
|
|
48
50
|
}
|
|
@@ -10,11 +10,8 @@ const processAudit = async (contrastConf, argvMain) => {
|
|
|
10
10
|
process.exit(0)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'audit',
|
|
16
|
-
argvMain
|
|
17
|
-
)
|
|
13
|
+
let config = await auditConfig.getAuditConfig(contrastConf, 'audit', argvMain)
|
|
14
|
+
|
|
18
15
|
await scaController.processSca(config)
|
|
19
16
|
if (!config.fingerprint) {
|
|
20
17
|
postRunMessage('audit')
|
package/src/sbom/generateSbom.ts
CHANGED
|
@@ -7,8 +7,15 @@ export const generateSbom = (config: any, type: string) => {
|
|
|
7
7
|
.then((res: { statusCode: number; body: any }) => {
|
|
8
8
|
if (res.statusCode === 200) {
|
|
9
9
|
return res.body
|
|
10
|
+
} else if (res.statusCode === 403) {
|
|
11
|
+
console.log('\nUnable to retrieve Software Bill of Materials (SBOM)')
|
|
12
|
+
console.log(
|
|
13
|
+
`Please ensure OSS is enabled for your organization - org-id ${config.organizationId} and app ${config.applicationId}`
|
|
14
|
+
)
|
|
15
|
+
return undefined
|
|
10
16
|
} else {
|
|
11
17
|
console.log('Unable to retrieve Software Bill of Materials (SBOM)')
|
|
18
|
+
return undefined
|
|
12
19
|
}
|
|
13
20
|
})
|
|
14
21
|
.catch((err: any) => {
|
|
@@ -29,6 +36,7 @@ export const generateSCASbom = (
|
|
|
29
36
|
return res.body
|
|
30
37
|
} else {
|
|
31
38
|
console.log('Unable to retrieve Software Bill of Materials (SBOM)')
|
|
39
|
+
return undefined
|
|
32
40
|
}
|
|
33
41
|
})
|
|
34
42
|
.catch((err: any) => {
|
|
@@ -217,9 +217,9 @@ function getIssueRow(cveArray) {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
function getAdviceRow(advice) {
|
|
220
|
-
const latestOrClosest = advice.
|
|
221
|
-
? advice.
|
|
222
|
-
: advice.
|
|
220
|
+
const latestOrClosest = advice.closestStableVersion
|
|
221
|
+
? advice.closestStableVersion
|
|
222
|
+
: advice.latestStableVersion
|
|
223
223
|
const displayAdvice = latestOrClosest
|
|
224
224
|
? `Change to version ${chalk.bold(latestOrClosest)}`
|
|
225
225
|
: 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.'
|
|
@@ -3,13 +3,11 @@ const { APP_VERSION } = require('../../constants/constants')
|
|
|
3
3
|
|
|
4
4
|
const commonSendSnapShot = async (analysis, config) => {
|
|
5
5
|
let requestBody = {}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
snapshot: analysis
|
|
12
|
-
})
|
|
6
|
+
requestBody = {
|
|
7
|
+
appID: config.applicationId,
|
|
8
|
+
cliVersion: APP_VERSION,
|
|
9
|
+
snapshot: analysis
|
|
10
|
+
}
|
|
13
11
|
|
|
14
12
|
const client = commonApi.getHttpClient(config)
|
|
15
13
|
return client
|
|
@@ -33,19 +31,6 @@ const commonSendSnapShot = async (analysis, config) => {
|
|
|
33
31
|
})
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
const sendToSCAServices = (config, analysis) => {
|
|
37
|
-
return {
|
|
38
|
-
applicationId: config.applicationId,
|
|
39
|
-
dependencyTree: analysis,
|
|
40
|
-
organizationId: config.organizationId,
|
|
41
|
-
language: config.language,
|
|
42
|
-
tool: {
|
|
43
|
-
name: 'Contrast Codesec',
|
|
44
|
-
version: APP_VERSION
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
34
|
module.exports = {
|
|
50
35
|
commonSendSnapShot
|
|
51
36
|
}
|
|
@@ -10,12 +10,7 @@ const goAnalysis = config => {
|
|
|
10
10
|
const rawGoDependencies = goReadDepFile.getGoDependencies(config)
|
|
11
11
|
const parsedGoDependencies =
|
|
12
12
|
goParseDeps.parseGoDependencies(rawGoDependencies)
|
|
13
|
-
|
|
14
|
-
if (config.experimental) {
|
|
15
|
-
return parseDependenciesForSCAServices(parsedGoDependencies)
|
|
16
|
-
} else {
|
|
17
|
-
return createGoTSMessage(parsedGoDependencies)
|
|
18
|
-
}
|
|
13
|
+
return createGoTSMessage(parsedGoDependencies)
|
|
19
14
|
} catch (e) {
|
|
20
15
|
console.log(e.message.toString())
|
|
21
16
|
}
|
|
@@ -3,8 +3,6 @@ const spawn = require('cross-spawn')
|
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const i18n = require('i18n')
|
|
5
5
|
const fs = require('fs')
|
|
6
|
-
const readLine = require('readline')
|
|
7
|
-
const paramHandler = require('../../utils/paramsUtil/paramHandler')
|
|
8
6
|
|
|
9
7
|
const MAVEN = 'maven'
|
|
10
8
|
const GRADLE = 'gradle'
|
|
@@ -31,30 +29,31 @@ const determineProjectTypeAndCwd = (files, config) => {
|
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
const buildMaven = (config, projectData, timeout) => {
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
args.push(config.mavenSettingsPath)
|
|
41
|
-
}
|
|
42
|
-
// Allow users to provide a custom location for their settings.xml
|
|
32
|
+
let command = 'mvn'
|
|
33
|
+
let args = ['dependency:tree', '-B']
|
|
34
|
+
if (config.mavenSettingsPath) {
|
|
35
|
+
args.push('-s')
|
|
36
|
+
args.push(config.mavenSettingsPath)
|
|
37
|
+
}
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.stdout.toString()
|
|
39
|
+
// Allow users to provide a custom location for their settings.xml
|
|
40
|
+
const cmdDepTree = spawn.sync(command, args, {
|
|
41
|
+
env: process.env,
|
|
42
|
+
cwd: projectData.cwd,
|
|
43
|
+
timeout
|
|
44
|
+
})
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
if (cmdDepTree.status !== 0) {
|
|
47
|
+
//if maven not found
|
|
48
|
+
if (config.debug && cmdDepTree.error.code === 'ENOENT') {
|
|
49
|
+
console.log(`ERROR: mvn not found`)
|
|
50
|
+
console.log('Please make sure mvn is installed and accessible')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
throw new Error(i18n.__('mavenDependencyTreeNonZero', projectData.cwd))
|
|
57
54
|
}
|
|
55
|
+
|
|
56
|
+
return cmdDepTree.stdout.toString()
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
const buildGradle = (config, projectData, timeout) => {
|
|
@@ -133,18 +132,14 @@ const getJavaBuildDeps = (config, files) => {
|
|
|
133
132
|
projectType: undefined
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout)
|
|
142
|
-
}
|
|
143
|
-
output.projectType = projectData.projectType
|
|
144
|
-
return output
|
|
145
|
-
} catch (err) {
|
|
146
|
-
console.log(err.message.toString())
|
|
135
|
+
const projectData = determineProjectTypeAndCwd(files, config)
|
|
136
|
+
if (projectData.projectType === MAVEN) {
|
|
137
|
+
output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout)
|
|
138
|
+
} else if (projectData.projectType === GRADLE) {
|
|
139
|
+
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout)
|
|
147
140
|
}
|
|
141
|
+
output.projectType = projectData.projectType
|
|
142
|
+
return output
|
|
148
143
|
}
|
|
149
144
|
|
|
150
145
|
module.exports = {
|
|
@@ -11,12 +11,7 @@ const javaAnalysis = async (config, languageFiles) => {
|
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
14
|
-
|
|
15
|
-
if (config.experimental) {
|
|
16
|
-
return parseDependenciesForSCAServices(javaDeps)
|
|
17
|
-
} else {
|
|
18
|
-
return createJavaTSMessage(javaDeps)
|
|
19
|
-
}
|
|
14
|
+
return createJavaTSMessage(javaDeps)
|
|
20
15
|
}
|
|
21
16
|
|
|
22
17
|
const buildJavaTree = (config, files) => {
|
|
@@ -14,11 +14,6 @@ const jsAnalysis = async (config, languageFiles) => {
|
|
|
14
14
|
const buildNodeTree = async (config, files) => {
|
|
15
15
|
let analysis = await readFiles(config, files)
|
|
16
16
|
const rawNode = await parseFiles(config, files, analysis)
|
|
17
|
-
|
|
18
|
-
if (config.experimental) {
|
|
19
|
-
return scaServiceParser.parseJS(rawNode)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
17
|
return formatMessage.createJavaScriptTSMessage(rawNode)
|
|
23
18
|
}
|
|
24
19
|
|
|
@@ -65,7 +60,7 @@ const parseFiles = async (config, files, js) => {
|
|
|
65
60
|
)
|
|
66
61
|
}
|
|
67
62
|
|
|
68
|
-
if (currentLockFileVersion === 3
|
|
63
|
+
if (currentLockFileVersion === 3) {
|
|
69
64
|
throw new Error(
|
|
70
65
|
`NPM lockfileVersion 3 is only supported when using the '-e' flag.`
|
|
71
66
|
)
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
const { readFile, parseProjectFiles } = require('./analysis')
|
|
2
2
|
const { createPhpTSMessage } = require('../common/formatMessage')
|
|
3
|
-
const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper')
|
|
4
3
|
|
|
5
4
|
const phpAnalysis = config => {
|
|
6
5
|
let analysis = readFiles(config)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return parsePHPLockFileForScaServices(analysis.rawLockFileContents)
|
|
10
|
-
} else {
|
|
11
|
-
const phpDep = parseProjectFiles(analysis)
|
|
12
|
-
return createPhpTSMessage(phpDep)
|
|
13
|
-
}
|
|
6
|
+
const phpDep = parseProjectFiles(analysis)
|
|
7
|
+
return createPhpTSMessage(phpDep)
|
|
14
8
|
}
|
|
15
9
|
|
|
16
10
|
const readFiles = config => {
|
|
@@ -60,16 +60,10 @@ const checkForCorrectFiles = languageFiles => {
|
|
|
60
60
|
|
|
61
61
|
const getPythonDeps = (config, languageFiles) => {
|
|
62
62
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
checkForCorrectFiles(languageFiles)
|
|
68
|
-
const parseProject = readAndParseProjectFile(config.file)
|
|
69
|
-
const parsePip = readAndParseLockFile(config.file)
|
|
70
|
-
|
|
71
|
-
return { pipfileLock: parsePip, pipfilDependanceies: parseProject }
|
|
72
|
-
}
|
|
63
|
+
checkForCorrectFiles(languageFiles)
|
|
64
|
+
const parseProject = readAndParseProjectFile(config.file)
|
|
65
|
+
const parsePip = readAndParseLockFile(config.file)
|
|
66
|
+
return { pipfileLock: parsePip, pipfilDependanceies: parseProject }
|
|
73
67
|
} catch (err) {
|
|
74
68
|
console.log(err.message.toString())
|
|
75
69
|
process.exit(1)
|
|
@@ -3,12 +3,7 @@ const { getPythonDeps, secondaryParser } = require('./analysis')
|
|
|
3
3
|
|
|
4
4
|
const pythonAnalysis = (config, languageFiles) => {
|
|
5
5
|
const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
|
|
6
|
-
|
|
7
|
-
if (config.experimental) {
|
|
8
|
-
return pythonDeps
|
|
9
|
-
} else {
|
|
10
|
-
return createPythonTSMessage(pythonDeps)
|
|
11
|
-
}
|
|
6
|
+
return createPythonTSMessage(pythonDeps)
|
|
12
7
|
}
|
|
13
8
|
|
|
14
9
|
module.exports = {
|
|
@@ -6,17 +6,7 @@ const getRubyDeps = (config, languageFiles) => {
|
|
|
6
6
|
checkForCorrectFiles(languageFiles)
|
|
7
7
|
const parsedGem = readAndParseGemfile(config.file)
|
|
8
8
|
const parsedLock = readAndParseGemLockFile(config.file)
|
|
9
|
-
|
|
10
|
-
const rubyArray = removeRedundantAndPopulateDefinedElements(
|
|
11
|
-
parsedLock.sources
|
|
12
|
-
)
|
|
13
|
-
let rubyTree = createRubyTree(rubyArray)
|
|
14
|
-
findChildrenDependencies(rubyTree)
|
|
15
|
-
processRootDependencies(parsedLock.dependencies, rubyTree)
|
|
16
|
-
return rubyTree
|
|
17
|
-
} else {
|
|
18
|
-
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock }
|
|
19
|
-
}
|
|
9
|
+
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock }
|
|
20
10
|
} catch (err) {
|
|
21
11
|
throw err
|
|
22
12
|
}
|
|
@@ -3,12 +3,7 @@ const { createRubyTSMessage } = require('../common/formatMessage')
|
|
|
3
3
|
|
|
4
4
|
const rubyAnalysis = (config, languageFiles) => {
|
|
5
5
|
const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY)
|
|
6
|
-
|
|
7
|
-
if (config.experimental) {
|
|
8
|
-
return rubyDeps
|
|
9
|
-
} else {
|
|
10
|
-
return createRubyTSMessage(rubyDeps)
|
|
11
|
-
}
|
|
6
|
+
return createRubyTSMessage(rubyDeps)
|
|
12
7
|
}
|
|
13
8
|
|
|
14
9
|
module.exports = {
|
|
@@ -26,18 +26,10 @@ const { rubyAnalysis } = require('./ruby')
|
|
|
26
26
|
const { pythonAnalysis } = require('./python')
|
|
27
27
|
const javaAnalysis = require('./java')
|
|
28
28
|
const jsAnalysis = require('./javascript')
|
|
29
|
-
const auditReport = require('./common/auditReport')
|
|
30
|
-
const scaUpload = require('./common/scaServicesUpload')
|
|
31
|
-
const settingsHelper = require('../utils/settingsHelper')
|
|
32
29
|
const chalk = require('chalk')
|
|
33
|
-
const saveResults = require('../scan/saveResults')
|
|
34
|
-
const {
|
|
35
|
-
convertGenericToTypedReportModelSca
|
|
36
|
-
} = require('./common/utils/reportUtilsSca')
|
|
37
30
|
|
|
38
31
|
const processSca = async config => {
|
|
39
32
|
//checks to see whether to use old TS / new SCA path
|
|
40
|
-
config = await settingsHelper.getSettings(config)
|
|
41
33
|
|
|
42
34
|
const startTime = performance.now()
|
|
43
35
|
let filesFound
|
|
@@ -72,18 +64,7 @@ const processSca = async config => {
|
|
|
72
64
|
switch (Object.keys(filesFound[0])[0]) {
|
|
73
65
|
case JAVA:
|
|
74
66
|
config.language = JAVA
|
|
75
|
-
|
|
76
|
-
if (config.mode === 'repo') {
|
|
77
|
-
try {
|
|
78
|
-
return repoMode.buildRepo(config, filesFound[0])
|
|
79
|
-
} catch (e) {
|
|
80
|
-
throw new Error(
|
|
81
|
-
'Unable to build in repository mode. Check your project file'
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0])
|
|
86
|
-
}
|
|
67
|
+
messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0])
|
|
87
68
|
break
|
|
88
69
|
case JAVASCRIPT:
|
|
89
70
|
messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
|
|
@@ -106,18 +87,9 @@ const processSca = async config => {
|
|
|
106
87
|
config.language = GO
|
|
107
88
|
break
|
|
108
89
|
case DOTNET:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
'\n.NET project found\n'
|
|
113
|
-
)} Language type is unsupported.`
|
|
114
|
-
)
|
|
115
|
-
return
|
|
116
|
-
} else {
|
|
117
|
-
messageToSend = dotNetAnalysis(config, filesFound[0])
|
|
118
|
-
config.language = DOTNET
|
|
119
|
-
break
|
|
120
|
-
}
|
|
90
|
+
messageToSend = dotNetAnalysis(config, filesFound[0])
|
|
91
|
+
config.language = DOTNET
|
|
92
|
+
break
|
|
121
93
|
default:
|
|
122
94
|
//something is wrong
|
|
123
95
|
console.log('No supported language detected in project path')
|
|
@@ -127,63 +99,31 @@ const processSca = async config => {
|
|
|
127
99
|
if (!config.applicationId) {
|
|
128
100
|
config.applicationId = await auditController.dealWithNoAppId(config)
|
|
129
101
|
}
|
|
102
|
+
console.log('') //empty log for space before spinner
|
|
103
|
+
//send message to TS
|
|
104
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
105
|
+
startSpinner(reportSpinner)
|
|
106
|
+
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
107
|
+
messageToSend,
|
|
108
|
+
config
|
|
109
|
+
)
|
|
130
110
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
startSpinner(reportSpinner)
|
|
135
|
-
const { reportArray, reportId } = await scaUpload.scaTreeUpload(
|
|
136
|
-
messageToSend,
|
|
137
|
-
config
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
const reportModelLibraryList =
|
|
141
|
-
convertGenericToTypedReportModelSca(reportArray)
|
|
142
|
-
auditReport.processAuditReport(config, reportModelLibraryList)
|
|
143
|
-
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
144
|
-
|
|
145
|
-
if (config.save !== undefined) {
|
|
146
|
-
await auditSave.auditSave(config, reportId)
|
|
147
|
-
} else {
|
|
148
|
-
console.log('Use contrast audit --save to generate an SBOM')
|
|
149
|
-
}
|
|
111
|
+
// poll for completion
|
|
112
|
+
await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner)
|
|
113
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
150
114
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
155
|
-
)
|
|
115
|
+
await vulnerabilityReportV2(config, snapshotResponse.id)
|
|
116
|
+
if (config.save !== undefined) {
|
|
117
|
+
await auditSave.auditSave(config)
|
|
156
118
|
} else {
|
|
157
|
-
console.log('
|
|
158
|
-
//send message to TS
|
|
159
|
-
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
160
|
-
startSpinner(reportSpinner)
|
|
161
|
-
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
162
|
-
messageToSend,
|
|
163
|
-
config
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
// poll for completion
|
|
167
|
-
await pollForSnapshotCompletion(
|
|
168
|
-
config,
|
|
169
|
-
snapshotResponse.id,
|
|
170
|
-
reportSpinner
|
|
171
|
-
)
|
|
172
|
-
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
173
|
-
|
|
174
|
-
await vulnerabilityReportV2(config, snapshotResponse.id)
|
|
175
|
-
if (config.save !== undefined) {
|
|
176
|
-
await auditSave.auditSave(config)
|
|
177
|
-
} else {
|
|
178
|
-
console.log('\nUse contrast audit --save to generate an SBOM')
|
|
179
|
-
}
|
|
180
|
-
const endTime = performance.now() - startTime
|
|
181
|
-
const scanDurationMs = endTime - startTime
|
|
182
|
-
|
|
183
|
-
console.log(
|
|
184
|
-
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
185
|
-
)
|
|
119
|
+
console.log('\nUse contrast audit --save to generate an SBOM')
|
|
186
120
|
}
|
|
121
|
+
const endTime = performance.now() - startTime
|
|
122
|
+
const scanDurationMs = endTime - startTime
|
|
123
|
+
|
|
124
|
+
console.log(
|
|
125
|
+
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
126
|
+
)
|
|
187
127
|
} else {
|
|
188
128
|
if (filesFound.length === 0) {
|
|
189
129
|
console.log(i18n.__('languageAnalysisNoLanguage'))
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
.scaServiceHealth(config)
|
|
15
|
-
.then(res => {
|
|
16
|
-
return res.body.status === 'UP';
|
|
17
|
-
})
|
|
18
|
-
.catch(err => {
|
|
19
|
-
console.log(err);
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
module.exports = {
|
|
23
|
-
getSettings
|
|
24
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const commonApi = require('./commonApi')
|
|
2
|
-
const { getMode } = require('./generalAPI')
|
|
3
|
-
const { SAAS, MODE_BUILD } = require('../constants/constants')
|
|
4
|
-
|
|
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
|
-
|
|
12
|
-
const isSCAServicesAvailable = async config => {
|
|
13
|
-
const client = commonApi.getHttpClient(config)
|
|
14
|
-
return client
|
|
15
|
-
.scaServiceHealth(config)
|
|
16
|
-
.then(res => {
|
|
17
|
-
return res.body.status === 'UP'
|
|
18
|
-
})
|
|
19
|
-
.catch(err => {
|
|
20
|
-
console.log(err)
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
module.exports = {
|
|
25
|
-
getSettings
|
|
26
|
-
}
|