@contrast/contrast 1.0.3 → 1.0.6
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 +20 -14
- package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
- package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +6 -14
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +29 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +101 -234
- 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/reportOutputModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +12 -0
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +13 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +99 -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/scan/processScan.js +10 -6
- package/dist/commands/scan/sca/scaAnalysis.js +49 -0
- package/dist/common/HTTPClient.js +18 -26
- package/dist/common/errorHandling.js +7 -17
- package/dist/common/versionChecker.js +14 -12
- package/dist/constants/constants.js +24 -2
- package/dist/constants/lambda.js +3 -1
- package/dist/constants/locales.js +42 -42
- package/dist/constants.js +25 -1
- package/dist/index.js +2 -2
- package/dist/lambda/help.js +22 -14
- package/dist/lambda/lambda.js +6 -0
- package/dist/scaAnalysis/common/formatMessage.js +19 -0
- package/dist/scaAnalysis/common/treeUpload.js +29 -0
- package/dist/scaAnalysis/go/goAnalysis.js +17 -0
- package/dist/scaAnalysis/go/goParseDeps.js +158 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +23 -0
- package/dist/scaAnalysis/java/analysis.js +108 -0
- package/dist/scaAnalysis/java/index.js +18 -0
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +339 -0
- package/dist/scan/autoDetection.js +46 -1
- package/dist/scan/fileUtils.js +73 -1
- package/dist/scan/formatScanOutput.js +215 -0
- package/dist/scan/help.js +3 -1
- 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/scan.js +27 -126
- package/dist/scan/scanConfig.js +1 -1
- package/dist/scan/scanController.js +11 -5
- package/dist/scan/scanResults.js +15 -19
- package/dist/utils/getConfig.js +3 -0
- package/dist/utils/oraWrapper.js +5 -1
- 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} +11 -21
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +72 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +204 -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/reportOutputModel.ts +29 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +13 -0
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +16 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +116 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -22
- package/src/commands/audit/auditConfig.ts +12 -3
- package/src/commands/audit/auditController.ts +20 -5
- package/src/commands/audit/processAudit.ts +3 -0
- package/src/commands/scan/processScan.js +13 -9
- package/src/commands/scan/sca/scaAnalysis.js +75 -0
- package/src/common/HTTPClient.js +31 -38
- package/src/common/errorHandling.ts +7 -25
- package/src/common/versionChecker.ts +24 -22
- package/src/constants/constants.js +24 -2
- package/src/constants/lambda.js +3 -1
- package/src/constants/locales.js +47 -56
- package/src/constants.js +29 -1
- package/src/index.ts +2 -3
- package/src/lambda/help.ts +22 -14
- package/src/lambda/lambda.ts +8 -0
- package/src/scaAnalysis/common/formatMessage.js +20 -0
- package/src/scaAnalysis/common/treeUpload.js +30 -0
- package/src/scaAnalysis/go/goAnalysis.js +20 -0
- package/src/scaAnalysis/go/goParseDeps.js +203 -0
- package/src/scaAnalysis/go/goReadDepFile.js +32 -0
- package/src/scaAnalysis/java/analysis.js +143 -0
- package/src/scaAnalysis/java/index.js +21 -0
- package/src/scaAnalysis/java/javaBuildDepsParser.js +404 -0
- package/src/scan/autoDetection.js +54 -1
- package/src/scan/fileUtils.js +91 -1
- package/src/scan/formatScanOutput.ts +250 -0
- package/src/scan/help.js +3 -1
- 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/scan.ts +63 -0
- package/src/scan/scanConfig.js +1 -1
- package/src/scan/scanController.js +15 -7
- package/src/scan/scanResults.js +21 -18
- package/src/utils/getConfig.ts +10 -0
- package/src/utils/oraWrapper.js +6 -1
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
- 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/scan/scan.js +0 -195
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLibraryHeader,
|
|
3
|
+
getReport,
|
|
4
|
+
printVulnerabilityResponse
|
|
5
|
+
} from './commonReportingFunctions'
|
|
6
|
+
import {
|
|
7
|
+
convertGenericToTypedLibraries,
|
|
8
|
+
severityCountAllLibraries
|
|
9
|
+
} from './utils/reportUtils'
|
|
10
|
+
|
|
11
|
+
export async function vulnerabilityReport(
|
|
12
|
+
analysis: any,
|
|
13
|
+
applicationId: string,
|
|
14
|
+
reportId: string
|
|
15
|
+
) {
|
|
16
|
+
const reportResponse = await getReport(analysis.config, reportId)
|
|
17
|
+
|
|
18
|
+
if (reportResponse !== undefined) {
|
|
19
|
+
const id = applicationId
|
|
20
|
+
const name = analysis.config.applicationName
|
|
21
|
+
formatVulnerabilityOutput(
|
|
22
|
+
reportResponse.vulnerabilities,
|
|
23
|
+
id,
|
|
24
|
+
name,
|
|
25
|
+
analysis.config
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function formatVulnerabilityOutput(
|
|
31
|
+
libraryVulnerabilityResponse: any,
|
|
32
|
+
id: string,
|
|
33
|
+
name: string,
|
|
34
|
+
config: any
|
|
35
|
+
) {
|
|
36
|
+
const vulnerableLibraries = convertGenericToTypedLibraries(
|
|
37
|
+
libraryVulnerabilityResponse
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const numberOfVulnerableLibraries = vulnerableLibraries.length
|
|
41
|
+
let numberOfCves = 0
|
|
42
|
+
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length))
|
|
43
|
+
|
|
44
|
+
createLibraryHeader(id, numberOfVulnerableLibraries, numberOfCves)
|
|
45
|
+
|
|
46
|
+
const hasSomeVulnerabilitiesReported = printVulnerabilityResponse(
|
|
47
|
+
vulnerableLibraries,
|
|
48
|
+
config
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return [
|
|
52
|
+
hasSomeVulnerabilitiesReported,
|
|
53
|
+
numberOfCves,
|
|
54
|
+
severityCountAllLibraries(vulnerableLibraries)
|
|
55
|
+
]
|
|
56
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReportCVEModel,
|
|
3
|
+
ReportLibraryModel
|
|
4
|
+
} from '../models/reportLibraryModel'
|
|
5
|
+
import { ReportSeverityModel } from '../models/reportSeverityModel'
|
|
6
|
+
import languageAnalysisEngine from '../../../languageAnalysisEngine/constants'
|
|
7
|
+
import {
|
|
8
|
+
CRITICAL_COLOUR,
|
|
9
|
+
CRITICAL_PRIORITY,
|
|
10
|
+
HIGH_COLOUR,
|
|
11
|
+
HIGH_PRIORITY,
|
|
12
|
+
LOW_COLOUR,
|
|
13
|
+
LOW_PRIORITY,
|
|
14
|
+
MEDIUM_COLOUR,
|
|
15
|
+
MEDIUM_PRIORITY,
|
|
16
|
+
NOTE_COLOUR,
|
|
17
|
+
NOTE_PRIORITY
|
|
18
|
+
} from '../../../../constants/constants'
|
|
19
|
+
import { orderBy } from 'lodash'
|
|
20
|
+
import {SeverityCountModel} from "../models/severityCountModel";
|
|
21
|
+
const {
|
|
22
|
+
supportedLanguages: { GO }
|
|
23
|
+
} = languageAnalysisEngine
|
|
24
|
+
|
|
25
|
+
export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
|
|
26
|
+
const mappedToReportSeverityModels = cveArray.map(cve => findCVESeverity(cve))
|
|
27
|
+
|
|
28
|
+
//order and get first
|
|
29
|
+
return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
export function findCVESeveritiesAndOrderByHighestPriority(cves: ReportCVEModel[]) {
|
|
34
|
+
return orderBy(cves.map(cve => findCVESeverity(cve)), ['priority'], ['asc'])
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function findCVESeverity(cve: ReportCVEModel) {
|
|
38
|
+
const cveName = cve.name as string
|
|
39
|
+
if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
|
|
40
|
+
return new ReportSeverityModel('CRITICAL', CRITICAL_PRIORITY, CRITICAL_COLOUR, cveName)
|
|
41
|
+
} else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
|
|
42
|
+
return new ReportSeverityModel('HIGH', HIGH_PRIORITY, HIGH_COLOUR, cveName)
|
|
43
|
+
} else if (cve.cvss3SeverityCode === 'MEDIUM' || cve.severityCode === 'MEDIUM') {
|
|
44
|
+
return new ReportSeverityModel('MEDIUM', MEDIUM_PRIORITY, MEDIUM_COLOUR, cveName)
|
|
45
|
+
} else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
|
|
46
|
+
return new ReportSeverityModel('LOW', LOW_PRIORITY, LOW_COLOUR, cveName)
|
|
47
|
+
} else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
|
|
48
|
+
return new ReportSeverityModel('NOTE', NOTE_PRIORITY, NOTE_COLOUR, cveName)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function convertGenericToTypedLibraries(libraries: any) {
|
|
53
|
+
return Object.entries(libraries).map(([name, cveArray]) => {
|
|
54
|
+
return new ReportLibraryModel(name, cveArray as ReportCVEModel[])
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function severityCountAllLibraries(vulnerableLibraries: ReportLibraryModel[]) {
|
|
59
|
+
const severityCount = new SeverityCountModel()
|
|
60
|
+
vulnerableLibraries.forEach(lib => severityCountAllCVEs(lib.cveArray, severityCount))
|
|
61
|
+
return severityCount
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function severityCountAllCVEs(cveArray: ReportCVEModel[], severityCount: SeverityCountModel) {
|
|
65
|
+
const severityCountInner = severityCount
|
|
66
|
+
cveArray.forEach(cve => severityCountSingleCVE(cve, severityCountInner))
|
|
67
|
+
return severityCountInner
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function severityCountSingleCVE(cve: ReportCVEModel, severityCount: SeverityCountModel) {
|
|
71
|
+
if (
|
|
72
|
+
cve.cvss3SeverityCode === 'CRITICAL' ||
|
|
73
|
+
cve.severityCode === 'CRITICAL'
|
|
74
|
+
) {
|
|
75
|
+
severityCount.critical += 1
|
|
76
|
+
} else if (
|
|
77
|
+
cve.cvss3SeverityCode === 'HIGH' ||
|
|
78
|
+
cve.severityCode === 'HIGH'
|
|
79
|
+
) {
|
|
80
|
+
severityCount.high += 1
|
|
81
|
+
} else if (
|
|
82
|
+
cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
83
|
+
cve.severityCode === 'MEDIUM'
|
|
84
|
+
) {
|
|
85
|
+
severityCount.medium += 1
|
|
86
|
+
} else if (
|
|
87
|
+
cve.cvss3SeverityCode === 'LOW' ||
|
|
88
|
+
cve.severityCode === 'LOW'
|
|
89
|
+
) {
|
|
90
|
+
severityCount.low += 1
|
|
91
|
+
} else if (
|
|
92
|
+
cve.cvss3SeverityCode === 'NOTE' ||
|
|
93
|
+
cve.severityCode === 'NOTE'
|
|
94
|
+
) {
|
|
95
|
+
severityCount.note += 1
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return severityCount
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function findNameAndVersion(library: ReportLibraryModel, config: any) {
|
|
102
|
+
if (config.language.toUpperCase() === GO) {
|
|
103
|
+
const nameVersion = library.name.split('@')
|
|
104
|
+
const name = nameVersion[0]
|
|
105
|
+
const version = nameVersion[1]
|
|
106
|
+
|
|
107
|
+
return { name, version }
|
|
108
|
+
} else {
|
|
109
|
+
const splitLibraryName = library.name.split('/')
|
|
110
|
+
const nameVersion = splitLibraryName[1].split('@')
|
|
111
|
+
const name = nameVersion[0]
|
|
112
|
+
const version = nameVersion[1]
|
|
113
|
+
|
|
114
|
+
return { name, version }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -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,34 @@
|
|
|
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)
|
|
10
13
|
if (!appID && config.applicationName) {
|
|
11
14
|
return await catalogueApplication(config)
|
|
12
15
|
}
|
|
16
|
+
if (!appID && !config.applicationName) {
|
|
17
|
+
config.applicationName = uuidv4()
|
|
18
|
+
return await catalogueApplication(config)
|
|
19
|
+
}
|
|
20
|
+
// @ts-ignore
|
|
13
21
|
} catch (e) {
|
|
14
|
-
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
if (e.toString().includes('tunneling socket could not be established')) {
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
console.log(e.message.toString())
|
|
26
|
+
console.log(
|
|
27
|
+
'There seems to be an issue with your proxy, please check and try again'
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
process.exit(1)
|
|
15
31
|
}
|
|
16
|
-
console.log(appID)
|
|
17
32
|
return appID
|
|
18
33
|
}
|
|
19
34
|
|
|
@@ -1,18 +1,22 @@
|
|
|
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')
|
|
2
|
+
const { startScan } = require('../../scan/scanController')
|
|
5
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')
|
|
6
7
|
|
|
7
8
|
const processScan = async argvMain => {
|
|
8
9
|
let config = scanConfig.getScanConfig(argvMain)
|
|
10
|
+
// console.log(config)
|
|
11
|
+
//try SCA analysis first
|
|
12
|
+
if (config.experimental) {
|
|
13
|
+
await processSca(config)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let scanResults = new ScanResultsModel(await startScan(config))
|
|
9
17
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
formatScanOutput(
|
|
13
|
-
scanResults?.projectOverview,
|
|
14
|
-
scanResults?.scanResultsInstances
|
|
15
|
-
)
|
|
18
|
+
if (scanResults.scanResultsInstances !== undefined) {
|
|
19
|
+
formatScanOutput(scanResults)
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
if (config.save !== undefined) {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const autoDetection = require('../../../scan/autoDetection')
|
|
2
|
+
const javaAnalysis = require('../../../scaAnalysis/java')
|
|
3
|
+
const treeUpload = require('../../../scaAnalysis/common/treeUpload')
|
|
4
|
+
const {
|
|
5
|
+
manualDetectAuditFilesAndLanguages
|
|
6
|
+
} = require('../../../scan/autoDetection')
|
|
7
|
+
const auditController = require('../../audit/auditController')
|
|
8
|
+
const {
|
|
9
|
+
supportedLanguages: { JAVA, GO }
|
|
10
|
+
} = require('../../../audit/languageAnalysisEngine/constants')
|
|
11
|
+
const goAnalysis = require('../../../scaAnalysis/go/goAnalysis')
|
|
12
|
+
|
|
13
|
+
const processSca = async config => {
|
|
14
|
+
let filesFound
|
|
15
|
+
if (config.projectPath) {
|
|
16
|
+
filesFound = await manualDetectAuditFilesAndLanguages(config.projectPath)
|
|
17
|
+
} else {
|
|
18
|
+
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// files found looks like [ { javascript: [ Array ] } ]
|
|
22
|
+
//check we have the language and call the right analyser
|
|
23
|
+
//refactor new analyser and see if we can clean it up
|
|
24
|
+
let messageToSend = undefined
|
|
25
|
+
if (filesFound.length === 1) {
|
|
26
|
+
switch (Object.keys(filesFound[0])[0]) {
|
|
27
|
+
case JAVA:
|
|
28
|
+
messageToSend = javaAnalysis.javaAnalysis(config, filesFound[0])
|
|
29
|
+
config.language = JAVA
|
|
30
|
+
break
|
|
31
|
+
// case 'javascript':
|
|
32
|
+
// // code block
|
|
33
|
+
// break;
|
|
34
|
+
// case 'dotnet':
|
|
35
|
+
// // code block
|
|
36
|
+
// break;
|
|
37
|
+
// case 'python':
|
|
38
|
+
// // code block
|
|
39
|
+
// break;
|
|
40
|
+
// case 'ruby':
|
|
41
|
+
// // code block
|
|
42
|
+
// break;
|
|
43
|
+
// case 'php':
|
|
44
|
+
// // code block
|
|
45
|
+
// break;
|
|
46
|
+
case GO:
|
|
47
|
+
messageToSend = goAnalysis.goAnalysis(config, filesFound[0])
|
|
48
|
+
config.language = GO
|
|
49
|
+
break
|
|
50
|
+
default:
|
|
51
|
+
//something is wrong
|
|
52
|
+
console.log('language detected not supported')
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!config.applicationId) {
|
|
57
|
+
config.applicationId = await auditController.dealWithNoAppId(config)
|
|
58
|
+
}
|
|
59
|
+
//send message to TS
|
|
60
|
+
console.log('processing dependencies')
|
|
61
|
+
const response = await treeUpload.commonSendSnapShot(messageToSend, config)
|
|
62
|
+
} else {
|
|
63
|
+
if (filesFound.length === 0) {
|
|
64
|
+
console.log('no compatible dependency files detected. Continuing...')
|
|
65
|
+
} else {
|
|
66
|
+
console.log(
|
|
67
|
+
'multiple language files detected, please use --project-path to specify a directory or the file where dependencies are declared'
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
processSca
|
|
75
|
+
}
|
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
|
}
|
|
@@ -188,6 +190,9 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
|
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
193
|
+
if (config.language.toUpperCase() === 'RUBY') {
|
|
194
|
+
//console.log('sendSnapshot requestBody', requestBody.snapshot.ruby)
|
|
195
|
+
}
|
|
191
196
|
const options = _.cloneDeep(this.requestOptions)
|
|
192
197
|
let url = createSnapshotURL(config)
|
|
193
198
|
options.url = url
|
|
@@ -195,32 +200,22 @@ HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
|
195
200
|
return requestUtils.sendRequest({ method: 'post', options })
|
|
196
201
|
}
|
|
197
202
|
|
|
198
|
-
HTTPClient.prototype.
|
|
199
|
-
const options = _.cloneDeep(this.requestOptions)
|
|
200
|
-
let url = createReportUrl(config)
|
|
201
|
-
options.url = url
|
|
202
|
-
|
|
203
|
-
return requestUtils.sendRequest({ method: 'get', options })
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
HTTPClient.prototype.getSpecificReport = function getSpecificReport(
|
|
207
|
-
config,
|
|
208
|
-
reportId
|
|
209
|
-
) {
|
|
203
|
+
HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
210
204
|
const options = _.cloneDeep(this.requestOptions)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
205
|
+
if (config.ignoreDev) {
|
|
206
|
+
options.url = createSpecificReportWithProdUrl(config, reportId)
|
|
207
|
+
} else {
|
|
208
|
+
options.url = createSpecificReportUrl(config, reportId)
|
|
209
|
+
}
|
|
214
210
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
215
211
|
}
|
|
216
212
|
|
|
217
213
|
HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(
|
|
218
|
-
|
|
219
|
-
|
|
214
|
+
config,
|
|
215
|
+
requestBody
|
|
220
216
|
) {
|
|
221
217
|
const options = _.cloneDeep(this.requestOptions)
|
|
222
|
-
|
|
223
|
-
options.url = url
|
|
218
|
+
options.url = createLibraryVulnerabilitiesUrl(config)
|
|
224
219
|
options.body = requestBody
|
|
225
220
|
|
|
226
221
|
return requestUtils.sendRequest({ method: 'put', options })
|
|
@@ -233,16 +228,16 @@ HTTPClient.prototype.getAppId = function getAppId(config) {
|
|
|
233
228
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
234
229
|
}
|
|
235
230
|
|
|
236
|
-
HTTPClient.prototype.getDependencyTree = function getReport(
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
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
|
+
// }
|
|
246
241
|
|
|
247
242
|
// serverless - lambda
|
|
248
243
|
function getServerlessHost(config = {}) {
|
|
@@ -379,22 +374,20 @@ function createLibraryVulnerabilitiesUrl(config) {
|
|
|
379
374
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`
|
|
380
375
|
}
|
|
381
376
|
|
|
382
|
-
function
|
|
383
|
-
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}`
|
|
384
379
|
}
|
|
385
380
|
|
|
386
|
-
function
|
|
387
|
-
return
|
|
381
|
+
function createSpecificReportWithProdUrl(config, reportId) {
|
|
382
|
+
return createSpecificReportUrl(config, reportId).concat(
|
|
383
|
+
`?nodesToInclude=PROD`
|
|
384
|
+
)
|
|
388
385
|
}
|
|
389
386
|
|
|
390
387
|
function createDataUrl() {
|
|
391
388
|
return `https://ardy.contrastsecurity.com/production`
|
|
392
389
|
}
|
|
393
390
|
|
|
394
|
-
const createGetDependencyTree = (protocol, orgUuid, appId, reportId) => {
|
|
395
|
-
return `${protocol}/Contrast/api/ng/sca/organizations/${orgUuid}/applications/${appId}/reports/${reportId}`
|
|
396
|
-
}
|
|
397
|
-
|
|
398
391
|
function createSbomCycloneDXUrl(config) {
|
|
399
392
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`
|
|
400
393
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import i18n from 'i18n'
|
|
2
|
-
import { sortBy } from 'lodash'
|
|
3
2
|
|
|
4
3
|
const handleResponseErrors = (res: any, api: string) => {
|
|
5
4
|
if (res.statusCode === 400) {
|
|
@@ -28,30 +27,15 @@ const libraryAnalysisError = () => {
|
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
const snapshotFailureError = () => {
|
|
31
|
-
console.log(
|
|
32
|
-
'\n ******************************** ' +
|
|
33
|
-
i18n.__('snapshotFailureHeader') +
|
|
34
|
-
' *********************************\n' +
|
|
35
|
-
i18n.__('snapshotFailureMessage')
|
|
36
|
-
)
|
|
30
|
+
console.log(i18n.__('snapshotFailureMessage'))
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
const vulnerabilitiesFailureError = () => {
|
|
40
|
-
console.log(
|
|
41
|
-
'\n ******************************** ' +
|
|
42
|
-
i18n.__('snapshotFailureHeader') +
|
|
43
|
-
' *********************************\n' +
|
|
44
|
-
i18n.__('vulnerabilitiesFailureMessage')
|
|
45
|
-
)
|
|
34
|
+
console.log(i18n.__('vulnerabilitiesFailureMessage'))
|
|
46
35
|
}
|
|
47
36
|
|
|
48
37
|
const reportFailureError = () => {
|
|
49
|
-
console.log(
|
|
50
|
-
'\n ******************************** ' +
|
|
51
|
-
i18n.__('snapshotFailureHeader') +
|
|
52
|
-
' *********************************\n' +
|
|
53
|
-
i18n.__('reportFailureMessage')
|
|
54
|
-
)
|
|
38
|
+
console.log(i18n.__('auditReportFailureMessage'))
|
|
55
39
|
}
|
|
56
40
|
|
|
57
41
|
const genericError = (missingCliOption: string) => {
|
|
@@ -80,10 +64,6 @@ const proxyError = () => {
|
|
|
80
64
|
generalError('proxyErrorHeader', 'proxyErrorMessage')
|
|
81
65
|
}
|
|
82
66
|
|
|
83
|
-
const hostWarningError = () => {
|
|
84
|
-
console.log(i18n.__('snapshotHostMessage'))
|
|
85
|
-
}
|
|
86
|
-
|
|
87
67
|
const failOptionError = () => {
|
|
88
68
|
console.log(
|
|
89
69
|
'\n ******************************** ' +
|
|
@@ -153,10 +133,12 @@ export {
|
|
|
153
133
|
forbiddenError,
|
|
154
134
|
proxyError,
|
|
155
135
|
failOptionError,
|
|
156
|
-
hostWarningError,
|
|
157
136
|
generalError,
|
|
158
137
|
getErrorMessage,
|
|
159
138
|
handleResponseErrors,
|
|
160
139
|
libraryAnalysisError,
|
|
161
|
-
findCommandOnError
|
|
140
|
+
findCommandOnError,
|
|
141
|
+
snapshotFailureError,
|
|
142
|
+
vulnerabilitiesFailureError,
|
|
143
|
+
reportFailureError
|
|
162
144
|
}
|
|
@@ -4,33 +4,35 @@ import boxen from 'boxen'
|
|
|
4
4
|
import chalk from 'chalk'
|
|
5
5
|
import semver from 'semver'
|
|
6
6
|
|
|
7
|
-
export async function findLatestCLIVersion() {
|
|
8
|
-
|
|
7
|
+
export async function findLatestCLIVersion(updateMessageHidden: boolean) {
|
|
8
|
+
if (!updateMessageHidden) {
|
|
9
|
+
const latestCLIVersion = await latestVersion('@contrast/contrast')
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
if (semver.lt(APP_VERSION, latestCLIVersion)) {
|
|
12
|
+
const updateAvailableMessage = `Update available ${chalk.yellow(
|
|
13
|
+
APP_VERSION
|
|
14
|
+
)} → ${chalk.green(latestCLIVersion)}`
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const npmUpdateAvailableCommand = `Run ${chalk.cyan(
|
|
17
|
+
'npm i @contrast/contrast -g'
|
|
18
|
+
)} to update via npm`
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const homebrewUpdateAvailableCommand = `Run ${chalk.cyan(
|
|
21
|
+
'brew install contrastsecurity/tap/contrast'
|
|
22
|
+
)} to update via brew`
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
console.log(
|
|
25
|
+
boxen(
|
|
26
|
+
`${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`,
|
|
27
|
+
{
|
|
28
|
+
titleAlignment: 'center',
|
|
29
|
+
margin: 1,
|
|
30
|
+
padding: 1,
|
|
31
|
+
align: 'center'
|
|
32
|
+
}
|
|
33
|
+
)
|
|
32
34
|
)
|
|
33
|
-
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|