@contrast/contrast 1.0.2 → 1.0.5
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/.prettierignore +4 -0
- package/README.md +24 -16
- package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
- package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +30 -13
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +51 -237
- package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -14
- package/dist/commands/audit/auditConfig.js +8 -2
- package/dist/commands/audit/auditController.js +14 -5
- package/dist/commands/audit/saveFile.js +11 -0
- package/dist/commands/auth/auth.js +19 -1
- package/dist/commands/config/config.js +19 -8
- package/dist/commands/scan/processScan.js +13 -27
- package/dist/commands/scan/sca/scaAnalysis.js +44 -0
- package/dist/common/HTTPClient.js +29 -26
- package/dist/common/errorHandling.js +15 -39
- package/dist/common/versionChecker.js +32 -0
- package/dist/constants/constants.js +16 -2
- package/dist/constants/lambda.js +3 -1
- package/dist/constants/locales.js +58 -48
- package/dist/constants.js +59 -3
- package/dist/index.js +48 -30
- package/dist/lambda/help.js +22 -14
- package/dist/lambda/lambda.js +6 -0
- package/dist/sbom/generateSbom.js +20 -0
- package/dist/scaAnalysis/common/formatMessage.js +11 -0
- package/dist/scaAnalysis/common/treeUpload.js +30 -0
- package/dist/scaAnalysis/java/analysis.js +116 -0
- package/dist/scaAnalysis/java/index.js +18 -0
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +326 -0
- package/dist/scan/autoDetection.js +46 -1
- package/dist/scan/fileUtils.js +73 -1
- package/dist/scan/formatScanOutput.js +212 -0
- package/dist/scan/help.js +6 -2
- package/dist/scan/models/groupedResultsModel.js +11 -0
- package/dist/scan/models/resultContentModel.js +2 -0
- package/dist/scan/models/scanResultsModel.js +11 -0
- package/dist/scan/populateProjectIdAndProjectName.js +1 -0
- package/dist/scan/saveResults.js +9 -10
- package/dist/scan/scan.js +26 -101
- package/dist/scan/scanConfig.js +20 -1
- package/dist/scan/scanController.js +8 -4
- package/dist/scan/scanResults.js +8 -17
- package/dist/utils/getConfig.js +3 -0
- package/dist/utils/requestUtils.js +1 -1
- package/dist/utils/saveFile.js +19 -0
- package/package.json +3 -2
- package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
- package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +41 -19
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +71 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +105 -0
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -22
- package/src/commands/audit/auditConfig.ts +12 -3
- package/src/commands/audit/auditController.ts +21 -5
- package/src/commands/audit/processAudit.ts +3 -1
- package/src/commands/audit/saveFile.ts +6 -0
- package/src/commands/auth/auth.js +25 -1
- package/src/commands/config/config.js +22 -8
- package/src/commands/scan/processScan.js +15 -31
- package/src/commands/scan/sca/scaAnalysis.js +73 -0
- package/src/common/HTTPClient.js +42 -36
- package/src/common/errorHandling.ts +17 -48
- package/src/common/versionChecker.ts +41 -0
- package/src/constants/constants.js +17 -4
- package/src/constants/lambda.js +3 -1
- package/src/constants/locales.js +69 -63
- package/src/constants.js +66 -3
- package/src/index.ts +62 -36
- package/src/lambda/help.ts +22 -14
- package/src/lambda/lambda.ts +8 -0
- package/src/sbom/generateSbom.ts +17 -0
- package/src/scaAnalysis/common/formatMessage.js +10 -0
- package/src/scaAnalysis/common/treeUpload.js +34 -0
- package/src/scaAnalysis/java/analysis.js +159 -0
- package/src/scaAnalysis/java/index.js +21 -0
- package/src/scaAnalysis/java/javaBuildDepsParser.js +391 -0
- package/src/scan/autoDetection.js +54 -1
- package/src/scan/fileUtils.js +91 -1
- package/src/scan/formatScanOutput.ts +241 -0
- package/src/scan/help.js +6 -2
- package/src/scan/models/groupedResultsModel.ts +20 -0
- package/src/scan/models/resultContentModel.ts +86 -0
- package/src/scan/models/scanResultsModel.ts +52 -0
- package/src/scan/populateProjectIdAndProjectName.js +1 -0
- package/src/scan/saveResults.js +8 -9
- package/src/scan/scan.ts +62 -0
- package/src/scan/scanConfig.js +26 -1
- package/src/scan/scanController.js +12 -4
- package/src/scan/scanResults.js +19 -17
- package/src/utils/getConfig.ts +12 -0
- package/src/utils/requestUtils.js +1 -1
- package/src/utils/saveFile.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
- package/dist/common/findLatestCLIVersion.js +0 -23
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
- package/src/common/findLatestCLIVersion.ts +0 -27
- package/src/scan/scan.js +0 -167
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReportCVEModel,
|
|
3
|
+
ReportLibraryModel
|
|
4
|
+
} from '../models/reportLibraryModel'
|
|
5
|
+
import { ReportSeverityModel } from '../models/reportSeverityModel'
|
|
6
|
+
import languageAnalysisEngine from '../../../languageAnalysisEngine/constants'
|
|
7
|
+
const {
|
|
8
|
+
supportedLanguages: { GO }
|
|
9
|
+
} = languageAnalysisEngine
|
|
10
|
+
|
|
11
|
+
export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
|
|
12
|
+
if (
|
|
13
|
+
cveArray.find(
|
|
14
|
+
cve =>
|
|
15
|
+
cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL'
|
|
16
|
+
)
|
|
17
|
+
) {
|
|
18
|
+
return new ReportSeverityModel('CRITICAL', 1)
|
|
19
|
+
} else if (
|
|
20
|
+
cveArray.find(
|
|
21
|
+
cve => cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH'
|
|
22
|
+
)
|
|
23
|
+
) {
|
|
24
|
+
return new ReportSeverityModel('HIGH', 2)
|
|
25
|
+
} else if (
|
|
26
|
+
cveArray.find(
|
|
27
|
+
cve => cve.cvss3SeverityCode === 'MEDIUM' || cve.severityCode === 'MEDIUM'
|
|
28
|
+
)
|
|
29
|
+
) {
|
|
30
|
+
return new ReportSeverityModel('MEDIUM', 3)
|
|
31
|
+
} else if (
|
|
32
|
+
cveArray.find(
|
|
33
|
+
cve => cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW'
|
|
34
|
+
)
|
|
35
|
+
) {
|
|
36
|
+
return new ReportSeverityModel('LOW', 4)
|
|
37
|
+
} else if (
|
|
38
|
+
cveArray.find(
|
|
39
|
+
cve => cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE'
|
|
40
|
+
)
|
|
41
|
+
) {
|
|
42
|
+
return new ReportSeverityModel('NOTE', 5)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function convertGenericToTypedLibraries(libraries: any) {
|
|
47
|
+
return Object.entries(libraries).map(([name, cveArray]) => {
|
|
48
|
+
return new ReportLibraryModel(name, cveArray as ReportCVEModel[])
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function severityCount(vulnerableLibraries: ReportLibraryModel[]) {
|
|
53
|
+
const severityCount = {
|
|
54
|
+
critical: 0,
|
|
55
|
+
high: 0,
|
|
56
|
+
medium: 0,
|
|
57
|
+
low: 0,
|
|
58
|
+
note: 0
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
vulnerableLibraries.forEach(lib => {
|
|
62
|
+
lib.cveArray.forEach(cve => {
|
|
63
|
+
if (
|
|
64
|
+
cve.cvss3SeverityCode === 'CRITICAL' ||
|
|
65
|
+
cve.severityCode === 'CRITICAL'
|
|
66
|
+
) {
|
|
67
|
+
severityCount['critical'] += 1
|
|
68
|
+
} else if (
|
|
69
|
+
cve.cvss3SeverityCode === 'HIGH' ||
|
|
70
|
+
cve.severityCode === 'HIGH'
|
|
71
|
+
) {
|
|
72
|
+
severityCount['high'] += 1
|
|
73
|
+
} else if (
|
|
74
|
+
cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
75
|
+
cve.severityCode === 'MEDIUM'
|
|
76
|
+
) {
|
|
77
|
+
severityCount['medium'] += 1
|
|
78
|
+
} else if (
|
|
79
|
+
cve.cvss3SeverityCode === 'LOW' ||
|
|
80
|
+
cve.severityCode === 'LOW'
|
|
81
|
+
) {
|
|
82
|
+
severityCount['low'] += 1
|
|
83
|
+
} else if (
|
|
84
|
+
cve.cvss3SeverityCode === 'NOTE' ||
|
|
85
|
+
cve.severityCode === 'NOTE'
|
|
86
|
+
) {
|
|
87
|
+
severityCount['note'] += 1
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
return severityCount
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function findNameAndVersion(library: ReportLibraryModel, config: any) {
|
|
96
|
+
if (config.language.toUpperCase() === GO) {
|
|
97
|
+
const nameVersion = library.name.split('@')
|
|
98
|
+
const name = nameVersion[0]
|
|
99
|
+
const version = nameVersion[1]
|
|
100
|
+
|
|
101
|
+
return { name, version }
|
|
102
|
+
} else {
|
|
103
|
+
const splitLibraryName = library.name.split('/')
|
|
104
|
+
const nameVersion = splitLibraryName[1].split('@')
|
|
105
|
+
const name = nameVersion[0]
|
|
106
|
+
const version = nameVersion[1]
|
|
107
|
+
|
|
108
|
+
return { name, version }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
const prettyjson = require('prettyjson')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
1
|
const { getHttpClient } = require('../../utils/commonApi')
|
|
4
2
|
const { handleResponseErrors } = require('../../common/errorHandling')
|
|
5
3
|
const { APP_VERSION } = require('../../constants/constants')
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
console.log(
|
|
9
|
-
'\n **************************' +
|
|
10
|
-
i18n.__('successHeader') +
|
|
11
|
-
'************************** '
|
|
12
|
-
)
|
|
13
|
-
console.log('\n' + i18n.__('snapshotSuccessMessage') + '\n')
|
|
14
|
-
console.log(
|
|
15
|
-
` ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
|
|
16
|
-
)
|
|
17
|
-
console.log('\n ***********************************************************')
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const newSendSnapShot = async (analysis, applicationId) => {
|
|
5
|
+
const newSendSnapShot = async analysis => {
|
|
21
6
|
const analysisLanguage = analysis.config.language.toLowerCase()
|
|
22
7
|
const requestBody = {
|
|
23
8
|
appID: analysis.config.applicationId,
|
|
@@ -30,11 +15,7 @@ const newSendSnapShot = async (analysis, applicationId) => {
|
|
|
30
15
|
return client
|
|
31
16
|
.sendSnapshot(requestBody, analysis.config)
|
|
32
17
|
.then(res => {
|
|
33
|
-
// if (!analysis.config.silent) {
|
|
34
|
-
// console.log(prettyjson.render(requestBody))
|
|
35
|
-
// }
|
|
36
18
|
if (res.statusCode === 201) {
|
|
37
|
-
displaySnapshotSuccessMessage(analysis.config)
|
|
38
19
|
return res.body
|
|
39
20
|
} else {
|
|
40
21
|
handleResponseErrors(res, 'snapshot')
|
|
@@ -46,6 +27,5 @@ const newSendSnapShot = async (analysis, applicationId) => {
|
|
|
46
27
|
}
|
|
47
28
|
|
|
48
29
|
module.exports = {
|
|
49
|
-
newSendSnapShot: newSendSnapShot
|
|
50
|
-
displaySnapshotSuccessMessage: displaySnapshotSuccessMessage
|
|
30
|
+
newSendSnapShot: newSendSnapShot
|
|
51
31
|
}
|
|
@@ -2,6 +2,10 @@ import paramHandler from '../../utils/paramsUtil/paramHandler'
|
|
|
2
2
|
import constants from '../../constants'
|
|
3
3
|
import cliOptions from '../../utils/parsedCLIOptions'
|
|
4
4
|
import languageAnalysisEngine from '../../audit/languageAnalysisEngine/constants'
|
|
5
|
+
import {
|
|
6
|
+
determineProjectLanguage,
|
|
7
|
+
identifyLanguages
|
|
8
|
+
} from '../../audit/autodetection/autoDetectLanguage'
|
|
5
9
|
|
|
6
10
|
const {
|
|
7
11
|
supportedLanguages: { NODE, JAVASCRIPT }
|
|
@@ -18,9 +22,14 @@ export const getAuditConfig = (argv: string[]): { [key: string]: string } => {
|
|
|
18
22
|
auditParameters.language === undefined ||
|
|
19
23
|
auditParameters.language === null
|
|
20
24
|
) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
try {
|
|
26
|
+
auditParameters.language = determineProjectLanguage(
|
|
27
|
+
identifyLanguages(auditParameters)
|
|
28
|
+
)
|
|
29
|
+
} catch (err: any) {
|
|
30
|
+
console.log(err.message)
|
|
31
|
+
process.exit(1)
|
|
32
|
+
}
|
|
24
33
|
} else if (auditParameters.language.toUpperCase() === JAVASCRIPT) {
|
|
25
34
|
auditParameters.language = NODE.toLowerCase()
|
|
26
35
|
}
|
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
import { catalogueApplication } from '../../audit/catalogueApplication/catalogueApplication'
|
|
2
2
|
import commonApi from '../../audit/languageAnalysisEngine/commonApi'
|
|
3
|
+
|
|
3
4
|
const identifyLanguageAE = require('./../../audit/languageAnalysisEngine')
|
|
4
|
-
const languageFactory = require('
|
|
5
|
+
const languageFactory = require('../../audit/languageAnalysisEngine/languageAnalysisFactory')
|
|
6
|
+
const { v4: uuidv4 } = require('uuid')
|
|
5
7
|
|
|
6
|
-
const dealWithNoAppId = async (config: { [x: string]: string }) => {
|
|
7
|
-
let appID
|
|
8
|
+
export const dealWithNoAppId = async (config: { [x: string]: string }) => {
|
|
9
|
+
let appID: string
|
|
8
10
|
try {
|
|
11
|
+
// @ts-ignore
|
|
9
12
|
appID = await commonApi.returnAppId(config)
|
|
13
|
+
// console.log('appid', appID)
|
|
10
14
|
if (!appID && config.applicationName) {
|
|
11
15
|
return await catalogueApplication(config)
|
|
12
16
|
}
|
|
17
|
+
if (!appID && !config.applicationName) {
|
|
18
|
+
config.applicationName = uuidv4()
|
|
19
|
+
return await catalogueApplication(config)
|
|
20
|
+
}
|
|
21
|
+
// @ts-ignore
|
|
13
22
|
} catch (e) {
|
|
14
|
-
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
if (e.toString().includes('tunneling socket could not be established')) {
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
console.log(e.message)
|
|
27
|
+
console.log(
|
|
28
|
+
'There seems to be an issue with your proxy, please check and try again'
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
process.exit(1)
|
|
15
32
|
}
|
|
16
|
-
console.log(appID)
|
|
17
33
|
return appID
|
|
18
34
|
}
|
|
19
35
|
|
|
@@ -10,8 +10,10 @@ export const processAudit = async (argv: parameterInput) => {
|
|
|
10
10
|
process.exit(1)
|
|
11
11
|
}
|
|
12
12
|
const config = getAuditConfig(argv)
|
|
13
|
+
|
|
14
|
+
// console.log(config)
|
|
15
|
+
|
|
13
16
|
const auditResults = await startAudit(config)
|
|
14
|
-
//report here
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
const printHelpMessage = () => {
|
|
@@ -11,8 +11,21 @@ const {
|
|
|
11
11
|
succeedSpinner
|
|
12
12
|
} = require('../../utils/oraWrapper')
|
|
13
13
|
const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
|
|
14
|
+
const parsedCLIOptions = require('../../utils/parsedCLIOptions')
|
|
15
|
+
const constants = require('../../constants')
|
|
16
|
+
const commandLineUsage = require('command-line-usage')
|
|
17
|
+
|
|
18
|
+
const processAuth = async (argv, config) => {
|
|
19
|
+
let authParams = parsedCLIOptions.getCommandLineArgsCustom(
|
|
20
|
+
argv,
|
|
21
|
+
constants.commandLineDefinitions.authOptionDefinitions
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if (authParams.help) {
|
|
25
|
+
console.log(authUsageGuide)
|
|
26
|
+
process.exit(0)
|
|
27
|
+
}
|
|
14
28
|
|
|
15
|
-
const processAuth = async config => {
|
|
16
29
|
const token = uuidv4()
|
|
17
30
|
const url = `${AUTH_UI_URL}/?token=${token}`
|
|
18
31
|
|
|
@@ -68,6 +81,17 @@ const pollAuthResult = async (token, client) => {
|
|
|
68
81
|
})
|
|
69
82
|
}
|
|
70
83
|
|
|
84
|
+
const authUsageGuide = commandLineUsage([
|
|
85
|
+
{
|
|
86
|
+
header: i18n.__('authHeader'),
|
|
87
|
+
content: [i18n.__('constantsAuthHeaderContents')]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
header: i18n.__('constantsAuthUsageHeader'),
|
|
91
|
+
content: [i18n.__('constantsAuthUsageContents')]
|
|
92
|
+
}
|
|
93
|
+
])
|
|
94
|
+
|
|
71
95
|
module.exports = {
|
|
72
96
|
processAuth: processAuth
|
|
73
97
|
}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
const
|
|
1
|
+
const parsedCLIOptions = require('../../utils/parsedCLIOptions')
|
|
2
|
+
const constants = require('../../constants')
|
|
3
|
+
const commandLineUsage = require('command-line-usage')
|
|
4
|
+
const i18n = require('i18n')
|
|
2
5
|
|
|
3
6
|
const processConfig = (argv, config) => {
|
|
4
|
-
const options = [{ name: 'clear', alias: 'c', type: Boolean }]
|
|
5
|
-
|
|
6
7
|
try {
|
|
7
|
-
|
|
8
|
+
let configParams = parsedCLIOptions.getCommandLineArgsCustom(
|
|
8
9
|
argv,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
constants.commandLineDefinitions.configOptionDefinitions
|
|
11
|
+
)
|
|
12
|
+
if (configParams.help) {
|
|
13
|
+
console.log(configUsageGuide)
|
|
14
|
+
process.exit(0)
|
|
15
|
+
}
|
|
16
|
+
if (configParams.clear) {
|
|
13
17
|
config.clear()
|
|
14
18
|
} else {
|
|
15
19
|
console.log(JSON.parse(JSON.stringify(config.store)))
|
|
@@ -20,6 +24,16 @@ const processConfig = (argv, config) => {
|
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
|
|
27
|
+
const configUsageGuide = commandLineUsage([
|
|
28
|
+
{
|
|
29
|
+
header: i18n.__('configHeader')
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
content: [i18n.__('constantsConfigUsageContents')],
|
|
33
|
+
optionList: constants.commandLineDefinitions.configOptionDefinitions
|
|
34
|
+
}
|
|
35
|
+
])
|
|
36
|
+
|
|
23
37
|
module.exports = {
|
|
24
38
|
processConfig: processConfig
|
|
25
39
|
}
|
|
@@ -1,44 +1,28 @@
|
|
|
1
|
-
const { startScan } = require('../../scan/scanController')
|
|
2
|
-
const { formatScanOutput } = require('../../scan/scan')
|
|
3
|
-
const { scanUsageGuide } = require('../../scan/help')
|
|
4
1
|
const scanConfig = require('../../scan/scanConfig')
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
2
|
+
const { startScan } = require('../../scan/scanController')
|
|
3
|
+
const { saveScanFile } = require('../../utils/saveFile')
|
|
4
|
+
const { ScanResultsModel } = require('../../scan/models/scanResultsModel')
|
|
5
|
+
const { formatScanOutput } = require('../../scan/formatScanOutput')
|
|
6
|
+
const { processSca } = require('./sca/scaAnalysis')
|
|
8
7
|
|
|
9
8
|
const processScan = async argvMain => {
|
|
10
|
-
if (argvMain.indexOf('--help') !== -1) {
|
|
11
|
-
printHelpMessage()
|
|
12
|
-
process.exit(1)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
9
|
let config = scanConfig.getScanConfig(argvMain)
|
|
10
|
+
// console.log(config)
|
|
11
|
+
//try SCA analysis first
|
|
12
|
+
if (config.experimental) {
|
|
13
|
+
await processSca(config)
|
|
14
|
+
}
|
|
16
15
|
|
|
17
|
-
let scanResults = await startScan(config)
|
|
16
|
+
let scanResults = new ScanResultsModel(await startScan(config))
|
|
18
17
|
if (scanResults) {
|
|
19
|
-
formatScanOutput(
|
|
20
|
-
scanResults?.projectOverview,
|
|
21
|
-
scanResults?.scanResultsInstances
|
|
22
|
-
)
|
|
18
|
+
formatScanOutput(scanResults)
|
|
23
19
|
}
|
|
24
20
|
|
|
25
|
-
if (config.save) {
|
|
26
|
-
|
|
27
|
-
const scanId = scanResults.scanDetail.id
|
|
28
|
-
const client = commonApi.getHttpClient(config)
|
|
29
|
-
const rawResults = await client.getSpecificScanResultSarif(config, scanId)
|
|
30
|
-
saveResults.writeResultsToFile(rawResults?.body)
|
|
31
|
-
} else {
|
|
32
|
-
console.log(i18n.__('scanNoFiletypeSpecifiedForSave'))
|
|
33
|
-
}
|
|
21
|
+
if (config.save !== undefined) {
|
|
22
|
+
await saveScanFile(config, scanResults)
|
|
34
23
|
}
|
|
35
24
|
}
|
|
36
25
|
|
|
37
|
-
const printHelpMessage = () => {
|
|
38
|
-
console.log(scanUsageGuide)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
26
|
module.exports = {
|
|
42
|
-
processScan
|
|
43
|
-
printHelpMessage
|
|
27
|
+
processScan
|
|
44
28
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const autoDetection = require('../../../scan/autoDetection')
|
|
2
|
+
const { javaAnalysis } = require('../../../scaAnalysis/java')
|
|
3
|
+
const { commonSendSnapShot } = require('../../../scaAnalysis/common/treeUpload')
|
|
4
|
+
const {
|
|
5
|
+
manualDetectAuditFilesAndLanguages
|
|
6
|
+
} = require('../../../scan/autoDetection')
|
|
7
|
+
const { dealWithNoAppId } = require('../../audit/auditController')
|
|
8
|
+
const {
|
|
9
|
+
supportedLanguages: { JAVA }
|
|
10
|
+
} = require('../../../audit/languageAnalysisEngine/constants')
|
|
11
|
+
|
|
12
|
+
const processSca = async config => {
|
|
13
|
+
let filesFound
|
|
14
|
+
if (config.projectPath) {
|
|
15
|
+
filesFound = await manualDetectAuditFilesAndLanguages(config.projectPath)
|
|
16
|
+
} else {
|
|
17
|
+
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// files found looks like [ { javascript: [ Array ] } ]
|
|
21
|
+
//check we have the language and call the right analyser
|
|
22
|
+
//refactor new analyser and see if we can clean it up
|
|
23
|
+
let messageToSend = undefined
|
|
24
|
+
if (filesFound.length === 1) {
|
|
25
|
+
switch (Object.keys(filesFound[0])[0]) {
|
|
26
|
+
case JAVA:
|
|
27
|
+
messageToSend = await javaAnalysis(config, filesFound[0])
|
|
28
|
+
config.language = JAVA
|
|
29
|
+
break
|
|
30
|
+
// case 'javascript':
|
|
31
|
+
// // code block
|
|
32
|
+
// break;
|
|
33
|
+
// case 'dotnet':
|
|
34
|
+
// // code block
|
|
35
|
+
// break;
|
|
36
|
+
// case 'python':
|
|
37
|
+
// // code block
|
|
38
|
+
// break;
|
|
39
|
+
// case 'ruby':
|
|
40
|
+
// // code block
|
|
41
|
+
// break;
|
|
42
|
+
// case 'php':
|
|
43
|
+
// // code block
|
|
44
|
+
// break;
|
|
45
|
+
// case 'go':
|
|
46
|
+
// // code block
|
|
47
|
+
// break;
|
|
48
|
+
default:
|
|
49
|
+
//something is wrong
|
|
50
|
+
console.log('language detected not supported')
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!config.applicationId) {
|
|
55
|
+
config.applicationId = await dealWithNoAppId(config)
|
|
56
|
+
}
|
|
57
|
+
//send message to TS
|
|
58
|
+
console.log('processing dependencies')
|
|
59
|
+
const response = await commonSendSnapShot(messageToSend, config)
|
|
60
|
+
} else {
|
|
61
|
+
if (filesFound.length === 0) {
|
|
62
|
+
console.log('no compatible dependency files detected. Continuing...')
|
|
63
|
+
} else {
|
|
64
|
+
console.log(
|
|
65
|
+
'multiple language files detected, please use --project-path to specify a directory or the file where dependencies are declared'
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
processSca
|
|
73
|
+
}
|
package/src/common/HTTPClient.js
CHANGED
|
@@ -106,7 +106,9 @@ HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
|
|
|
106
106
|
options.url = url
|
|
107
107
|
options.body = {
|
|
108
108
|
codeArtifactId: codeArtifactId,
|
|
109
|
-
label:
|
|
109
|
+
label: config.label
|
|
110
|
+
? config.label
|
|
111
|
+
: `Started by CLI tool at ${new Date().toString()}`
|
|
110
112
|
}
|
|
111
113
|
return requestUtils.sendRequest({ method: 'post', options })
|
|
112
114
|
}
|
|
@@ -130,6 +132,9 @@ HTTPClient.prototype.createProjectId = function createProjectId(config) {
|
|
|
130
132
|
name: config.name,
|
|
131
133
|
archived: 'false'
|
|
132
134
|
}
|
|
135
|
+
if (config.language) {
|
|
136
|
+
options.body.language = config.language
|
|
137
|
+
}
|
|
133
138
|
options.url = createHarmonyProjectsUrl(config)
|
|
134
139
|
return requestUtils.sendRequest({ method: 'post', options })
|
|
135
140
|
}
|
|
@@ -185,6 +190,9 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
|
|
|
185
190
|
}
|
|
186
191
|
|
|
187
192
|
HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
193
|
+
if (config.language.toUpperCase() === 'RUBY') {
|
|
194
|
+
//console.log('sendSnapshot requestBody', requestBody.snapshot.ruby)
|
|
195
|
+
}
|
|
188
196
|
const options = _.cloneDeep(this.requestOptions)
|
|
189
197
|
let url = createSnapshotURL(config)
|
|
190
198
|
options.url = url
|
|
@@ -192,32 +200,22 @@ HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
|
192
200
|
return requestUtils.sendRequest({ method: 'post', options })
|
|
193
201
|
}
|
|
194
202
|
|
|
195
|
-
HTTPClient.prototype.
|
|
203
|
+
HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
196
204
|
const options = _.cloneDeep(this.requestOptions)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
HTTPClient.prototype.getSpecificReport = function getSpecificReport(
|
|
204
|
-
config,
|
|
205
|
-
reportId
|
|
206
|
-
) {
|
|
207
|
-
const options = _.cloneDeep(this.requestOptions)
|
|
208
|
-
let url = createSpecificReportUrl(config, reportId)
|
|
209
|
-
options.url = url
|
|
210
|
-
|
|
205
|
+
if (config.ignoreDev) {
|
|
206
|
+
options.url = createSpecificReportWithProdUrl(config, reportId)
|
|
207
|
+
} else {
|
|
208
|
+
options.url = createSpecificReportUrl(config, reportId)
|
|
209
|
+
}
|
|
211
210
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
212
211
|
}
|
|
213
212
|
|
|
214
213
|
HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
config,
|
|
215
|
+
requestBody
|
|
217
216
|
) {
|
|
218
217
|
const options = _.cloneDeep(this.requestOptions)
|
|
219
|
-
|
|
220
|
-
options.url = url
|
|
218
|
+
options.url = createLibraryVulnerabilitiesUrl(config)
|
|
221
219
|
options.body = requestBody
|
|
222
220
|
|
|
223
221
|
return requestUtils.sendRequest({ method: 'put', options })
|
|
@@ -230,16 +228,16 @@ HTTPClient.prototype.getAppId = function getAppId(config) {
|
|
|
230
228
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
231
229
|
}
|
|
232
230
|
|
|
233
|
-
HTTPClient.prototype.getDependencyTree = function getReport(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
231
|
+
// HTTPClient.prototype.getDependencyTree = function getReport(
|
|
232
|
+
// orgUuid,
|
|
233
|
+
// appId,
|
|
234
|
+
// reportId
|
|
235
|
+
// ) {
|
|
236
|
+
// const options = _.cloneDeep(this.requestOptions)
|
|
237
|
+
// let url = createGetDependencyTree(options.uri, orgUuid, appId, reportId)
|
|
238
|
+
// options.url = url
|
|
239
|
+
// return requestUtils.sendRequest({ method: 'get', options })
|
|
240
|
+
// }
|
|
243
241
|
|
|
244
242
|
// serverless - lambda
|
|
245
243
|
function getServerlessHost(config = {}) {
|
|
@@ -317,6 +315,12 @@ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
|
|
|
317
315
|
return requestUtils.sendRequest({ method: 'post', options })
|
|
318
316
|
}
|
|
319
317
|
|
|
318
|
+
HTTPClient.prototype.getSbom = function getSbom(config) {
|
|
319
|
+
const options = _.cloneDeep(this.requestOptions)
|
|
320
|
+
options.url = createSbomCycloneDXUrl(config)
|
|
321
|
+
return requestUtils.sendRequest({ method: 'get', options })
|
|
322
|
+
}
|
|
323
|
+
|
|
320
324
|
// scan
|
|
321
325
|
const createGetScanIdURL = config => {
|
|
322
326
|
return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`
|
|
@@ -370,20 +374,22 @@ function createLibraryVulnerabilitiesUrl(config) {
|
|
|
370
374
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`
|
|
371
375
|
}
|
|
372
376
|
|
|
373
|
-
function
|
|
374
|
-
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`
|
|
377
|
+
function createSpecificReportUrl(config, reportId) {
|
|
378
|
+
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}`
|
|
375
379
|
}
|
|
376
380
|
|
|
377
|
-
function
|
|
378
|
-
return
|
|
381
|
+
function createSpecificReportWithProdUrl(config, reportId) {
|
|
382
|
+
return createSpecificReportUrl(config, reportId).concat(
|
|
383
|
+
`?nodesToInclude=PROD`
|
|
384
|
+
)
|
|
379
385
|
}
|
|
380
386
|
|
|
381
387
|
function createDataUrl() {
|
|
382
388
|
return `https://ardy.contrastsecurity.com/production`
|
|
383
389
|
}
|
|
384
390
|
|
|
385
|
-
|
|
386
|
-
return `${
|
|
391
|
+
function createSbomCycloneDXUrl(config) {
|
|
392
|
+
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`
|
|
387
393
|
}
|
|
388
394
|
|
|
389
395
|
module.exports = HTTPClient
|