@contrast/contrast 1.0.5 → 1.0.8
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 +0 -5
- package/dist/audit/autodetection/autoDetectLanguage.js +3 -3
- package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +9 -9
- package/dist/audit/languageAnalysisEngine/index.js +2 -2
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +6 -27
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -5
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +99 -20
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +3 -1
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +16 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +35 -14
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +58 -47
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
- package/dist/audit/save.js +29 -0
- package/dist/commands/audit/auditController.js +22 -6
- package/dist/commands/audit/help.js +24 -1
- package/dist/commands/audit/processAudit.js +8 -2
- package/dist/commands/audit/saveFile.js +7 -3
- package/dist/commands/scan/processScan.js +1 -1
- package/dist/commands/scan/sca/scaAnalysis.js +48 -11
- package/dist/common/HTTPClient.js +56 -15
- package/dist/common/errorHandling.js +6 -1
- package/dist/common/versionChecker.js +20 -5
- package/dist/constants/constants.js +13 -3
- package/dist/constants/locales.js +15 -12
- package/dist/constants.js +9 -4
- package/dist/index.js +4 -3
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +35 -4
- package/dist/lambda/types.js +13 -0
- package/dist/sbom/generateSbom.js +4 -3
- package/dist/scaAnalysis/common/formatMessage.js +46 -1
- package/dist/scaAnalysis/common/treeUpload.js +1 -3
- package/dist/scaAnalysis/go/goAnalysis.js +17 -0
- package/dist/scaAnalysis/go/goParseDeps.js +158 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +21 -0
- package/dist/scaAnalysis/java/analysis.js +11 -22
- package/dist/scaAnalysis/java/index.js +6 -6
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +14 -1
- package/dist/scaAnalysis/javascript/analysis.js +110 -0
- package/dist/scaAnalysis/javascript/index.js +41 -0
- package/dist/scaAnalysis/php/analysis.js +89 -0
- package/dist/scaAnalysis/php/index.js +10 -0
- package/dist/scaAnalysis/python/analysis.js +42 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +226 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +8 -4
- package/dist/scan/fileUtils.js +26 -8
- package/dist/scan/formatScanOutput.js +18 -17
- package/dist/scan/models/groupedResultsModel.js +1 -1
- package/dist/scan/models/scanResultsModel.js +3 -1
- package/dist/scan/populateProjectIdAndProjectName.js +2 -1
- package/dist/scan/scan.js +5 -3
- package/dist/scan/scanConfig.js +6 -1
- package/dist/scan/scanController.js +26 -6
- package/dist/scan/scanResults.js +20 -6
- package/dist/utils/commonApi.js +4 -1
- package/dist/utils/filterProjectPath.js +7 -2
- package/dist/utils/oraWrapper.js +5 -1
- package/package.json +13 -9
- package/src/audit/autodetection/autoDetectLanguage.ts +3 -3
- package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +11 -11
- package/src/audit/languageAnalysisEngine/index.js +2 -2
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +11 -31
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +35 -32
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +179 -25
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +12 -3
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +20 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +50 -18
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +88 -66
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
- package/src/audit/save.js +32 -0
- package/src/commands/audit/auditController.ts +23 -15
- package/src/commands/audit/help.ts +24 -1
- package/src/commands/audit/processAudit.ts +7 -4
- package/src/commands/audit/saveFile.ts +5 -1
- package/src/commands/scan/processScan.js +2 -1
- package/src/commands/scan/sca/scaAnalysis.js +70 -29
- package/src/common/HTTPClient.js +72 -25
- package/src/common/errorHandling.ts +10 -1
- package/src/common/versionChecker.ts +24 -5
- package/src/constants/constants.js +13 -3
- package/src/constants/locales.js +15 -12
- package/src/constants.js +9 -4
- package/src/index.ts +5 -3
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +37 -17
- package/src/lambda/types.ts +35 -0
- package/src/lambda/utils.ts +2 -7
- package/src/sbom/generateSbom.ts +1 -1
- package/src/scaAnalysis/common/formatMessage.js +51 -1
- package/src/scaAnalysis/common/treeUpload.js +1 -6
- package/src/scaAnalysis/go/goAnalysis.js +19 -0
- package/src/scaAnalysis/go/goParseDeps.js +203 -0
- package/src/scaAnalysis/go/goReadDepFile.js +30 -0
- package/src/scaAnalysis/java/analysis.js +15 -32
- package/src/scaAnalysis/java/index.js +6 -6
- package/src/scaAnalysis/java/javaBuildDepsParser.js +15 -2
- package/src/scaAnalysis/javascript/analysis.js +127 -0
- package/src/scaAnalysis/javascript/index.js +56 -0
- package/src/scaAnalysis/php/analysis.js +98 -0
- package/src/scaAnalysis/php/index.js +11 -0
- package/src/scaAnalysis/python/analysis.js +49 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +282 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +11 -7
- package/src/scan/fileUtils.js +27 -8
- package/src/scan/formatScanOutput.ts +26 -18
- package/src/scan/models/groupedResultsModel.ts +3 -3
- package/src/scan/models/resultContentModel.ts +1 -1
- package/src/scan/models/scanResultsModel.ts +5 -2
- package/src/scan/populateProjectIdAndProjectName.js +3 -1
- package/src/scan/scan.ts +8 -6
- package/src/scan/scanConfig.js +5 -1
- package/src/scan/scanController.js +30 -9
- package/src/scan/scanResults.js +31 -10
- package/src/utils/commonApi.js +4 -1
- package/src/utils/filterProjectPath.js +6 -2
- package/src/utils/oraWrapper.js +6 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class SeverityCountModel {
|
|
2
|
+
critical!: number
|
|
3
|
+
high!: number
|
|
4
|
+
medium!: number
|
|
5
|
+
low!: number
|
|
6
|
+
note!: number
|
|
7
|
+
|
|
8
|
+
//needed as default to stop NaN when new object constructed
|
|
9
|
+
constructor() {
|
|
10
|
+
this.critical = 0
|
|
11
|
+
this.high = 0
|
|
12
|
+
this.medium = 0
|
|
13
|
+
this.low = 0
|
|
14
|
+
this.note = 0
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get getTotal(): number {
|
|
18
|
+
return this.critical + this.high + this.medium + this.low + this.note
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -4,9 +4,11 @@ import {
|
|
|
4
4
|
printVulnerabilityResponse
|
|
5
5
|
} from './commonReportingFunctions'
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
convertGenericToTypedLibraryVulns,
|
|
8
|
+
severityCountAllLibraries
|
|
9
9
|
} from './utils/reportUtils'
|
|
10
|
+
import i18n from 'i18n'
|
|
11
|
+
import chalk from 'chalk'
|
|
10
12
|
|
|
11
13
|
export async function vulnerabilityReport(
|
|
12
14
|
analysis: any,
|
|
@@ -17,11 +19,9 @@ export async function vulnerabilityReport(
|
|
|
17
19
|
|
|
18
20
|
if (reportResponse !== undefined) {
|
|
19
21
|
const id = applicationId
|
|
20
|
-
const name = analysis.config.applicationName
|
|
21
22
|
formatVulnerabilityOutput(
|
|
22
23
|
reportResponse.vulnerabilities,
|
|
23
24
|
id,
|
|
24
|
-
name,
|
|
25
25
|
analysis.config
|
|
26
26
|
)
|
|
27
27
|
}
|
|
@@ -30,27 +30,59 @@ export async function vulnerabilityReport(
|
|
|
30
30
|
export function formatVulnerabilityOutput(
|
|
31
31
|
libraryVulnerabilityResponse: any,
|
|
32
32
|
id: string,
|
|
33
|
-
name: string,
|
|
34
33
|
config: any
|
|
35
34
|
) {
|
|
36
|
-
const vulnerableLibraries =
|
|
35
|
+
const vulnerableLibraries = convertGenericToTypedLibraryVulns(
|
|
37
36
|
libraryVulnerabilityResponse
|
|
38
37
|
)
|
|
39
38
|
|
|
40
39
|
const numberOfVulnerableLibraries = vulnerableLibraries.length
|
|
41
|
-
let numberOfCves = 0
|
|
42
|
-
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length))
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
if (numberOfVulnerableLibraries === 0) {
|
|
42
|
+
console.log(i18n.__('scanNoVulnerabilitiesFound'))
|
|
43
|
+
console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'))
|
|
44
|
+
console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'))
|
|
45
|
+
console.log(
|
|
46
|
+
chalk.bold(`Found ${numberOfVulnerableLibraries} vulnerabilities`)
|
|
47
|
+
)
|
|
48
|
+
console.log(
|
|
49
|
+
i18n.__(
|
|
50
|
+
'foundDetailedVulnerabilities',
|
|
51
|
+
String(0),
|
|
52
|
+
String(0),
|
|
53
|
+
String(0),
|
|
54
|
+
String(0),
|
|
55
|
+
String(0)
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
} else {
|
|
59
|
+
let numberOfCves = 0
|
|
60
|
+
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length))
|
|
45
61
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
createLibraryHeader(id, numberOfVulnerableLibraries, numberOfCves)
|
|
63
|
+
|
|
64
|
+
const hasSomeVulnerabilitiesReported = printVulnerabilityResponse(
|
|
65
|
+
vulnerableLibraries,
|
|
66
|
+
config
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
return [
|
|
70
|
+
hasSomeVulnerabilitiesReported,
|
|
71
|
+
numberOfCves,
|
|
72
|
+
severityCountAllLibraries(vulnerableLibraries)
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function vulnerabilityReportV2(config: any, reportId: string) {
|
|
78
|
+
const reportResponse = await getReport(config, reportId)
|
|
50
79
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
80
|
+
if (reportResponse !== undefined) {
|
|
81
|
+
const name = config.applicationName
|
|
82
|
+
formatVulnerabilityOutput(
|
|
83
|
+
reportResponse.vulnerabilities,
|
|
84
|
+
config.applicationId,
|
|
85
|
+
config
|
|
86
|
+
)
|
|
87
|
+
}
|
|
56
88
|
}
|
|
@@ -4,90 +4,112 @@ import {
|
|
|
4
4
|
} from '../models/reportLibraryModel'
|
|
5
5
|
import { ReportSeverityModel } from '../models/reportSeverityModel'
|
|
6
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'
|
|
7
21
|
const {
|
|
8
22
|
supportedLanguages: { GO }
|
|
9
23
|
} = languageAnalysisEngine
|
|
10
24
|
|
|
11
25
|
export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
export function findCVESeveritiesAndOrderByHighestPriority(
|
|
33
|
+
cves: ReportCVEModel[]
|
|
34
|
+
) {
|
|
35
|
+
return orderBy(
|
|
36
|
+
cves.map(cve => findCVESeverity(cve)),
|
|
37
|
+
['priority'],
|
|
38
|
+
['asc']
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function findCVESeverity(cve: ReportCVEModel) {
|
|
43
|
+
const cveName = cve.name as string
|
|
44
|
+
if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
|
|
45
|
+
return new ReportSeverityModel(
|
|
46
|
+
'CRITICAL',
|
|
47
|
+
CRITICAL_PRIORITY,
|
|
48
|
+
CRITICAL_COLOUR,
|
|
49
|
+
cveName
|
|
22
50
|
)
|
|
23
|
-
) {
|
|
24
|
-
return new ReportSeverityModel('HIGH',
|
|
51
|
+
} else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
|
|
52
|
+
return new ReportSeverityModel('HIGH', HIGH_PRIORITY, HIGH_COLOUR, cveName)
|
|
25
53
|
} else if (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
54
|
+
cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
55
|
+
cve.severityCode === 'MEDIUM'
|
|
29
56
|
) {
|
|
30
|
-
return new ReportSeverityModel(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
57
|
+
return new ReportSeverityModel(
|
|
58
|
+
'MEDIUM',
|
|
59
|
+
MEDIUM_PRIORITY,
|
|
60
|
+
MEDIUM_COLOUR,
|
|
61
|
+
cveName
|
|
34
62
|
)
|
|
35
|
-
) {
|
|
36
|
-
return new ReportSeverityModel('LOW',
|
|
37
|
-
} else if (
|
|
38
|
-
|
|
39
|
-
cve => cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE'
|
|
40
|
-
)
|
|
41
|
-
) {
|
|
42
|
-
return new ReportSeverityModel('NOTE', 5)
|
|
63
|
+
} else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
|
|
64
|
+
return new ReportSeverityModel('LOW', LOW_PRIORITY, LOW_COLOUR, cveName)
|
|
65
|
+
} else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
|
|
66
|
+
return new ReportSeverityModel('NOTE', NOTE_PRIORITY, NOTE_COLOUR, cveName)
|
|
43
67
|
}
|
|
44
68
|
}
|
|
45
69
|
|
|
46
|
-
export function
|
|
70
|
+
export function convertGenericToTypedLibraryVulns(libraries: any) {
|
|
47
71
|
return Object.entries(libraries).map(([name, cveArray]) => {
|
|
48
72
|
return new ReportLibraryModel(name, cveArray as ReportCVEModel[])
|
|
49
73
|
})
|
|
50
74
|
}
|
|
51
75
|
|
|
52
|
-
export function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
76
|
+
export function severityCountAllLibraries(
|
|
77
|
+
vulnerableLibraries: ReportLibraryModel[]
|
|
78
|
+
) {
|
|
79
|
+
const severityCount = new SeverityCountModel()
|
|
80
|
+
vulnerableLibraries.forEach(lib =>
|
|
81
|
+
severityCountAllCVEs(lib.cveArray, severityCount)
|
|
82
|
+
)
|
|
83
|
+
return severityCount
|
|
84
|
+
}
|
|
60
85
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
})
|
|
86
|
+
export function severityCountAllCVEs(
|
|
87
|
+
cveArray: ReportCVEModel[],
|
|
88
|
+
severityCount: SeverityCountModel
|
|
89
|
+
) {
|
|
90
|
+
const severityCountInner = severityCount
|
|
91
|
+
cveArray.forEach(cve => severityCountSingleCVE(cve, severityCountInner))
|
|
92
|
+
return severityCountInner
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function severityCountSingleCVE(
|
|
96
|
+
cve: ReportCVEModel,
|
|
97
|
+
severityCount: SeverityCountModel
|
|
98
|
+
) {
|
|
99
|
+
if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
|
|
100
|
+
severityCount.critical += 1
|
|
101
|
+
} else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
|
|
102
|
+
severityCount.high += 1
|
|
103
|
+
} else if (
|
|
104
|
+
cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
105
|
+
cve.severityCode === 'MEDIUM'
|
|
106
|
+
) {
|
|
107
|
+
severityCount.medium += 1
|
|
108
|
+
} else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
|
|
109
|
+
severityCount.low += 1
|
|
110
|
+
} else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
|
|
111
|
+
severityCount.note += 1
|
|
112
|
+
}
|
|
91
113
|
|
|
92
114
|
return severityCount
|
|
93
115
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
const { getHttpClient } = require('../../utils/commonApi')
|
|
2
1
|
const { handleResponseErrors } = require('../../common/errorHandling')
|
|
3
2
|
const { APP_VERSION } = require('../../constants/constants')
|
|
3
|
+
const commonApi = require('../../utils/commonApi')
|
|
4
|
+
const _ = require('lodash')
|
|
5
|
+
const oraFunctions = require('../../utils/oraWrapper')
|
|
6
|
+
const i18n = require('i18n')
|
|
7
|
+
const oraWrapper = require('../../utils/oraWrapper')
|
|
8
|
+
const requestUtils = require('../../utils/requestUtils')
|
|
9
|
+
const { performance } = require('perf_hooks')
|
|
4
10
|
|
|
5
11
|
const newSendSnapShot = async analysis => {
|
|
6
12
|
const analysisLanguage = analysis.config.language.toLowerCase()
|
|
@@ -10,7 +16,7 @@ const newSendSnapShot = async analysis => {
|
|
|
10
16
|
snapshot: { [analysisLanguage]: analysis[analysisLanguage] }
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
const client = getHttpClient(analysis.config)
|
|
19
|
+
const client = commonApi.getHttpClient(analysis.config)
|
|
14
20
|
|
|
15
21
|
return client
|
|
16
22
|
.sendSnapshot(requestBody, analysis.config)
|
|
@@ -26,6 +32,75 @@ const newSendSnapShot = async analysis => {
|
|
|
26
32
|
})
|
|
27
33
|
}
|
|
28
34
|
|
|
35
|
+
const pollSnapshotResults = async (config, snapshotId, client) => {
|
|
36
|
+
await requestUtils.sleep(5000)
|
|
37
|
+
return client
|
|
38
|
+
.getReportStatusById(config, snapshotId)
|
|
39
|
+
.then(res => {
|
|
40
|
+
return res
|
|
41
|
+
})
|
|
42
|
+
.catch(err => {
|
|
43
|
+
console.log(err)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const getTimeout = config => {
|
|
48
|
+
if (config.timeout) {
|
|
49
|
+
return config.timeout
|
|
50
|
+
} else {
|
|
51
|
+
if (config.verbose) {
|
|
52
|
+
console.log('Timeout set to 2 minutes')
|
|
53
|
+
}
|
|
54
|
+
return 120
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const pollForSnapshotCompletition = async (
|
|
59
|
+
config,
|
|
60
|
+
snapshotId,
|
|
61
|
+
reportSpinner
|
|
62
|
+
) => {
|
|
63
|
+
const client = commonApi.getHttpClient(config)
|
|
64
|
+
const startTime = performance.now()
|
|
65
|
+
const timeout = getTimeout(config)
|
|
66
|
+
|
|
67
|
+
let complete = false
|
|
68
|
+
if (!_.isNil(snapshotId)) {
|
|
69
|
+
while (!complete) {
|
|
70
|
+
let result = await pollSnapshotResults(config, snapshotId, client)
|
|
71
|
+
if (result.statusCode === 200) {
|
|
72
|
+
if (result.body.status === 'PROCESSED') {
|
|
73
|
+
complete = true
|
|
74
|
+
return result.body
|
|
75
|
+
}
|
|
76
|
+
if (result.body.status === 'FAILED') {
|
|
77
|
+
complete = true
|
|
78
|
+
if (config.debug) {
|
|
79
|
+
oraFunctions.failSpinner(
|
|
80
|
+
reportSpinner,
|
|
81
|
+
i18n.__('auditNotCompleted')
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
console.log(result.body.errorMessage)
|
|
85
|
+
oraWrapper.stopSpinner(reportSpinner)
|
|
86
|
+
console.log('Contrast audit finished')
|
|
87
|
+
process.exit(1)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const endTime = performance.now() - startTime
|
|
91
|
+
if (requestUtils.millisToSeconds(endTime) > timeout) {
|
|
92
|
+
oraFunctions.failSpinner(
|
|
93
|
+
reportSpinner,
|
|
94
|
+
'Contrast audit timed out at the specified ' + timeout + ' seconds.'
|
|
95
|
+
)
|
|
96
|
+
console.log('Please try again, allowing more time.')
|
|
97
|
+
process.exit(1)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
29
103
|
module.exports = {
|
|
30
|
-
newSendSnapShot: newSendSnapShot
|
|
104
|
+
newSendSnapShot: newSendSnapShot,
|
|
105
|
+
pollForSnapshotCompletition: pollForSnapshotCompletition
|
|
31
106
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
const chalk = require('chalk')
|
|
4
|
+
const save = require('../commands/audit/saveFile')
|
|
5
|
+
const sbom = require('../sbom/generateSbom')
|
|
6
|
+
|
|
7
|
+
async function auditSave(config) {
|
|
8
|
+
if (config.save) {
|
|
9
|
+
if (config.save.toLowerCase() === 'sbom') {
|
|
10
|
+
save.saveFile(config, await sbom.generateSbom(config))
|
|
11
|
+
|
|
12
|
+
const filename = `${config.applicationId}-sbom-cyclonedx.json`
|
|
13
|
+
if (fs.existsSync(filename)) {
|
|
14
|
+
console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`)
|
|
15
|
+
} else {
|
|
16
|
+
console.log(
|
|
17
|
+
chalk.yellow.bold(
|
|
18
|
+
`\n Unable to save ${filename} Software Bill of Materials (SBOM)`
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
console.log(i18n.__('auditBadFiletypeSpecifiedForSave'))
|
|
24
|
+
}
|
|
25
|
+
} else if (config.save === null) {
|
|
26
|
+
console.log(i18n.__('auditNoFiletypeSpecifiedForSave'))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
auditSave
|
|
32
|
+
}
|
|
@@ -3,27 +3,26 @@ import commonApi from '../../audit/languageAnalysisEngine/commonApi'
|
|
|
3
3
|
|
|
4
4
|
const identifyLanguageAE = require('./../../audit/languageAnalysisEngine')
|
|
5
5
|
const languageFactory = require('../../audit/languageAnalysisEngine/languageAnalysisFactory')
|
|
6
|
-
const { v4: uuidv4 } = require('uuid')
|
|
7
6
|
|
|
8
7
|
export const dealWithNoAppId = async (config: { [x: string]: string }) => {
|
|
9
8
|
let appID: string
|
|
10
9
|
try {
|
|
11
10
|
// @ts-ignore
|
|
12
11
|
appID = await commonApi.returnAppId(config)
|
|
13
|
-
// console.log('appid', appID)
|
|
14
12
|
if (!appID && config.applicationName) {
|
|
15
13
|
return await catalogueApplication(config)
|
|
16
14
|
}
|
|
17
15
|
if (!appID && !config.applicationName) {
|
|
18
|
-
config.applicationName =
|
|
19
|
-
|
|
16
|
+
config.applicationName = getAppName(config.file) as string
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
appID = await commonApi.returnAppId(config)
|
|
19
|
+
if (!appID) {
|
|
20
|
+
return await catalogueApplication(config)
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
} catch (e) {
|
|
23
|
-
// @ts-ignore
|
|
23
|
+
} catch (e: any) {
|
|
24
24
|
if (e.toString().includes('tunneling socket could not be established')) {
|
|
25
|
-
|
|
26
|
-
console.log(e.message)
|
|
25
|
+
console.log(e.message.toString())
|
|
27
26
|
console.log(
|
|
28
27
|
'There seems to be an issue with your proxy, please check and try again'
|
|
29
28
|
)
|
|
@@ -38,10 +37,19 @@ export const startAudit = async (config: { [key: string]: string }) => {
|
|
|
38
37
|
// @ts-ignore
|
|
39
38
|
config.applicationId = await dealWithNoAppId(config)
|
|
40
39
|
}
|
|
41
|
-
identifyLanguageAE(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
)
|
|
40
|
+
identifyLanguageAE(config.file, languageFactory, config.applicationId, config)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const getAppName = (file: string) => {
|
|
44
|
+
const last = file.charAt(file.length - 1)
|
|
45
|
+
if (last !== '/') {
|
|
46
|
+
return file.split('/').pop()
|
|
47
|
+
} else {
|
|
48
|
+
const str = removeLastChar(file)
|
|
49
|
+
return str.split('/').pop()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const removeLastChar = (str: string) => {
|
|
54
|
+
return str.substring(0, str.length - 1)
|
|
47
55
|
}
|
|
@@ -41,7 +41,30 @@ const auditUsageGuide = commandLineUsage([
|
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
header: i18n.__('constantsAuditOptions'),
|
|
44
|
-
optionList: constants.commandLineDefinitions.auditOptionDefinitions
|
|
44
|
+
optionList: constants.commandLineDefinitions.auditOptionDefinitions,
|
|
45
|
+
hide: [
|
|
46
|
+
'application-id',
|
|
47
|
+
'application-name',
|
|
48
|
+
'organization-id',
|
|
49
|
+
'api-key',
|
|
50
|
+
'authorization',
|
|
51
|
+
'host',
|
|
52
|
+
'proxy',
|
|
53
|
+
'help',
|
|
54
|
+
'ff',
|
|
55
|
+
'ignore-cert-errors',
|
|
56
|
+
'verbose',
|
|
57
|
+
'debug',
|
|
58
|
+
'experimental',
|
|
59
|
+
'tags',
|
|
60
|
+
'sub-project',
|
|
61
|
+
'code',
|
|
62
|
+
'maven-settings-path',
|
|
63
|
+
'language',
|
|
64
|
+
'experimental',
|
|
65
|
+
'app-groups',
|
|
66
|
+
'metadata'
|
|
67
|
+
]
|
|
45
68
|
}
|
|
46
69
|
])
|
|
47
70
|
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { startAudit } from './auditController'
|
|
2
2
|
import { getAuditConfig } from './auditConfig'
|
|
3
3
|
import { auditUsageGuide } from './help'
|
|
4
|
+
import { processSca } from '../scan/sca/scaAnalysis'
|
|
4
5
|
|
|
5
6
|
export type parameterInput = string[]
|
|
6
7
|
|
|
7
8
|
export const processAudit = async (argv: parameterInput) => {
|
|
8
9
|
if (argv.indexOf('--help') != -1) {
|
|
9
10
|
printHelpMessage()
|
|
10
|
-
process.exit(
|
|
11
|
+
process.exit(0)
|
|
11
12
|
}
|
|
12
13
|
const config = getAuditConfig(argv)
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if (config.experimental) {
|
|
16
|
+
await processSca(config)
|
|
17
|
+
} else {
|
|
18
|
+
await startAudit(config)
|
|
19
|
+
}
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
const printHelpMessage = () => {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export const saveFile = (config: any, rawResults: any) => {
|
|
4
4
|
const fileName = `${config.applicationId}-sbom-cyclonedx.json`
|
|
5
5
|
fs.writeFileSync(fileName, JSON.stringify(rawResults))
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
saveFile
|
|
10
|
+
}
|