@contrast/contrast 1.0.20 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cliConstants.js +13 -6
- package/dist/commands/audit/help.js +2 -1
- package/dist/commands/audit/processAudit.js +1 -1
- package/dist/commands/fingerprint/fingerprintConfig.js +12 -0
- package/dist/commands/fingerprint/processFingerprint.js +14 -0
- package/dist/commands/learn/learn.js +9 -0
- package/dist/commands/learn/processLearn.js +10 -0
- package/dist/common/commonHelp.js +8 -1
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +8 -1
- package/dist/index.js +8 -0
- package/dist/lambda/help.js +2 -1
- package/dist/scaAnalysis/scaAnalysis.js +155 -0
- package/dist/scan/autoDetection.js +2 -2
- package/dist/scan/fileUtils.js +2 -2
- package/dist/scan/help.js +2 -1
- package/package.json +1 -1
- package/src/cliConstants.js +15 -6
- package/src/commands/audit/help.js +2 -1
- package/src/commands/audit/processAudit.js +1 -1
- package/src/commands/fingerprint/fingerprintConfig.js +19 -0
- package/src/commands/fingerprint/processFingerprint.js +21 -0
- package/src/commands/learn/learn.js +10 -0
- package/src/commands/learn/processLearn.js +13 -0
- package/src/common/commonHelp.js +11 -1
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +16 -1
- package/src/index.ts +11 -0
- package/src/lambda/help.ts +2 -1
- package/src/scaAnalysis/scaAnalysis.js +206 -0
- package/src/scan/autoDetection.js +2 -2
- package/src/scan/fileUtils.js +2 -2
- package/src/scan/help.js +2 -1
- package/dist/commands/scan/sca/scaAnalysis.js +0 -157
- package/src/commands/scan/sca/scaAnalysis.js +0 -211
package/dist/cliConstants.js
CHANGED
|
@@ -296,10 +296,6 @@ const auditOptionDefinitions = [
|
|
|
296
296
|
'}: ' +
|
|
297
297
|
i18n.__('constantsIgnoreDev')
|
|
298
298
|
},
|
|
299
|
-
{
|
|
300
|
-
name: 'fingerprint',
|
|
301
|
-
type: Boolean
|
|
302
|
-
},
|
|
303
299
|
{
|
|
304
300
|
name: 'save',
|
|
305
301
|
alias: 's',
|
|
@@ -358,6 +354,14 @@ const auditOptionDefinitions = [
|
|
|
358
354
|
i18n.__('auditOptionsBranchSummary')
|
|
359
355
|
}
|
|
360
356
|
];
|
|
357
|
+
const fingerprintOptionDefinitions = [
|
|
358
|
+
...auditOptionDefinitions,
|
|
359
|
+
{
|
|
360
|
+
name: 'depth',
|
|
361
|
+
type: Number,
|
|
362
|
+
description: '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('depthOption')
|
|
363
|
+
}
|
|
364
|
+
];
|
|
361
365
|
const mainUsageGuide = commandLineUsage([
|
|
362
366
|
{
|
|
363
367
|
header: i18n.__('constantsHeader'),
|
|
@@ -379,7 +383,8 @@ const mainUsageGuide = commandLineUsage([
|
|
|
379
383
|
{ name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
|
|
380
384
|
{ name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
|
|
381
385
|
{ name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
|
|
382
|
-
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
|
|
386
|
+
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
|
|
387
|
+
{ name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
|
|
383
388
|
]
|
|
384
389
|
},
|
|
385
390
|
{
|
|
@@ -393,7 +398,8 @@ const mainUsageGuide = commandLineUsage([
|
|
|
393
398
|
]
|
|
394
399
|
},
|
|
395
400
|
commonHelpLinks()[0],
|
|
396
|
-
commonHelpLinks()[1]
|
|
401
|
+
commonHelpLinks()[1],
|
|
402
|
+
commonHelpLinks()[2]
|
|
397
403
|
]);
|
|
398
404
|
const mainDefinition = [{ name: 'command', defaultOption: true }];
|
|
399
405
|
module.exports = {
|
|
@@ -401,6 +407,7 @@ module.exports = {
|
|
|
401
407
|
mainUsageGuide,
|
|
402
408
|
mainDefinition,
|
|
403
409
|
scanOptionDefinitions,
|
|
410
|
+
fingerprintOptionDefinitions,
|
|
404
411
|
auditOptionDefinitions,
|
|
405
412
|
authOptionDefinitions,
|
|
406
413
|
configOptionDefinitions,
|
|
@@ -61,7 +61,8 @@ const auditUsageGuide = commandLineUsage([
|
|
|
61
61
|
optionList: constants.commandLineDefinitions.auditAdvancedOptionDefinitionsForHelp
|
|
62
62
|
},
|
|
63
63
|
commonHelpLinks()[0],
|
|
64
|
-
commonHelpLinks()[1]
|
|
64
|
+
commonHelpLinks()[1],
|
|
65
|
+
commonHelpLinks()[2]
|
|
65
66
|
]);
|
|
66
67
|
module.exports = {
|
|
67
68
|
auditUsageGuide
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const auditConfig = require('./auditConfig');
|
|
3
3
|
const { auditUsageGuide } = require('./help');
|
|
4
|
-
const scaController = require('
|
|
4
|
+
const scaController = require('../../scaAnalysis/scaAnalysis');
|
|
5
5
|
const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry');
|
|
6
6
|
const { postRunMessage } = require('../../common/commonHelp');
|
|
7
7
|
const processAudit = async (contrastConf, argvMain) => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const parsedCLIOptions = require('../../utils/parsedCLIOptions');
|
|
3
|
+
const constants = require('../../cliConstants');
|
|
4
|
+
const paramHandler = require('../../utils/paramsUtil/paramHandler');
|
|
5
|
+
const getFingerprintConfig = async (contrastConf, command, argv) => {
|
|
6
|
+
const fingerprintParameters = await parsedCLIOptions.getCommandLineArgsCustom(contrastConf, command, argv, constants.commandLineDefinitions.fingerprintOptionDefinitions);
|
|
7
|
+
const paramsAuth = paramHandler.getAuth(fingerprintParameters);
|
|
8
|
+
return { ...paramsAuth, ...fingerprintParameters };
|
|
9
|
+
};
|
|
10
|
+
module.exports = {
|
|
11
|
+
getFingerprintConfig
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const fingerprintConfig = require('./fingerprintConfig');
|
|
3
|
+
const autoDetection = require('../../scan/autoDetection');
|
|
4
|
+
const saveResults = require('../../scan/saveResults');
|
|
5
|
+
const processFingerprint = async (contrastConf, argvMain) => {
|
|
6
|
+
const config = await fingerprintConfig.getFingerprintConfig(contrastConf, 'fingerprint', argvMain);
|
|
7
|
+
let fingerprint = await autoDetection.autoDetectFingerprintInfo(config.file, config.depth);
|
|
8
|
+
let idArray = fingerprint.map(x => x.id);
|
|
9
|
+
await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json');
|
|
10
|
+
return console.log(idArray);
|
|
11
|
+
};
|
|
12
|
+
module.exports = {
|
|
13
|
+
processFingerprint
|
|
14
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { openLearnPage } = require('./learn');
|
|
3
|
+
async function processLearn() {
|
|
4
|
+
console.log('Opening develop central...');
|
|
5
|
+
console.log('If the page does not open you can open it directly via https://www.contrastsecurity.com/developer/learn');
|
|
6
|
+
return openLearnPage();
|
|
7
|
+
}
|
|
8
|
+
module.exports = {
|
|
9
|
+
processLearn
|
|
10
|
+
};
|
|
@@ -19,17 +19,24 @@ const commonHelpLinks = () => {
|
|
|
19
19
|
i18n.__('commonHelpLearnMoreEnterpriseHeader') +
|
|
20
20
|
i18n.__('commonHelpLearnMoreEnterpriseText')
|
|
21
21
|
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
content: [
|
|
25
|
+
i18n.__('commonHelpLearnHeader') + i18n.__('commonHelpLearnText')
|
|
26
|
+
]
|
|
22
27
|
}
|
|
23
28
|
];
|
|
24
29
|
};
|
|
25
30
|
const postRunMessage = commandName => {
|
|
26
31
|
console.log('\n' + chalk.underline.bold('Other Features:'));
|
|
27
32
|
if (commandName !== 'scan')
|
|
28
|
-
console.log("'contrast scan' to run
|
|
33
|
+
console.log("'contrast scan' to run Contrast's industry leading SAST scanner");
|
|
29
34
|
if (commandName !== 'audit')
|
|
30
35
|
console.log("'contrast audit' to find vulnerabilities in your open source dependencies");
|
|
31
36
|
if (commandName !== 'lambda')
|
|
32
37
|
console.log("'contrast lambda' to secure your AWS serverless functions");
|
|
38
|
+
if (commandName !== 'learn')
|
|
39
|
+
console.log("'contrast learn' launches Contrast's Secure Code Learning Hub.");
|
|
33
40
|
};
|
|
34
41
|
module.exports = {
|
|
35
42
|
commonHelpLinks,
|
|
@@ -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.21';
|
|
16
16
|
const TIMEOUT = 120000;
|
|
17
17
|
const HIGH_COLOUR = '#ff9900';
|
|
18
18
|
const CRITICAL_COLOUR = '#e35858';
|
|
@@ -121,6 +121,10 @@ const en_locales = () => {
|
|
|
121
121
|
versionName: 'version',
|
|
122
122
|
configName: 'config',
|
|
123
123
|
helpName: 'help',
|
|
124
|
+
learnName: 'learn',
|
|
125
|
+
helpLearnSummary: 'launches Contrast’s Secure Code Learning Hub.',
|
|
126
|
+
fingerprintName: 'assess repo to see how many languages it can detect. For use in pipeline only.',
|
|
127
|
+
depthOption: 'can set how deep in the file system the cli looks for language files',
|
|
124
128
|
scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
|
|
125
129
|
scanOptionsTimeoutSummary: 'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
|
|
126
130
|
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.',
|
|
@@ -219,7 +223,10 @@ const en_locales = () => {
|
|
|
219
223
|
commonHelpLearnMoreText: ' https://www.contrastsecurity.com/developer ',
|
|
220
224
|
commonHelpLearnMoreEnterpriseText: ' https://docs.contrastsecurity.com/en/run-contrast-cli.html ',
|
|
221
225
|
commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')('Join the discussion:'),
|
|
222
|
-
commonHelpJoinDiscussionText: ' https://
|
|
226
|
+
commonHelpJoinDiscussionText: ' https://www.contrastsecurity.com/developer/community',
|
|
227
|
+
commonHelpLearnHeader: chalk.hex('#ffe599')('\rWant to UP your game?') +
|
|
228
|
+
" type 'contrast learn'",
|
|
229
|
+
commonHelpLearnText: `\n🎓 Advance your security knowledge and become an ${chalk.hex('#ffd966')('All-star coder')} ⭐ with ${chalk.bold('Contrast Secure Code Learning Hub.')} 😺`,
|
|
223
230
|
authCommand: {
|
|
224
231
|
credentialsAccepted: {
|
|
225
232
|
title: 'Credentials accepted',
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const processAudit_1 = require("./commands/audit/processAudit");
|
|
|
9
9
|
const auth_1 = require("./commands/auth/auth");
|
|
10
10
|
const config_1 = require("./commands/config/config");
|
|
11
11
|
const processScan_1 = require("./commands/scan/processScan");
|
|
12
|
+
const processFingerprint_1 = require("./commands/fingerprint/processFingerprint");
|
|
12
13
|
const cliConstants_1 = __importDefault(require("./cliConstants"));
|
|
13
14
|
const constants_1 = require("./constants/constants");
|
|
14
15
|
const lambda_1 = require("./lambda/lambda");
|
|
@@ -16,6 +17,7 @@ const getConfig_1 = require("./utils/getConfig");
|
|
|
16
17
|
const versionChecker_1 = require("./common/versionChecker");
|
|
17
18
|
const errorHandling_1 = require("./common/errorHandling");
|
|
18
19
|
const telemetry_1 = require("./telemetry/telemetry");
|
|
20
|
+
const processLearn_1 = require("./commands/learn/processLearn");
|
|
19
21
|
const { commandLineDefinitions: { mainUsageGuide, mainDefinition } } = cliConstants_1.default;
|
|
20
22
|
const config = (0, getConfig_1.localConfig)(constants_1.APP_NAME, constants_1.APP_VERSION);
|
|
21
23
|
const getMainOption = () => {
|
|
@@ -64,6 +66,12 @@ const start = async () => {
|
|
|
64
66
|
if (command === 'audit') {
|
|
65
67
|
return await (0, processAudit_1.processAudit)(config, argvMain);
|
|
66
68
|
}
|
|
69
|
+
if (command === 'learn') {
|
|
70
|
+
return (0, processLearn_1.processLearn)();
|
|
71
|
+
}
|
|
72
|
+
if (command === 'fingerprint') {
|
|
73
|
+
return await (0, processFingerprint_1.processFingerprint)(config, argvMain);
|
|
74
|
+
}
|
|
67
75
|
if (command === 'help' ||
|
|
68
76
|
argvMain.includes('--help') ||
|
|
69
77
|
Object.keys(mainOptions).length === 0) {
|
package/dist/lambda/help.js
CHANGED
|
@@ -82,6 +82,7 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
|
|
|
82
82
|
]
|
|
83
83
|
},
|
|
84
84
|
(0, commonHelp_1.commonHelpLinks)()[0],
|
|
85
|
-
(0, commonHelp_1.commonHelpLinks)()[1]
|
|
85
|
+
(0, commonHelp_1.commonHelpLinks)()[1],
|
|
86
|
+
(0, commonHelp_1.commonHelpLinks)()[2]
|
|
86
87
|
]);
|
|
87
88
|
exports.lambdaUsageGuide = lambdaUsageGuide;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET } } = require('../constants/constants');
|
|
3
|
+
const { pollForSnapshotCompletion } = require('../audit/languageAnalysisEngine/sendSnapshot');
|
|
4
|
+
const { returnOra, startSpinner, succeedSpinner } = require('../utils/oraWrapper');
|
|
5
|
+
const { vulnerabilityReportV2 } = require('../audit/report/reportingFeature');
|
|
6
|
+
const autoDetection = require('../scan/autoDetection');
|
|
7
|
+
const treeUpload = require('./common/treeUpload');
|
|
8
|
+
const auditController = require('../commands/audit/auditController');
|
|
9
|
+
const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const i18n = require('i18n');
|
|
12
|
+
const auditSave = require('../audit/save');
|
|
13
|
+
const { auditUsageGuide } = require('../commands/audit/help');
|
|
14
|
+
const repoMode = require('./repoMode');
|
|
15
|
+
const { dotNetAnalysis } = require('./dotnet');
|
|
16
|
+
const { goAnalysis } = require('./go/goAnalysis');
|
|
17
|
+
const { phpAnalysis } = require('./php');
|
|
18
|
+
const { rubyAnalysis } = require('./ruby');
|
|
19
|
+
const { pythonAnalysis } = require('./python');
|
|
20
|
+
const javaAnalysis = require('./java');
|
|
21
|
+
const jsAnalysis = require('./javascript');
|
|
22
|
+
const auditReport = require('./common/auditReport');
|
|
23
|
+
const scaUpload = require('./common/scaServicesUpload');
|
|
24
|
+
const settingsHelper = require('../utils/settingsHelper');
|
|
25
|
+
const chalk = require('chalk');
|
|
26
|
+
const saveResults = require('../scan/saveResults');
|
|
27
|
+
const { convertGenericToTypedReportModelSca } = require('./common/utils/reportUtilsSca');
|
|
28
|
+
const processSca = async (config) => {
|
|
29
|
+
config = await settingsHelper.getSettings(config);
|
|
30
|
+
const startTime = performance.now();
|
|
31
|
+
let filesFound;
|
|
32
|
+
if (config.help) {
|
|
33
|
+
console.log(auditUsageGuide);
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
const projectStats = await rootFile.getProjectStats(config.file);
|
|
37
|
+
let pathWithFile = projectStats.isFile();
|
|
38
|
+
config.fileName = config.file;
|
|
39
|
+
config.file = pathWithFile
|
|
40
|
+
? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
|
|
41
|
+
: config.file;
|
|
42
|
+
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file);
|
|
43
|
+
autoDetection.dealWithMultiJava(filesFound);
|
|
44
|
+
if (filesFound.length > 1 && pathWithFile) {
|
|
45
|
+
filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
|
|
46
|
+
}
|
|
47
|
+
let messageToSend = undefined;
|
|
48
|
+
if (filesFound.length === 1) {
|
|
49
|
+
switch (Object.keys(filesFound[0])[0]) {
|
|
50
|
+
case JAVA:
|
|
51
|
+
config.language = JAVA;
|
|
52
|
+
if (config.mode === 'repo') {
|
|
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
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
case JAVASCRIPT:
|
|
65
|
+
messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
|
|
66
|
+
config.language = NODE;
|
|
67
|
+
break;
|
|
68
|
+
case PYTHON:
|
|
69
|
+
messageToSend = pythonAnalysis(config, filesFound[0]);
|
|
70
|
+
config.language = PYTHON;
|
|
71
|
+
break;
|
|
72
|
+
case RUBY:
|
|
73
|
+
messageToSend = rubyAnalysis(config, filesFound[0]);
|
|
74
|
+
config.language = RUBY;
|
|
75
|
+
break;
|
|
76
|
+
case PHP:
|
|
77
|
+
messageToSend = phpAnalysis(config, filesFound[0]);
|
|
78
|
+
config.language = PHP;
|
|
79
|
+
break;
|
|
80
|
+
case GO:
|
|
81
|
+
messageToSend = goAnalysis(config, filesFound[0]);
|
|
82
|
+
config.language = GO;
|
|
83
|
+
break;
|
|
84
|
+
case DOTNET:
|
|
85
|
+
if (config.experimental) {
|
|
86
|
+
console.log(`${chalk.bold('\n.NET project found\n')} Language type is unsupported.`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
messageToSend = dotNetAnalysis(config, filesFound[0]);
|
|
91
|
+
config.language = DOTNET;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
default:
|
|
95
|
+
console.log('No supported language detected in project path');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!config.applicationId) {
|
|
99
|
+
config.applicationId = await auditController.dealWithNoAppId(config);
|
|
100
|
+
}
|
|
101
|
+
if (config.experimental) {
|
|
102
|
+
console.log('');
|
|
103
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
|
|
104
|
+
startSpinner(reportSpinner);
|
|
105
|
+
const { reportArray, reportId } = await scaUpload.scaTreeUpload(messageToSend, config);
|
|
106
|
+
const reportModelLibraryList = convertGenericToTypedReportModelSca(reportArray);
|
|
107
|
+
auditReport.processAuditReport(config, reportModelLibraryList);
|
|
108
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
|
|
109
|
+
if (config.save !== undefined) {
|
|
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 -----`);
|
|
118
|
+
}
|
|
119
|
+
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 -----`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
if (filesFound.length === 0) {
|
|
140
|
+
console.log(i18n.__('languageAnalysisNoLanguage'));
|
|
141
|
+
console.log(i18n.__('languageAnalysisNoLanguageHelpLine'));
|
|
142
|
+
throw new Error();
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log(chalk.bold(`\nMultiple language files detected \n`));
|
|
146
|
+
filesFound.forEach(file => {
|
|
147
|
+
console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0]);
|
|
148
|
+
});
|
|
149
|
+
throw new Error(`Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
module.exports = {
|
|
154
|
+
processSca
|
|
155
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const i18n = require('i18n');
|
|
3
3
|
const fileFinder = require('./fileUtils');
|
|
4
|
-
const autoDetectFingerprintInfo = async (filePath) => {
|
|
5
|
-
let complexObj = await fileFinder.findAllFiles(filePath);
|
|
4
|
+
const autoDetectFingerprintInfo = async (filePath, depth) => {
|
|
5
|
+
let complexObj = await fileFinder.findAllFiles(filePath, depth);
|
|
6
6
|
let result = [];
|
|
7
7
|
let count = 0;
|
|
8
8
|
complexObj.forEach(i => {
|
package/dist/scan/fileUtils.js
CHANGED
|
@@ -10,7 +10,7 @@ const findFile = async () => {
|
|
|
10
10
|
onlyFiles: true
|
|
11
11
|
});
|
|
12
12
|
};
|
|
13
|
-
const findAllFiles = async (filePath) => {
|
|
13
|
+
const findAllFiles = async (filePath, depth = 2) => {
|
|
14
14
|
const result = await fg([
|
|
15
15
|
'**/pom.xml',
|
|
16
16
|
'**/build.gradle',
|
|
@@ -22,7 +22,7 @@ const findAllFiles = async (filePath) => {
|
|
|
22
22
|
'**/go.mod'
|
|
23
23
|
], {
|
|
24
24
|
dot: false,
|
|
25
|
-
deep:
|
|
25
|
+
deep: depth,
|
|
26
26
|
onlyFiles: true,
|
|
27
27
|
absolute: true,
|
|
28
28
|
cwd: filePath ? filePath : process.cwd()
|
package/dist/scan/help.js
CHANGED
|
@@ -43,7 +43,8 @@ const scanUsageGuide = commandLineUsage([
|
|
|
43
43
|
optionList: constants.commandLineDefinitions.scanAdvancedOptionDefinitionsForHelp
|
|
44
44
|
},
|
|
45
45
|
commonHelpLinks()[0],
|
|
46
|
-
commonHelpLinks()[1]
|
|
46
|
+
commonHelpLinks()[1],
|
|
47
|
+
commonHelpLinks()[2]
|
|
47
48
|
]);
|
|
48
49
|
module.exports = {
|
|
49
50
|
scanUsageGuide
|
package/package.json
CHANGED
package/src/cliConstants.js
CHANGED
|
@@ -337,10 +337,6 @@ const auditOptionDefinitions = [
|
|
|
337
337
|
'}: ' +
|
|
338
338
|
i18n.__('constantsIgnoreDev')
|
|
339
339
|
},
|
|
340
|
-
{
|
|
341
|
-
name: 'fingerprint',
|
|
342
|
-
type: Boolean
|
|
343
|
-
},
|
|
344
340
|
{
|
|
345
341
|
name: 'save',
|
|
346
342
|
alias: 's',
|
|
@@ -405,6 +401,16 @@ const auditOptionDefinitions = [
|
|
|
405
401
|
}
|
|
406
402
|
]
|
|
407
403
|
|
|
404
|
+
const fingerprintOptionDefinitions = [
|
|
405
|
+
...auditOptionDefinitions,
|
|
406
|
+
{
|
|
407
|
+
name: 'depth',
|
|
408
|
+
type: Number,
|
|
409
|
+
description:
|
|
410
|
+
'{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('depthOption')
|
|
411
|
+
}
|
|
412
|
+
]
|
|
413
|
+
|
|
408
414
|
const mainUsageGuide = commandLineUsage([
|
|
409
415
|
{
|
|
410
416
|
header: i18n.__('constantsHeader'),
|
|
@@ -426,7 +432,8 @@ const mainUsageGuide = commandLineUsage([
|
|
|
426
432
|
{ name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
|
|
427
433
|
{ name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
|
|
428
434
|
{ name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
|
|
429
|
-
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
|
|
435
|
+
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
|
|
436
|
+
{ name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
|
|
430
437
|
]
|
|
431
438
|
},
|
|
432
439
|
{
|
|
@@ -440,7 +447,8 @@ const mainUsageGuide = commandLineUsage([
|
|
|
440
447
|
]
|
|
441
448
|
},
|
|
442
449
|
commonHelpLinks()[0],
|
|
443
|
-
commonHelpLinks()[1]
|
|
450
|
+
commonHelpLinks()[1],
|
|
451
|
+
commonHelpLinks()[2]
|
|
444
452
|
])
|
|
445
453
|
|
|
446
454
|
const mainDefinition = [{ name: 'command', defaultOption: true }]
|
|
@@ -450,6 +458,7 @@ module.exports = {
|
|
|
450
458
|
mainUsageGuide,
|
|
451
459
|
mainDefinition,
|
|
452
460
|
scanOptionDefinitions,
|
|
461
|
+
fingerprintOptionDefinitions,
|
|
453
462
|
auditOptionDefinitions,
|
|
454
463
|
authOptionDefinitions,
|
|
455
464
|
configOptionDefinitions,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const auditConfig = require('./auditConfig')
|
|
2
2
|
const { auditUsageGuide } = require('./help')
|
|
3
|
-
const scaController = require('
|
|
3
|
+
const scaController = require('../../scaAnalysis/scaAnalysis')
|
|
4
4
|
const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry')
|
|
5
5
|
const { postRunMessage } = require('../../common/commonHelp')
|
|
6
6
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const parsedCLIOptions = require('../../utils/parsedCLIOptions')
|
|
2
|
+
const constants = require('../../cliConstants')
|
|
3
|
+
const paramHandler = require('../../utils/paramsUtil/paramHandler')
|
|
4
|
+
|
|
5
|
+
const getFingerprintConfig = async (contrastConf, command, argv) => {
|
|
6
|
+
const fingerprintParameters = await parsedCLIOptions.getCommandLineArgsCustom(
|
|
7
|
+
contrastConf,
|
|
8
|
+
command,
|
|
9
|
+
argv,
|
|
10
|
+
constants.commandLineDefinitions.fingerprintOptionDefinitions
|
|
11
|
+
)
|
|
12
|
+
const paramsAuth = paramHandler.getAuth(fingerprintParameters)
|
|
13
|
+
|
|
14
|
+
return { ...paramsAuth, ...fingerprintParameters }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
getFingerprintConfig
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const fingerprintConfig = require('./fingerprintConfig')
|
|
2
|
+
const autoDetection = require('../../scan/autoDetection')
|
|
3
|
+
const saveResults = require('../../scan/saveResults')
|
|
4
|
+
const processFingerprint = async (contrastConf, argvMain) => {
|
|
5
|
+
const config = await fingerprintConfig.getFingerprintConfig(
|
|
6
|
+
contrastConf,
|
|
7
|
+
'fingerprint',
|
|
8
|
+
argvMain
|
|
9
|
+
)
|
|
10
|
+
let fingerprint = await autoDetection.autoDetectFingerprintInfo(
|
|
11
|
+
config.file,
|
|
12
|
+
config.depth
|
|
13
|
+
)
|
|
14
|
+
let idArray = fingerprint.map(x => x.id)
|
|
15
|
+
await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json')
|
|
16
|
+
return console.log(idArray)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
processFingerprint
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { openLearnPage } = require('./learn')
|
|
2
|
+
|
|
3
|
+
async function processLearn() {
|
|
4
|
+
console.log('Opening develop central...')
|
|
5
|
+
console.log(
|
|
6
|
+
'If the page does not open you can open it directly via https://www.contrastsecurity.com/developer/learn'
|
|
7
|
+
)
|
|
8
|
+
return openLearnPage()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
processLearn
|
|
13
|
+
}
|
package/src/common/commonHelp.js
CHANGED
|
@@ -19,6 +19,11 @@ const commonHelpLinks = () => {
|
|
|
19
19
|
i18n.__('commonHelpLearnMoreEnterpriseHeader') +
|
|
20
20
|
i18n.__('commonHelpLearnMoreEnterpriseText')
|
|
21
21
|
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
content: [
|
|
25
|
+
i18n.__('commonHelpLearnHeader') + i18n.__('commonHelpLearnText')
|
|
26
|
+
]
|
|
22
27
|
}
|
|
23
28
|
]
|
|
24
29
|
}
|
|
@@ -27,7 +32,7 @@ const postRunMessage = commandName => {
|
|
|
27
32
|
console.log('\n' + chalk.underline.bold('Other Features:'))
|
|
28
33
|
if (commandName !== 'scan')
|
|
29
34
|
console.log(
|
|
30
|
-
"'contrast scan' to run
|
|
35
|
+
"'contrast scan' to run Contrast's industry leading SAST scanner"
|
|
31
36
|
)
|
|
32
37
|
if (commandName !== 'audit')
|
|
33
38
|
console.log(
|
|
@@ -35,6 +40,11 @@ const postRunMessage = commandName => {
|
|
|
35
40
|
)
|
|
36
41
|
if (commandName !== 'lambda')
|
|
37
42
|
console.log("'contrast lambda' to secure your AWS serverless functions")
|
|
43
|
+
|
|
44
|
+
if (commandName !== 'learn')
|
|
45
|
+
console.log(
|
|
46
|
+
"'contrast learn' launches Contrast's Secure Code Learning Hub."
|
|
47
|
+
)
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
module.exports = {
|
package/src/constants/locales.js
CHANGED
|
@@ -177,6 +177,12 @@ const en_locales = () => {
|
|
|
177
177
|
versionName: 'version',
|
|
178
178
|
configName: 'config',
|
|
179
179
|
helpName: 'help',
|
|
180
|
+
learnName: 'learn',
|
|
181
|
+
helpLearnSummary: 'launches Contrast’s Secure Code Learning Hub.',
|
|
182
|
+
fingerprintName:
|
|
183
|
+
'assess repo to see how many languages it can detect. For use in pipeline only.',
|
|
184
|
+
depthOption:
|
|
185
|
+
'can set how deep in the file system the cli looks for language files',
|
|
180
186
|
scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
|
|
181
187
|
scanOptionsTimeoutSummary:
|
|
182
188
|
'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
|
|
@@ -320,7 +326,16 @@ const en_locales = () => {
|
|
|
320
326
|
commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')(
|
|
321
327
|
'Join the discussion:'
|
|
322
328
|
),
|
|
323
|
-
commonHelpJoinDiscussionText:
|
|
329
|
+
commonHelpJoinDiscussionText:
|
|
330
|
+
' https://www.contrastsecurity.com/developer/community',
|
|
331
|
+
commonHelpLearnHeader:
|
|
332
|
+
chalk.hex('#ffe599')('\rWant to UP your game?') +
|
|
333
|
+
" type 'contrast learn'",
|
|
334
|
+
commonHelpLearnText: `\n🎓 Advance your security knowledge and become an ${chalk.hex(
|
|
335
|
+
'#ffd966'
|
|
336
|
+
)('All-star coder')} ⭐ with ${chalk.bold(
|
|
337
|
+
'Contrast Secure Code Learning Hub.'
|
|
338
|
+
)} 😺`,
|
|
324
339
|
authCommand: {
|
|
325
340
|
credentialsAccepted: {
|
|
326
341
|
title: 'Credentials accepted',
|