@contrast/contrast 1.0.11 → 1.0.12
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/{languageAnalysisEngine/report → report}/commonReportingFunctions.js +17 -7
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportGuidanceModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportListModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/reportingFeature.js +2 -2
- package/dist/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.js +2 -2
- package/dist/commands/audit/help.js +3 -1
- package/dist/commands/scan/sca/scaAnalysis.js +2 -2
- package/dist/common/commonHelp.js +19 -0
- package/dist/common/versionChecker.js +4 -2
- package/dist/constants/constants.js +2 -2
- package/dist/constants/locales.js +7 -0
- package/dist/constants.js +3 -4
- package/dist/lambda/help.js +2 -3
- package/dist/scaAnalysis/php/analysis.js +1 -1
- package/dist/scaAnalysis/php/index.js +12 -6
- package/dist/scaAnalysis/php/phpNewServicesMapper.js +62 -0
- package/dist/scan/help.js +2 -3
- package/dist/scan/scanConfig.js +1 -1
- package/dist/scan/scanResults.js +8 -1
- package/dist/utils/getConfig.js +2 -4
- package/package.json +4 -2
- package/src/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.ts +23 -5
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportGuidanceModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportListModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/reportingFeature.ts +2 -2
- package/src/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.ts +2 -2
- package/src/commands/audit/help.ts +3 -1
- package/src/commands/scan/sca/scaAnalysis.js +2 -2
- package/src/common/HTTPClient.js +1 -0
- package/src/common/commonHelp.ts +13 -0
- package/src/common/versionChecker.ts +4 -4
- package/src/constants/constants.js +2 -2
- package/src/constants/locales.js +9 -0
- package/src/constants.js +3 -5
- package/src/lambda/help.ts +2 -3
- package/src/scaAnalysis/common/treeUpload.js +1 -0
- package/src/scaAnalysis/php/analysis.js +1 -1
- package/src/scaAnalysis/php/index.js +12 -6
- package/src/scaAnalysis/php/phpNewServicesMapper.js +77 -0
- package/src/scan/help.js +2 -3
- package/src/scan/scanConfig.js +1 -1
- package/src/scan/scanResults.js +7 -1
- package/src/utils/getConfig.ts +2 -9
|
@@ -3,23 +3,29 @@ 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.getNumOfAndSeverityType = exports.buildFormattedHeaderNum = exports.gatherRemediationAdvice = exports.buildBody = exports.buildHeader = exports.printFormattedOutput = exports.printVulnerabilityResponse = exports.getReport = exports.
|
|
7
|
-
const commonApi_1 = require("
|
|
6
|
+
exports.getNumOfAndSeverityType = exports.buildFormattedHeaderNum = exports.gatherRemediationAdvice = exports.buildBody = exports.buildHeader = exports.printFormattedOutput = exports.printVulnerabilityResponse = exports.getReport = exports.createSummaryMessageBottom = exports.createSummaryMessageTop = void 0;
|
|
7
|
+
const commonApi_1 = require("../../utils/commonApi");
|
|
8
8
|
const reportListModel_1 = require("./models/reportListModel");
|
|
9
9
|
const lodash_1 = require("lodash");
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const reportUtils_1 = require("./utils/reportUtils");
|
|
12
12
|
const severityCountModel_1 = require("./models/severityCountModel");
|
|
13
13
|
const reportOutputModel_1 = require("./models/reportOutputModel");
|
|
14
|
-
const constants_1 = require("
|
|
14
|
+
const constants_1 = require("../../constants/constants");
|
|
15
15
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
16
16
|
const reportGuidanceModel_1 = require("./models/reportGuidanceModel");
|
|
17
|
-
const
|
|
17
|
+
const createSummaryMessageTop = (numberOfVulnerableLibraries, numberOfCves) => {
|
|
18
18
|
numberOfVulnerableLibraries === 1
|
|
19
19
|
? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
|
|
20
20
|
: console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`);
|
|
21
21
|
};
|
|
22
|
-
exports.
|
|
22
|
+
exports.createSummaryMessageTop = createSummaryMessageTop;
|
|
23
|
+
const createSummaryMessageBottom = (numberOfVulnerableLibraries) => {
|
|
24
|
+
numberOfVulnerableLibraries === 1
|
|
25
|
+
? console.log(`Found 1 vulnerable library`)
|
|
26
|
+
: console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries`);
|
|
27
|
+
};
|
|
28
|
+
exports.createSummaryMessageBottom = createSummaryMessageBottom;
|
|
23
29
|
const getReport = async (config, reportId) => {
|
|
24
30
|
const client = (0, commonApi_1.getHttpClient)(config);
|
|
25
31
|
return client
|
|
@@ -48,7 +54,7 @@ const printVulnerabilityResponse = (config, vulnerableLibraries, numberOfVulnera
|
|
|
48
54
|
};
|
|
49
55
|
exports.printVulnerabilityResponse = printVulnerabilityResponse;
|
|
50
56
|
const printFormattedOutput = (config, libraries, numberOfVulnerableLibraries, numberOfCves, guidance) => {
|
|
51
|
-
(0, exports.
|
|
57
|
+
(0, exports.createSummaryMessageTop)(numberOfVulnerableLibraries, numberOfCves);
|
|
52
58
|
console.log();
|
|
53
59
|
const report = new reportListModel_1.ReportList();
|
|
54
60
|
for (const library of libraries) {
|
|
@@ -100,9 +106,13 @@ const printFormattedOutput = (config, libraries, numberOfVulnerableLibraries, nu
|
|
|
100
106
|
console.log(reportOutputModel.header.vulnMessage, reportOutputModel.header.introducesMessage);
|
|
101
107
|
console.log(table.toString() + '\n');
|
|
102
108
|
}
|
|
103
|
-
(0, exports.
|
|
109
|
+
(0, exports.createSummaryMessageBottom)(numberOfVulnerableLibraries);
|
|
104
110
|
const { criticalMessage, highMessage, mediumMessage, lowMessage, noteMessage } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst);
|
|
105
111
|
console.log(`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`);
|
|
112
|
+
if (config.host !== constants_1.CE_URL) {
|
|
113
|
+
console.log('\n' + chalk_1.default.bold('View your full dependency tree in Contrast:'));
|
|
114
|
+
console.log(`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
|
|
115
|
+
}
|
|
106
116
|
};
|
|
107
117
|
exports.printFormattedOutput = printFormattedOutput;
|
|
108
118
|
function buildHeader(highestSeverity, contrastHeaderNum, libraryName, version, numOfCVEs) {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -31,9 +31,9 @@ const commonReportingFunctions_1 = require("./commonReportingFunctions");
|
|
|
31
31
|
const reportUtils_1 = require("./utils/reportUtils");
|
|
32
32
|
const i18n_1 = __importDefault(require("i18n"));
|
|
33
33
|
const chalk_1 = __importDefault(require("chalk"));
|
|
34
|
-
const constants = __importStar(require("
|
|
34
|
+
const constants = __importStar(require("../../constants/constants"));
|
|
35
35
|
const severityCountModel_1 = require("./models/severityCountModel");
|
|
36
|
-
const common = __importStar(require("
|
|
36
|
+
const common = __importStar(require("../../common/fail"));
|
|
37
37
|
function convertKeysToStandardFormat(config, guidance) {
|
|
38
38
|
let convertedGuidance = guidance;
|
|
39
39
|
switch (config.language) {
|
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.countVulnerableLibrariesBySeverity = exports.findNameAndVersion = exports.severityCountSingleCVE = exports.severityCountAllCVEs = exports.severityCountAllLibraries = exports.convertGenericToTypedLibraryVulns = exports.findCVESeverity = exports.findCVESeveritiesAndOrderByHighestPriority = exports.findHighestSeverityCVE = void 0;
|
|
7
7
|
const reportLibraryModel_1 = require("../models/reportLibraryModel");
|
|
8
8
|
const reportSeverityModel_1 = require("../models/reportSeverityModel");
|
|
9
|
-
const constants_1 = __importDefault(require("
|
|
10
|
-
const constants_2 = require("
|
|
9
|
+
const constants_1 = __importDefault(require("../../../constants/constants"));
|
|
10
|
+
const constants_2 = require("../../../constants/constants");
|
|
11
11
|
const lodash_1 = require("lodash");
|
|
12
12
|
const severityCountModel_1 = require("../models/severityCountModel");
|
|
13
13
|
const { supportedLanguages: { GO } } = constants_1.default;
|
|
@@ -7,6 +7,7 @@ exports.auditUsageGuide = void 0;
|
|
|
7
7
|
const command_line_usage_1 = __importDefault(require("command-line-usage"));
|
|
8
8
|
const i18n_1 = __importDefault(require("i18n"));
|
|
9
9
|
const constants_1 = __importDefault(require("../../constants"));
|
|
10
|
+
const commonHelp_1 = require("../../common/commonHelp");
|
|
10
11
|
const auditUsageGuide = (0, command_line_usage_1.default)([
|
|
11
12
|
{
|
|
12
13
|
header: i18n_1.default.__('auditHeader'),
|
|
@@ -53,6 +54,7 @@ const auditUsageGuide = (0, command_line_usage_1.default)([
|
|
|
53
54
|
'app-groups',
|
|
54
55
|
'metadata'
|
|
55
56
|
]
|
|
56
|
-
}
|
|
57
|
+
},
|
|
58
|
+
(0, commonHelp_1.commonHelpLinks)()
|
|
57
59
|
]);
|
|
58
60
|
exports.auditUsageGuide = auditUsageGuide;
|
|
@@ -12,7 +12,7 @@ const javascriptAnalysis = require('../../../scaAnalysis/javascript');
|
|
|
12
12
|
const { pollForSnapshotCompletition } = require('../../../audit/languageAnalysisEngine/sendSnapshot');
|
|
13
13
|
const { returnOra, startSpinner, succeedSpinner } = require('../../../utils/oraWrapper');
|
|
14
14
|
const i18n = require('i18n');
|
|
15
|
-
const { vulnerabilityReportV2 } = require('../../../audit/
|
|
15
|
+
const { vulnerabilityReportV2 } = require('../../../audit/report/reportingFeature');
|
|
16
16
|
const auditSave = require('../../../audit/save');
|
|
17
17
|
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet');
|
|
18
18
|
const { auditUsageGuide } = require('../../audit/help');
|
|
@@ -54,7 +54,7 @@ const processSca = async (config) => {
|
|
|
54
54
|
messageToSend = rubyAnalysis(config, filesFound[0]);
|
|
55
55
|
config.language = RUBY;
|
|
56
56
|
break;
|
|
57
|
-
case
|
|
57
|
+
case PHP:
|
|
58
58
|
messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0]);
|
|
59
59
|
config.language = PHP;
|
|
60
60
|
break;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.commonHelpLinks = void 0;
|
|
7
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
8
|
+
function commonHelpLinks() {
|
|
9
|
+
return {
|
|
10
|
+
header: i18n_1.default.__('commonHelpHeader'),
|
|
11
|
+
content: [
|
|
12
|
+
i18n_1.default.__('commonHelpCheckOutHeader') + i18n_1.default.__('commonHelpCheckOutText'),
|
|
13
|
+
i18n_1.default.__('commonHelpLearnMoreHeader') + i18n_1.default.__('commonHelpLearnMoreText'),
|
|
14
|
+
i18n_1.default.__('commonHelpJoinDiscussionHeader') +
|
|
15
|
+
i18n_1.default.__('commonHelpJoinDiscussionText')
|
|
16
|
+
]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
exports.commonHelpLinks = commonHelpLinks;
|
|
@@ -23,8 +23,10 @@ const getLatestVersion = async (config) => {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
async function findLatestCLIVersion(config) {
|
|
26
|
-
const
|
|
27
|
-
|
|
26
|
+
const isCI = process.env.CONTRAST_CODESEC_CI
|
|
27
|
+
? JSON.parse(process.env.CONTRAST_CODESEC_CI)
|
|
28
|
+
: false;
|
|
29
|
+
if (!isCI) {
|
|
28
30
|
let latestCLIVersion = await getLatestVersion(config);
|
|
29
31
|
latestCLIVersion = latestCLIVersion.substring(8);
|
|
30
32
|
if (semver_1.default.lt(constants_1.APP_VERSION, latestCLIVersion)) {
|
|
@@ -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.12';
|
|
16
16
|
const TIMEOUT = 120000;
|
|
17
17
|
const HIGH_COLOUR = '#ff9900';
|
|
18
18
|
const CRITICAL_COLOUR = '#e35858';
|
|
@@ -29,7 +29,7 @@ const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com';
|
|
|
29
29
|
const SARIF_FILE = 'SARIF';
|
|
30
30
|
const SBOM_CYCLONE_DX_FILE = 'cyclonedx';
|
|
31
31
|
const SBOM_SPDX_FILE = 'spdx';
|
|
32
|
-
const CE_URL = 'https://ce.contrastsecurity.com
|
|
32
|
+
const CE_URL = 'https://ce.contrastsecurity.com';
|
|
33
33
|
module.exports = {
|
|
34
34
|
supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
|
|
35
35
|
supportedLanguagesScan: { JAVASCRIPT, DOTNET, JAVA },
|
|
@@ -295,6 +295,13 @@ const en_locales = () => {
|
|
|
295
295
|
auditReportFailureMessage: 'Unable to generate library report',
|
|
296
296
|
auditSCAAnalysisBegins: 'Contrast SCA audit started',
|
|
297
297
|
auditSCAAnalysisComplete: 'Contrast audit complete',
|
|
298
|
+
commonHelpHeader: 'Need More Help?',
|
|
299
|
+
commonHelpCheckOutHeader: chalk.hex('#9DC184')('Check out:'),
|
|
300
|
+
commonHelpCheckOutText: ' https://support.contrastsecurity.com',
|
|
301
|
+
commonHelpLearnMoreHeader: chalk.hex('#9DC184')('Learn more at:'),
|
|
302
|
+
commonHelpLearnMoreText: ' https://developer.contrastsecurity.com',
|
|
303
|
+
commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')('Join the discussion:'),
|
|
304
|
+
commonHelpJoinDiscussionText: ' https://dev.to/codesec',
|
|
298
305
|
...lambda
|
|
299
306
|
};
|
|
300
307
|
};
|
package/dist/constants.js
CHANGED
|
@@ -3,6 +3,7 @@ const commandLineUsage = require('command-line-usage');
|
|
|
3
3
|
const i18n = require('i18n');
|
|
4
4
|
const { en_locales } = require('./constants/locales.js');
|
|
5
5
|
const { parseSeverity } = require('./common/fail');
|
|
6
|
+
const { commonHelpLinks } = require('./common/commonHelp');
|
|
6
7
|
i18n.configure({
|
|
7
8
|
staticCatalog: {
|
|
8
9
|
en: en_locales()
|
|
@@ -366,15 +367,13 @@ const mainUsageGuide = commandLineUsage([
|
|
|
366
367
|
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
|
|
367
368
|
]
|
|
368
369
|
},
|
|
369
|
-
{
|
|
370
|
-
content: '{underline https://developer.contrastsecurity.com/} \n For technical support head to {underline https://support.contrastsecurity.com}'
|
|
371
|
-
},
|
|
372
370
|
{
|
|
373
371
|
header: i18n.__('configHeader2'),
|
|
374
372
|
content: [
|
|
375
373
|
{ name: i18n.__('clearHeader'), summary: i18n.__('clearContent') }
|
|
376
374
|
]
|
|
377
|
-
}
|
|
375
|
+
},
|
|
376
|
+
commonHelpLinks()
|
|
378
377
|
]);
|
|
379
378
|
const mainDefinition = [{ name: 'command', defaultOption: true }];
|
|
380
379
|
module.exports = {
|
package/dist/lambda/help.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.lambdaUsageGuide = void 0;
|
|
7
7
|
const command_line_usage_1 = __importDefault(require("command-line-usage"));
|
|
8
8
|
const i18n_1 = __importDefault(require("i18n"));
|
|
9
|
+
const commonHelp_1 = require("../common/commonHelp");
|
|
9
10
|
const lambdaUsageGuide = (0, command_line_usage_1.default)([
|
|
10
11
|
{
|
|
11
12
|
header: i18n_1.default.__('lambdaHeader'),
|
|
@@ -80,8 +81,6 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
|
|
|
80
81
|
{ name: i18n_1.default.__('lambdaHelpOption'), summary: i18n_1.default.__('helpSummary') }
|
|
81
82
|
]
|
|
82
83
|
},
|
|
83
|
-
|
|
84
|
-
content: '{underline https://www.contrastsecurity.com/developer/codesec}'
|
|
85
|
-
}
|
|
84
|
+
(0, commonHelp_1.commonHelpLinks)()
|
|
86
85
|
]);
|
|
87
86
|
exports.lambdaUsageGuide = lambdaUsageGuide;
|
|
@@ -5,7 +5,7 @@ const _ = require('lodash');
|
|
|
5
5
|
const readFile = (config, nameOfFile) => {
|
|
6
6
|
if (config.file) {
|
|
7
7
|
try {
|
|
8
|
-
return fs.readFileSync(config.file + '/' + nameOfFile);
|
|
8
|
+
return fs.readFileSync(config.file + '/' + nameOfFile, 'utf8');
|
|
9
9
|
}
|
|
10
10
|
catch (error) {
|
|
11
11
|
console.log('Unable to find file');
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const { readFile, parseProjectFiles } = require('./analysis');
|
|
3
3
|
const { createPhpTSMessage } = require('../common/formatMessage');
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper');
|
|
5
|
+
const phpAnalysis = config => {
|
|
6
|
+
let analysis = readFiles(config);
|
|
7
|
+
if (config.experimental) {
|
|
8
|
+
return parsePHPLockFileForScaServices(analysis.rawLockFileContents);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
const phpDep = parseProjectFiles(analysis);
|
|
12
|
+
return createPhpTSMessage(phpDep);
|
|
13
|
+
}
|
|
8
14
|
};
|
|
9
|
-
const readFiles =
|
|
15
|
+
const readFiles = config => {
|
|
10
16
|
let php = {};
|
|
11
17
|
php.composerJSON = JSON.parse(readFile(config, 'composer.json'));
|
|
12
18
|
php.rawLockFileContents = JSON.parse(readFile(config, 'composer.lock'));
|
|
13
19
|
return php;
|
|
14
20
|
};
|
|
15
21
|
module.exports = {
|
|
16
|
-
phpAnalysis
|
|
22
|
+
phpAnalysis: phpAnalysis
|
|
17
23
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { keyBy, merge } = require('lodash');
|
|
3
|
+
const parsePHPLockFileForScaServices = phpLockFile => {
|
|
4
|
+
const packages = keyBy(phpLockFile.packages, 'name');
|
|
5
|
+
const packagesDev = keyBy(phpLockFile['packages-dev'], 'name');
|
|
6
|
+
return merge(buildDepTree(packages, true), buildDepTree(packagesDev, false));
|
|
7
|
+
};
|
|
8
|
+
const buildDepTree = (packages, isProduction) => {
|
|
9
|
+
const dependencyTree = {};
|
|
10
|
+
for (const packagesKey in packages) {
|
|
11
|
+
const currentObj = packages[packagesKey];
|
|
12
|
+
const { group, name } = findGroupAndName(currentObj.name);
|
|
13
|
+
const key = `${group}/${name}@${currentObj.version}`;
|
|
14
|
+
dependencyTree[key] = {
|
|
15
|
+
group: group,
|
|
16
|
+
name: name,
|
|
17
|
+
version: currentObj.version,
|
|
18
|
+
directDependency: true,
|
|
19
|
+
isProduction: isProduction,
|
|
20
|
+
dependencies: []
|
|
21
|
+
};
|
|
22
|
+
const mergedChildDeps = merge(buildSubDepsIntoFlatStructure(currentObj.require), buildSubDepsIntoFlatStructure(currentObj['require-dev']));
|
|
23
|
+
for (const childKey in mergedChildDeps) {
|
|
24
|
+
const { group, name } = findGroupAndName(childKey);
|
|
25
|
+
const builtKey = `${group}/${name}`;
|
|
26
|
+
dependencyTree[builtKey] = mergedChildDeps[childKey];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return dependencyTree;
|
|
30
|
+
};
|
|
31
|
+
const buildSubDepsIntoFlatStructure = childDeps => {
|
|
32
|
+
const dependencyTree = {};
|
|
33
|
+
for (const dep in childDeps) {
|
|
34
|
+
const version = childDeps[dep];
|
|
35
|
+
const { group, name } = findGroupAndName(dep);
|
|
36
|
+
const key = `${group}/${name}`;
|
|
37
|
+
dependencyTree[key] = {
|
|
38
|
+
group: group,
|
|
39
|
+
name: name,
|
|
40
|
+
version: version,
|
|
41
|
+
directDependency: false,
|
|
42
|
+
isProduction: false,
|
|
43
|
+
dependencies: []
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return dependencyTree;
|
|
47
|
+
};
|
|
48
|
+
const findGroupAndName = groupAndName => {
|
|
49
|
+
if (groupAndName.includes('/')) {
|
|
50
|
+
const groupName = groupAndName.split('/');
|
|
51
|
+
return { group: groupName[0], name: groupName[1] };
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return { group: groupAndName, name: groupAndName };
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
module.exports = {
|
|
58
|
+
parsePHPLockFileForScaServices,
|
|
59
|
+
buildDepTree,
|
|
60
|
+
buildSubDepsIntoFlatStructure,
|
|
61
|
+
findGroupAndName
|
|
62
|
+
};
|
package/dist/scan/help.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const commandLineUsage = require('command-line-usage');
|
|
3
3
|
const i18n = require('i18n');
|
|
4
4
|
const constants = require('../constants');
|
|
5
|
+
const { commonHelpLinks } = require('../common/commonHelp');
|
|
5
6
|
const scanUsageGuide = commandLineUsage([
|
|
6
7
|
{
|
|
7
8
|
header: i18n.__('scanHeader')
|
|
@@ -35,9 +36,7 @@ const scanUsageGuide = commandLineUsage([
|
|
|
35
36
|
'application-name'
|
|
36
37
|
]
|
|
37
38
|
},
|
|
38
|
-
|
|
39
|
-
content: '{underline https://www.contrastsecurity.com}'
|
|
40
|
-
}
|
|
39
|
+
commonHelpLinks()
|
|
41
40
|
]);
|
|
42
41
|
module.exports = {
|
|
43
42
|
scanUsageGuide
|
package/dist/scan/scanConfig.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const paramHandler = require('../utils/paramsUtil/paramHandler');
|
|
3
|
-
const constants = require('
|
|
3
|
+
const constants = require('../constants.js');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { supportedLanguagesScan } = require('../constants/constants');
|
|
6
6
|
const i18n = require('i18n');
|
package/dist/scan/scanResults.js
CHANGED
|
@@ -65,10 +65,17 @@ const returnScanResults = async (config, codeArtifactId, newProject, timeout, st
|
|
|
65
65
|
let endTime = new Date() - startTime;
|
|
66
66
|
if (requestUtils.millisToSeconds(endTime) > timeout) {
|
|
67
67
|
oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan timed out at the specified ' + timeout + ' seconds.');
|
|
68
|
-
|
|
68
|
+
const isCI = process.env.CONTRAST_CODESEC_CI
|
|
69
|
+
? JSON.parse(process.env.CONTRAST_CODESEC_CI)
|
|
70
|
+
: false;
|
|
71
|
+
if (!isCI) {
|
|
69
72
|
const retry = await retryScanPrompt();
|
|
70
73
|
timeout = retry.timeout;
|
|
71
74
|
}
|
|
75
|
+
else {
|
|
76
|
+
console.log('Please try again, allowing more time');
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
}
|
package/dist/utils/getConfig.js
CHANGED
|
@@ -5,16 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.setConfigValues = exports.localConfig = void 0;
|
|
7
7
|
const conf_1 = __importDefault(require("conf"));
|
|
8
|
+
const constants_1 = require("../constants/constants");
|
|
8
9
|
const localConfig = (name, version) => {
|
|
9
10
|
const config = new conf_1.default({
|
|
10
11
|
configName: name
|
|
11
12
|
});
|
|
12
13
|
config.set('version', version);
|
|
13
|
-
if (process.env.CONTRAST_CODSEC_CI) {
|
|
14
|
-
config.set('isCI', JSON.parse(process.env.CONTRAST_CODSEC_CI.toLowerCase()));
|
|
15
|
-
}
|
|
16
14
|
if (!config.has('host')) {
|
|
17
|
-
config.set('host',
|
|
15
|
+
config.set('host', constants_1.CE_URL);
|
|
18
16
|
}
|
|
19
17
|
return config;
|
|
20
18
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/contrast",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Contrast Security's command line tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"test": "jest --testPathIgnorePatterns=./test-integration/",
|
|
24
24
|
"test-int": "jest ./test-integration/",
|
|
25
25
|
"test-int-scan": "jest ./test-integration/scan",
|
|
26
|
-
"test-int-audit": "jest test-integration/audit
|
|
26
|
+
"test-int-audit": "jest test-integration/audit",
|
|
27
|
+
"test-int-audit-reports": "jest test-integration/audit/audit-language-reports.spec.js",
|
|
28
|
+
"test-int-audit-features": "jest test-integration/audit/auditFeatures/",
|
|
27
29
|
"format": "prettier --write \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
28
30
|
"check-format": "prettier --check \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
|
|
29
31
|
"coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getHttpClient, handleResponseErrors } from '
|
|
1
|
+
import { getHttpClient, handleResponseErrors } from '../../utils/commonApi'
|
|
2
2
|
import {
|
|
3
3
|
ReportCompositeKey,
|
|
4
4
|
ReportList,
|
|
@@ -22,16 +22,17 @@ import {
|
|
|
22
22
|
ReportOutputModel
|
|
23
23
|
} from './models/reportOutputModel'
|
|
24
24
|
import {
|
|
25
|
+
CE_URL,
|
|
25
26
|
CRITICAL_COLOUR,
|
|
26
27
|
HIGH_COLOUR,
|
|
27
28
|
LOW_COLOUR,
|
|
28
29
|
MEDIUM_COLOUR,
|
|
29
30
|
NOTE_COLOUR
|
|
30
|
-
} from '
|
|
31
|
+
} from '../../constants/constants'
|
|
31
32
|
import Table from 'cli-table3'
|
|
32
33
|
import { ReportGuidanceModel } from './models/reportGuidanceModel'
|
|
33
34
|
|
|
34
|
-
export const
|
|
35
|
+
export const createSummaryMessageTop = (
|
|
35
36
|
numberOfVulnerableLibraries: number,
|
|
36
37
|
numberOfCves: number
|
|
37
38
|
) => {
|
|
@@ -42,6 +43,14 @@ export const createSummaryMessage = (
|
|
|
42
43
|
)
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
export const createSummaryMessageBottom = (
|
|
47
|
+
numberOfVulnerableLibraries: number
|
|
48
|
+
) => {
|
|
49
|
+
numberOfVulnerableLibraries === 1
|
|
50
|
+
? console.log(`Found 1 vulnerable library`)
|
|
51
|
+
: console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries`)
|
|
52
|
+
}
|
|
53
|
+
|
|
45
54
|
export const getReport = async (config: any, reportId: string) => {
|
|
46
55
|
const client = getHttpClient(config)
|
|
47
56
|
return client
|
|
@@ -87,7 +96,7 @@ export const printFormattedOutput = (
|
|
|
87
96
|
numberOfCves: number,
|
|
88
97
|
guidance: any
|
|
89
98
|
) => {
|
|
90
|
-
|
|
99
|
+
createSummaryMessageTop(numberOfVulnerableLibraries, numberOfCves)
|
|
91
100
|
console.log()
|
|
92
101
|
const report = new ReportList()
|
|
93
102
|
|
|
@@ -183,7 +192,7 @@ export const printFormattedOutput = (
|
|
|
183
192
|
console.log(table.toString() + '\n')
|
|
184
193
|
}
|
|
185
194
|
|
|
186
|
-
|
|
195
|
+
createSummaryMessageBottom(numberOfVulnerableLibraries)
|
|
187
196
|
const {
|
|
188
197
|
criticalMessage,
|
|
189
198
|
highMessage,
|
|
@@ -194,6 +203,15 @@ export const printFormattedOutput = (
|
|
|
194
203
|
console.log(
|
|
195
204
|
`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
|
|
196
205
|
)
|
|
206
|
+
|
|
207
|
+
if (config.host !== CE_URL) {
|
|
208
|
+
console.log(
|
|
209
|
+
'\n' + chalk.bold('View your full dependency tree in Contrast:')
|
|
210
|
+
)
|
|
211
|
+
console.log(
|
|
212
|
+
`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
|
|
213
|
+
)
|
|
214
|
+
}
|
|
197
215
|
}
|
|
198
216
|
|
|
199
217
|
export function buildHeader(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
} from './utils/reportUtils'
|
|
9
9
|
import i18n from 'i18n'
|
|
10
10
|
import chalk from 'chalk'
|
|
11
|
-
import * as constants from '
|
|
11
|
+
import * as constants from '../../constants/constants'
|
|
12
12
|
import { SeverityCountModel } from './models/severityCountModel'
|
|
13
|
-
import * as common from '
|
|
13
|
+
import * as common from '../../common/fail'
|
|
14
14
|
|
|
15
15
|
export function convertKeysToStandardFormat(config: any, guidance: any) {
|
|
16
16
|
let convertedGuidance = guidance
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ReportLibraryModel
|
|
4
4
|
} from '../models/reportLibraryModel'
|
|
5
5
|
import { ReportSeverityModel } from '../models/reportSeverityModel'
|
|
6
|
-
import languageAnalysisEngine from '
|
|
6
|
+
import languageAnalysisEngine from '../../../constants/constants'
|
|
7
7
|
import {
|
|
8
8
|
CRITICAL_COLOUR,
|
|
9
9
|
CRITICAL_PRIORITY,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
MEDIUM_PRIORITY,
|
|
16
16
|
NOTE_COLOUR,
|
|
17
17
|
NOTE_PRIORITY
|
|
18
|
-
} from '
|
|
18
|
+
} from '../../../constants/constants'
|
|
19
19
|
import { orderBy } from 'lodash'
|
|
20
20
|
import { SeverityCountModel } from '../models/severityCountModel'
|
|
21
21
|
import { ReportModelStructure } from '../models/reportListModel'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import commandLineUsage from 'command-line-usage'
|
|
2
2
|
import i18n from 'i18n'
|
|
3
3
|
import constants from '../../constants'
|
|
4
|
+
import { commonHelpLinks } from '../../common/commonHelp'
|
|
4
5
|
|
|
5
6
|
const auditUsageGuide = commandLineUsage([
|
|
6
7
|
{
|
|
@@ -48,7 +49,8 @@ const auditUsageGuide = commandLineUsage([
|
|
|
48
49
|
'app-groups',
|
|
49
50
|
'metadata'
|
|
50
51
|
]
|
|
51
|
-
}
|
|
52
|
+
},
|
|
53
|
+
commonHelpLinks()
|
|
52
54
|
])
|
|
53
55
|
|
|
54
56
|
export { auditUsageGuide }
|
|
@@ -21,7 +21,7 @@ const {
|
|
|
21
21
|
const i18n = require('i18n')
|
|
22
22
|
const {
|
|
23
23
|
vulnerabilityReportV2
|
|
24
|
-
} = require('../../../audit/
|
|
24
|
+
} = require('../../../audit/report/reportingFeature')
|
|
25
25
|
const auditSave = require('../../../audit/save')
|
|
26
26
|
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
|
|
27
27
|
const { auditUsageGuide } = require('../../audit/help')
|
|
@@ -77,7 +77,7 @@ const processSca = async config => {
|
|
|
77
77
|
messageToSend = rubyAnalysis(config, filesFound[0])
|
|
78
78
|
config.language = RUBY
|
|
79
79
|
break
|
|
80
|
-
case
|
|
80
|
+
case PHP:
|
|
81
81
|
messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0])
|
|
82
82
|
config.language = PHP
|
|
83
83
|
break
|
package/src/common/HTTPClient.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import i18n from 'i18n'
|
|
2
|
+
|
|
3
|
+
export function commonHelpLinks() {
|
|
4
|
+
return {
|
|
5
|
+
header: i18n.__('commonHelpHeader'),
|
|
6
|
+
content: [
|
|
7
|
+
i18n.__('commonHelpCheckOutHeader') + i18n.__('commonHelpCheckOutText'),
|
|
8
|
+
i18n.__('commonHelpLearnMoreHeader') + i18n.__('commonHelpLearnMoreText'),
|
|
9
|
+
i18n.__('commonHelpJoinDiscussionHeader') +
|
|
10
|
+
i18n.__('commonHelpJoinDiscussionText')
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -18,11 +18,11 @@ const getLatestVersion = async (config: any) => {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
// @ts-ignore
|
|
22
21
|
export async function findLatestCLIVersion(config: ContrastConf) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const isCI = process.env.CONTRAST_CODESEC_CI
|
|
23
|
+
? JSON.parse(process.env.CONTRAST_CODESEC_CI)
|
|
24
|
+
: false
|
|
25
|
+
if (!isCI) {
|
|
26
26
|
let latestCLIVersion: string = await getLatestVersion(config)
|
|
27
27
|
//strip key
|
|
28
28
|
latestCLIVersion = latestCLIVersion.substring(8)
|
|
@@ -14,7 +14,7 @@ const HIGH = 'HIGH'
|
|
|
14
14
|
const CRITICAL = 'CRITICAL'
|
|
15
15
|
// App
|
|
16
16
|
const APP_NAME = 'contrast'
|
|
17
|
-
const APP_VERSION = '1.0.
|
|
17
|
+
const APP_VERSION = '1.0.12'
|
|
18
18
|
const TIMEOUT = 120000
|
|
19
19
|
const HIGH_COLOUR = '#ff9900'
|
|
20
20
|
const CRITICAL_COLOUR = '#e35858'
|
|
@@ -32,7 +32,7 @@ const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com'
|
|
|
32
32
|
const SARIF_FILE = 'SARIF'
|
|
33
33
|
const SBOM_CYCLONE_DX_FILE = 'cyclonedx'
|
|
34
34
|
const SBOM_SPDX_FILE = 'spdx'
|
|
35
|
-
const CE_URL = 'https://ce.contrastsecurity.com
|
|
35
|
+
const CE_URL = 'https://ce.contrastsecurity.com'
|
|
36
36
|
|
|
37
37
|
module.exports = {
|
|
38
38
|
supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
|
package/src/constants/locales.js
CHANGED
|
@@ -441,6 +441,15 @@ const en_locales = () => {
|
|
|
441
441
|
auditReportFailureMessage: 'Unable to generate library report',
|
|
442
442
|
auditSCAAnalysisBegins: 'Contrast SCA audit started',
|
|
443
443
|
auditSCAAnalysisComplete: 'Contrast audit complete',
|
|
444
|
+
commonHelpHeader: 'Need More Help?',
|
|
445
|
+
commonHelpCheckOutHeader: chalk.hex('#9DC184')('Check out:'),
|
|
446
|
+
commonHelpCheckOutText: ' https://support.contrastsecurity.com',
|
|
447
|
+
commonHelpLearnMoreHeader: chalk.hex('#9DC184')('Learn more at:'),
|
|
448
|
+
commonHelpLearnMoreText: ' https://developer.contrastsecurity.com',
|
|
449
|
+
commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')(
|
|
450
|
+
'Join the discussion:'
|
|
451
|
+
),
|
|
452
|
+
commonHelpJoinDiscussionText: ' https://dev.to/codesec',
|
|
444
453
|
...lambda
|
|
445
454
|
}
|
|
446
455
|
}
|
package/src/constants.js
CHANGED
|
@@ -2,6 +2,7 @@ const commandLineUsage = require('command-line-usage')
|
|
|
2
2
|
const i18n = require('i18n')
|
|
3
3
|
const { en_locales } = require('./constants/locales.js')
|
|
4
4
|
const { parseSeverity } = require('./common/fail')
|
|
5
|
+
const { commonHelpLinks } = require('./common/commonHelp')
|
|
5
6
|
|
|
6
7
|
i18n.configure({
|
|
7
8
|
staticCatalog: {
|
|
@@ -410,16 +411,13 @@ const mainUsageGuide = commandLineUsage([
|
|
|
410
411
|
{ name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
|
|
411
412
|
]
|
|
412
413
|
},
|
|
413
|
-
{
|
|
414
|
-
content:
|
|
415
|
-
'{underline https://developer.contrastsecurity.com/} \n For technical support head to {underline https://support.contrastsecurity.com}'
|
|
416
|
-
},
|
|
417
414
|
{
|
|
418
415
|
header: i18n.__('configHeader2'),
|
|
419
416
|
content: [
|
|
420
417
|
{ name: i18n.__('clearHeader'), summary: i18n.__('clearContent') }
|
|
421
418
|
]
|
|
422
|
-
}
|
|
419
|
+
},
|
|
420
|
+
commonHelpLinks()
|
|
423
421
|
])
|
|
424
422
|
|
|
425
423
|
const mainDefinition = [{ name: 'command', defaultOption: true }]
|
package/src/lambda/help.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import commandLineUsage from 'command-line-usage'
|
|
2
2
|
import i18n from 'i18n'
|
|
3
|
+
import { commonHelpLinks } from '../common/commonHelp'
|
|
3
4
|
|
|
4
5
|
const lambdaUsageGuide = commandLineUsage([
|
|
5
6
|
{
|
|
@@ -80,9 +81,7 @@ const lambdaUsageGuide = commandLineUsage([
|
|
|
80
81
|
{ name: i18n.__('lambdaHelpOption'), summary: i18n.__('helpSummary') }
|
|
81
82
|
]
|
|
82
83
|
},
|
|
83
|
-
|
|
84
|
-
content: '{underline https://www.contrastsecurity.com/developer/codesec}'
|
|
85
|
-
}
|
|
84
|
+
commonHelpLinks()
|
|
86
85
|
])
|
|
87
86
|
|
|
88
87
|
export { lambdaUsageGuide }
|
|
@@ -5,7 +5,7 @@ const _ = require('lodash')
|
|
|
5
5
|
const readFile = (config, nameOfFile) => {
|
|
6
6
|
if (config.file) {
|
|
7
7
|
try {
|
|
8
|
-
return fs.readFileSync(config.file + '/' + nameOfFile)
|
|
8
|
+
return fs.readFileSync(config.file + '/' + nameOfFile, 'utf8')
|
|
9
9
|
} catch (error) {
|
|
10
10
|
console.log('Unable to find file')
|
|
11
11
|
console.log(error)
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
const { readFile, parseProjectFiles } = require('./analysis')
|
|
2
2
|
const { createPhpTSMessage } = require('../common/formatMessage')
|
|
3
|
+
const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper')
|
|
3
4
|
|
|
4
|
-
const phpAnalysis =
|
|
5
|
-
let analysis = readFiles(config
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const phpAnalysis = config => {
|
|
6
|
+
let analysis = readFiles(config)
|
|
7
|
+
|
|
8
|
+
if (config.experimental) {
|
|
9
|
+
return parsePHPLockFileForScaServices(analysis.rawLockFileContents)
|
|
10
|
+
} else {
|
|
11
|
+
const phpDep = parseProjectFiles(analysis)
|
|
12
|
+
return createPhpTSMessage(phpDep)
|
|
13
|
+
}
|
|
8
14
|
}
|
|
9
15
|
|
|
10
|
-
const readFiles =
|
|
16
|
+
const readFiles = config => {
|
|
11
17
|
let php = {}
|
|
12
18
|
|
|
13
19
|
php.composerJSON = JSON.parse(readFile(config, 'composer.json'))
|
|
@@ -18,5 +24,5 @@ const readFiles = (config, files) => {
|
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
module.exports = {
|
|
21
|
-
phpAnalysis
|
|
27
|
+
phpAnalysis: phpAnalysis
|
|
22
28
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const { keyBy, merge } = require('lodash')
|
|
2
|
+
|
|
3
|
+
const parsePHPLockFileForScaServices = phpLockFile => {
|
|
4
|
+
const packages = keyBy(phpLockFile.packages, 'name')
|
|
5
|
+
const packagesDev = keyBy(phpLockFile['packages-dev'], 'name')
|
|
6
|
+
|
|
7
|
+
return merge(buildDepTree(packages, true), buildDepTree(packagesDev, false))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const buildDepTree = (packages, isProduction) => {
|
|
11
|
+
//builds deps into flat structure
|
|
12
|
+
const dependencyTree = {}
|
|
13
|
+
|
|
14
|
+
for (const packagesKey in packages) {
|
|
15
|
+
const currentObj = packages[packagesKey]
|
|
16
|
+
const { group, name } = findGroupAndName(currentObj.name)
|
|
17
|
+
|
|
18
|
+
const key = `${group}/${name}@${currentObj.version}`
|
|
19
|
+
dependencyTree[key] = {
|
|
20
|
+
group: group,
|
|
21
|
+
name: name,
|
|
22
|
+
version: currentObj.version,
|
|
23
|
+
directDependency: true,
|
|
24
|
+
isProduction: isProduction,
|
|
25
|
+
dependencies: []
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const mergedChildDeps = merge(
|
|
29
|
+
buildSubDepsIntoFlatStructure(currentObj.require),
|
|
30
|
+
buildSubDepsIntoFlatStructure(currentObj['require-dev'])
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
for (const childKey in mergedChildDeps) {
|
|
34
|
+
const { group, name } = findGroupAndName(childKey)
|
|
35
|
+
const builtKey = `${group}/${name}`
|
|
36
|
+
dependencyTree[builtKey] = mergedChildDeps[childKey]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return dependencyTree
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// currently sub deps will be built into a flat structure
|
|
43
|
+
// but not ingested via the new services as they do not have concrete versions
|
|
44
|
+
const buildSubDepsIntoFlatStructure = childDeps => {
|
|
45
|
+
const dependencyTree = {}
|
|
46
|
+
|
|
47
|
+
for (const dep in childDeps) {
|
|
48
|
+
const version = childDeps[dep]
|
|
49
|
+
const { group, name } = findGroupAndName(dep)
|
|
50
|
+
const key = `${group}/${name}`
|
|
51
|
+
dependencyTree[key] = {
|
|
52
|
+
group: group,
|
|
53
|
+
name: name,
|
|
54
|
+
version: version,
|
|
55
|
+
directDependency: false,
|
|
56
|
+
isProduction: false,
|
|
57
|
+
dependencies: []
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return dependencyTree
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const findGroupAndName = groupAndName => {
|
|
64
|
+
if (groupAndName.includes('/')) {
|
|
65
|
+
const groupName = groupAndName.split('/')
|
|
66
|
+
return { group: groupName[0], name: groupName[1] }
|
|
67
|
+
} else {
|
|
68
|
+
return { group: groupAndName, name: groupAndName }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
parsePHPLockFileForScaServices,
|
|
74
|
+
buildDepTree,
|
|
75
|
+
buildSubDepsIntoFlatStructure,
|
|
76
|
+
findGroupAndName
|
|
77
|
+
}
|
package/src/scan/help.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const commandLineUsage = require('command-line-usage')
|
|
2
2
|
const i18n = require('i18n')
|
|
3
3
|
const constants = require('../constants')
|
|
4
|
+
const { commonHelpLinks } = require('../common/commonHelp')
|
|
4
5
|
|
|
5
6
|
const scanUsageGuide = commandLineUsage([
|
|
6
7
|
{
|
|
@@ -35,9 +36,7 @@ const scanUsageGuide = commandLineUsage([
|
|
|
35
36
|
'application-name'
|
|
36
37
|
]
|
|
37
38
|
},
|
|
38
|
-
|
|
39
|
-
content: '{underline https://www.contrastsecurity.com}'
|
|
40
|
-
}
|
|
39
|
+
commonHelpLinks()
|
|
41
40
|
])
|
|
42
41
|
|
|
43
42
|
module.exports = {
|
package/src/scan/scanConfig.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const paramHandler = require('../utils/paramsUtil/paramHandler')
|
|
2
|
-
const constants = require('
|
|
2
|
+
const constants = require('../constants.js')
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const { supportedLanguagesScan } = require('../constants/constants')
|
|
5
5
|
const i18n = require('i18n')
|
package/src/scan/scanResults.js
CHANGED
|
@@ -93,9 +93,15 @@ const returnScanResults = async (
|
|
|
93
93
|
'Contrast Scan timed out at the specified ' + timeout + ' seconds.'
|
|
94
94
|
)
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
const isCI = process.env.CONTRAST_CODESEC_CI
|
|
97
|
+
? JSON.parse(process.env.CONTRAST_CODESEC_CI)
|
|
98
|
+
: false
|
|
99
|
+
if (!isCI) {
|
|
97
100
|
const retry = await retryScanPrompt()
|
|
98
101
|
timeout = retry.timeout
|
|
102
|
+
} else {
|
|
103
|
+
console.log('Please try again, allowing more time')
|
|
104
|
+
process.exit(1)
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
}
|
package/src/utils/getConfig.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Conf from 'conf'
|
|
2
|
+
import { CE_URL } from '../constants/constants'
|
|
2
3
|
|
|
3
4
|
type ContrastConfOptions = Partial<{
|
|
4
5
|
version: string
|
|
@@ -7,7 +8,6 @@ type ContrastConfOptions = Partial<{
|
|
|
7
8
|
orgId: string
|
|
8
9
|
authHeader: string
|
|
9
10
|
numOfRuns: number
|
|
10
|
-
isCI: boolean
|
|
11
11
|
}>
|
|
12
12
|
|
|
13
13
|
type ContrastConf = Conf<ContrastConfOptions>
|
|
@@ -18,15 +18,8 @@ const localConfig = (name: string, version: string) => {
|
|
|
18
18
|
})
|
|
19
19
|
config.set('version', version)
|
|
20
20
|
|
|
21
|
-
if (process.env.CONTRAST_CODSEC_CI) {
|
|
22
|
-
config.set(
|
|
23
|
-
'isCI',
|
|
24
|
-
JSON.parse(process.env.CONTRAST_CODSEC_CI.toLowerCase()) as boolean
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
21
|
if (!config.has('host')) {
|
|
29
|
-
config.set('host',
|
|
22
|
+
config.set('host', CE_URL)
|
|
30
23
|
}
|
|
31
24
|
return config
|
|
32
25
|
}
|