@contrast/contrast 1.0.0 → 1.0.1
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 +2 -0
- package/README.md +120 -47
- package/dist/audit/AnalysisEngine.js +37 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
- package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/goAnalysisEngine/index.js +17 -0
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
- package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/javaAnalysisEngine/index.js +34 -0
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
- package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
- package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
- package/dist/audit/languageAnalysisEngine/constants.js +20 -0
- package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
- package/dist/audit/languageAnalysisEngine/index.js +39 -0
- package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +70 -0
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
- package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
- package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
- package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
- package/dist/audit/nodeAnalysisEngine/index.js +31 -0
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/phpAnalysisEngine/index.js +23 -0
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
- package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/pythonAnalysisEngine/index.js +25 -0
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
- package/dist/audit/rubyAnalysisEngine/index.js +25 -0
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
- package/dist/commands/audit/auditConfig.js +25 -0
- package/dist/commands/audit/auditController.js +31 -0
- package/dist/commands/audit/help.js +52 -0
- package/dist/commands/audit/processAudit.js +18 -0
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/scan/processScan.js +19 -5
- package/dist/common/HTTPClient.js +101 -13
- package/dist/common/errorHandling.js +49 -1
- package/dist/common/findLatestCLIVersion.js +23 -0
- package/dist/constants/constants.js +1 -1
- package/dist/constants/lambda.js +32 -4
- package/dist/constants/locales.js +39 -16
- package/dist/constants.js +148 -20
- package/dist/index.js +7 -1
- package/dist/lambda/aws.js +14 -11
- package/dist/lambda/help.js +4 -0
- package/dist/lambda/lambda.js +50 -27
- package/dist/lambda/lambdaUtils.js +72 -0
- package/dist/lambda/logUtils.js +11 -1
- package/dist/lambda/scanDetailCompletion.js +4 -4
- package/dist/lambda/scanRequest.js +11 -5
- package/dist/lambda/utils.js +110 -53
- package/dist/scan/autoDetection.js +0 -32
- package/dist/scan/fileUtils.js +1 -1
- package/dist/scan/help.js +12 -40
- package/dist/scan/populateProjectIdAndProjectName.js +4 -0
- package/dist/scan/saveResults.js +15 -0
- package/dist/scan/scan.js +77 -42
- package/dist/scan/scanConfig.js +20 -0
- package/dist/scan/scanController.js +13 -15
- package/dist/scan/scanResults.js +18 -16
- package/dist/utils/commonApi.js +3 -3
- package/dist/utils/fileUtils.js +31 -0
- package/dist/utils/paramsUtil/commandlineParams.js +1 -20
- package/dist/utils/paramsUtil/genericCommandLineParams.js +12 -0
- package/dist/utils/paramsUtil/paramHandler.js +3 -6
- package/dist/utils/parsedCLIOptions.js +14 -8
- package/package.json +26 -21
- package/src/audit/AnalysisEngine.js +103 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
- package/src/audit/dotnetAnalysisEngine/index.js +26 -0
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/goAnalysisEngine/index.js +18 -0
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
- package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
- package/src/audit/javaAnalysisEngine/index.js +41 -0
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
- package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
- package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
- package/src/audit/languageAnalysisEngine/constants.js +23 -0
- package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
- package/src/audit/languageAnalysisEngine/index.js +45 -0
- package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +94 -0
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
- package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
- package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
- package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
- package/src/audit/nodeAnalysisEngine/index.js +35 -0
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
- package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
- package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/phpAnalysisEngine/index.js +27 -0
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
- package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
- package/src/audit/pythonAnalysisEngine/index.js +55 -0
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
- package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
- package/src/audit/rubyAnalysisEngine/index.js +30 -0
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
- package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
- package/src/commands/audit/auditConfig.ts +30 -0
- package/src/commands/audit/auditController.ts +31 -0
- package/src/commands/audit/help.ts +48 -0
- package/src/commands/audit/processAudit.ts +19 -0
- package/src/commands/auth/auth.js +1 -1
- package/src/commands/scan/processScan.js +20 -5
- package/src/common/HTTPClient.js +136 -14
- package/src/common/errorHandling.ts +56 -1
- package/src/common/findLatestCLIVersion.ts +27 -0
- package/src/constants/constants.js +1 -1
- package/src/constants/lambda.js +45 -4
- package/src/constants/locales.js +48 -20
- package/src/constants.js +168 -22
- package/src/index.ts +9 -2
- package/src/lambda/aws.ts +13 -12
- package/src/lambda/help.ts +4 -0
- package/src/lambda/lambda.ts +53 -34
- package/src/lambda/lambdaUtils.ts +111 -0
- package/src/lambda/logUtils.ts +19 -1
- package/src/lambda/scanDetailCompletion.ts +4 -4
- package/src/lambda/scanRequest.ts +13 -11
- package/src/lambda/utils.ts +149 -81
- package/src/scan/autoDetection.js +0 -29
- package/src/scan/fileUtils.js +1 -1
- package/src/scan/help.js +12 -45
- package/src/scan/populateProjectIdAndProjectName.js +4 -0
- package/src/scan/saveResults.js +15 -0
- package/src/scan/scan.js +95 -59
- package/src/scan/scanConfig.js +29 -0
- package/src/scan/scanController.js +13 -13
- package/src/scan/scanResults.js +21 -19
- package/src/utils/commonApi.js +2 -3
- package/src/utils/paramsUtil/commandlineParams.js +1 -26
- package/src/utils/paramsUtil/paramHandler.js +3 -7
- package/src/utils/parsedCLIOptions.js +11 -9
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
const commonApi = require('../commonApi')
|
|
3
|
+
const commonReport = require('./commonReportingFunctions')
|
|
4
|
+
|
|
5
|
+
function displaySuccessMessageVulnerabilities() {
|
|
6
|
+
console.log(i18n.__('vulnerabilitiesSuccessMessage'))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const vulnerabilityReport = async (analysis, applicationId, config) => {
|
|
10
|
+
let depRiskReportCount = {}
|
|
11
|
+
if (analysis.language === 'NODE') {
|
|
12
|
+
depRiskReportCount = await commonReport.dependencyRiskReport(
|
|
13
|
+
analysis.node.packageJSON,
|
|
14
|
+
config
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
if (config['report']) {
|
|
18
|
+
const reportResponse = await commonReport.getReport(applicationId)
|
|
19
|
+
if (reportResponse !== undefined) {
|
|
20
|
+
const libraryVulnerabilityInput = createLibraryVulnerabilityInput(
|
|
21
|
+
reportResponse.reports
|
|
22
|
+
)
|
|
23
|
+
const libraryVulnerabilityResponse = await getLibraryVulnerabilities(
|
|
24
|
+
libraryVulnerabilityInput,
|
|
25
|
+
applicationId
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
const severity = config['cve_severity']
|
|
29
|
+
const id = applicationId
|
|
30
|
+
const name = config.applicationName
|
|
31
|
+
const hasSomeVulnerabilitiesReported = formatVulnerabilityOutput(
|
|
32
|
+
libraryVulnerabilityResponse,
|
|
33
|
+
severity,
|
|
34
|
+
id,
|
|
35
|
+
name,
|
|
36
|
+
depRiskReportCount,
|
|
37
|
+
config
|
|
38
|
+
)
|
|
39
|
+
commonReport.analyseReportOptions(hasSomeVulnerabilitiesReported)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const createLibraryVulnerabilityInput = report => {
|
|
45
|
+
const language = Object.keys(report[0].report)[0]
|
|
46
|
+
const reportTree = report[0].report[language].dependencyTree
|
|
47
|
+
const libraries = reportTree[Object.keys(reportTree)[0]]
|
|
48
|
+
|
|
49
|
+
let gav = []
|
|
50
|
+
// eslint-disable-next-line
|
|
51
|
+
for (const key of Object.keys(libraries)) {
|
|
52
|
+
gav.push({
|
|
53
|
+
name: libraries[key].name,
|
|
54
|
+
group: libraries[key].group,
|
|
55
|
+
version: libraries[key].resolved
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
name_group_versions: gav,
|
|
61
|
+
language: language.toUpperCase()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const oldCountSeverity = vulnerableLibraries => {
|
|
66
|
+
const severityCount = {
|
|
67
|
+
critical: 0,
|
|
68
|
+
high: 0,
|
|
69
|
+
medium: 0,
|
|
70
|
+
low: 0
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
vulnerableLibraries.forEach(lib => {
|
|
74
|
+
lib.vulns.forEach(vuln => {
|
|
75
|
+
if (vuln.severity_code === 'HIGH') {
|
|
76
|
+
severityCount['high'] += 1
|
|
77
|
+
} else if (vuln.severity_code === 'MEDIUM') {
|
|
78
|
+
severityCount['medium'] += 1
|
|
79
|
+
} else if (vuln.severity_code === 'LOW') {
|
|
80
|
+
severityCount['low'] += 1
|
|
81
|
+
} else if (vuln.severity_code === 'CRITICAL') {
|
|
82
|
+
severityCount['critical'] += 1
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
return severityCount
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const parseVulnerabilites = libraryVulnerabilityResponse => {
|
|
90
|
+
let parsedVulnerabilites = {}
|
|
91
|
+
let vulnName = libraryVulnerabilityResponse.libraries
|
|
92
|
+
for (let x in vulnName) {
|
|
93
|
+
let vuln = vulnName[x].vulns
|
|
94
|
+
if (vuln.length > 0) {
|
|
95
|
+
let libname =
|
|
96
|
+
vulnName[x].group +
|
|
97
|
+
'/' +
|
|
98
|
+
vulnName[x].file_name +
|
|
99
|
+
'@' +
|
|
100
|
+
vulnName[x].file_version
|
|
101
|
+
parsedVulnerabilites[libname] = vulnName[x].vulns
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return parsedVulnerabilites
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const formatVulnerabilityOutput = (
|
|
108
|
+
libraryVulnerabilityResponse,
|
|
109
|
+
severity,
|
|
110
|
+
id,
|
|
111
|
+
name,
|
|
112
|
+
depRiskReportCount,
|
|
113
|
+
config
|
|
114
|
+
) => {
|
|
115
|
+
let vulnerableLibraries = libraryVulnerabilityResponse.libraries.filter(
|
|
116
|
+
data => {
|
|
117
|
+
return data.vulns.length > 0
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
const numberOfVulnerableLibraries = vulnerableLibraries.length
|
|
122
|
+
let numberOfCves = 0
|
|
123
|
+
vulnerableLibraries.forEach(lib => (numberOfCves += lib.vulns.length))
|
|
124
|
+
commonReport.createLibraryHeader(
|
|
125
|
+
id,
|
|
126
|
+
numberOfVulnerableLibraries,
|
|
127
|
+
numberOfCves,
|
|
128
|
+
name
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
const severityCount = oldCountSeverity(vulnerableLibraries)
|
|
132
|
+
|
|
133
|
+
// parse so filter code will work for both new (ignore dev dep) and current report
|
|
134
|
+
let vulnerabilities = parseVulnerabilites(libraryVulnerabilityResponse)
|
|
135
|
+
let filteredVulns = commonReport.filterVulnerabilitiesBySeverity(
|
|
136
|
+
severity,
|
|
137
|
+
vulnerabilities
|
|
138
|
+
)
|
|
139
|
+
let hasSomeVulnerabilitiesReported
|
|
140
|
+
hasSomeVulnerabilitiesReported = commonReport.printVulnerabilityResponse(
|
|
141
|
+
severity,
|
|
142
|
+
filteredVulns,
|
|
143
|
+
vulnerabilities
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
console.log(
|
|
147
|
+
'\n **************************' +
|
|
148
|
+
` Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVE's ` +
|
|
149
|
+
'************************** '
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if (depRiskReportCount && depRiskReportCount.scopedCount === 0) {
|
|
153
|
+
console.log(' No private libraries that are not scoped detected')
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
console.log(
|
|
157
|
+
' \n Please go to the Contrast UI to view your dependency tree: \n' +
|
|
158
|
+
` \n ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
|
|
159
|
+
)
|
|
160
|
+
return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const getLibraryVulnerabilities = async (input, applicationId) => {
|
|
164
|
+
const requestBody = input
|
|
165
|
+
const addParams = agent.getAdditionalParams()
|
|
166
|
+
const userParams = await util.getParams(applicationId)
|
|
167
|
+
const protocol = getValidHost(userParams.host)
|
|
168
|
+
const client = commonApi.getHttpClient(userParams, protocol, addParams)
|
|
169
|
+
|
|
170
|
+
return client
|
|
171
|
+
.getLibraryVulnerabilities(requestBody, userParams)
|
|
172
|
+
.then(res => {
|
|
173
|
+
if (res.statusCode === 200) {
|
|
174
|
+
displaySuccessMessageVulnerabilities()
|
|
175
|
+
return res.body
|
|
176
|
+
} else {
|
|
177
|
+
handleResponseErrors(res, 'vulnerabilities')
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
.catch(err => {
|
|
181
|
+
console.log(err)
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = {
|
|
186
|
+
vulnerabilityReport: vulnerabilityReport,
|
|
187
|
+
getLibraryVulnerabilities: getLibraryVulnerabilities,
|
|
188
|
+
formatVulnerabilityOutput: formatVulnerabilityOutput,
|
|
189
|
+
createLibraryVulnerabilityInput: createLibraryVulnerabilityInput
|
|
190
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const prettyjson = require('prettyjson')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
const { getHttpClient } = require('../../utils/commonApi')
|
|
4
|
+
const { handleResponseErrors } = require('../../common/errorHandling')
|
|
5
|
+
const { APP_VERSION } = require('../../constants/constants')
|
|
6
|
+
|
|
7
|
+
function displaySnapshotSuccessMessage(config) {
|
|
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) => {
|
|
21
|
+
const analysisLanguage = analysis.config.language.toLowerCase()
|
|
22
|
+
const requestBody = {
|
|
23
|
+
appID: analysis.config.applicationId,
|
|
24
|
+
cliVersion: APP_VERSION,
|
|
25
|
+
snapshot: { [analysisLanguage]: analysis[analysisLanguage] }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const client = getHttpClient(analysis.config)
|
|
29
|
+
|
|
30
|
+
return client
|
|
31
|
+
.sendSnapshot(requestBody, analysis.config)
|
|
32
|
+
.then(res => {
|
|
33
|
+
// if (!analysis.config.silent) {
|
|
34
|
+
// console.log(prettyjson.render(requestBody))
|
|
35
|
+
// }
|
|
36
|
+
if (res.statusCode === 201) {
|
|
37
|
+
displaySnapshotSuccessMessage(analysis.config)
|
|
38
|
+
return res.body
|
|
39
|
+
} else {
|
|
40
|
+
handleResponseErrors(res, 'snapshot')
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
.catch(err => {
|
|
44
|
+
console.log(err)
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
newSendSnapShot: newSendSnapShot,
|
|
50
|
+
displaySnapshotSuccessMessage: displaySnapshotSuccessMessage
|
|
51
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { featuresTeamServer } = require('./capabilities')
|
|
2
|
+
const semver = require('semver')
|
|
3
|
+
const { handleResponseErrors } = require('../../../common/errorHandling')
|
|
4
|
+
const { getHttpClient } = require('../../../utils/commonApi')
|
|
5
|
+
|
|
6
|
+
const getGlobalProperties = async config => {
|
|
7
|
+
const client = getHttpClient(config)
|
|
8
|
+
|
|
9
|
+
return client
|
|
10
|
+
.getGlobalProperties(config)
|
|
11
|
+
.then(res => {
|
|
12
|
+
if (res.statusCode === 200) {
|
|
13
|
+
return res.body
|
|
14
|
+
} else {
|
|
15
|
+
handleResponseErrors(res, 'globalProperties')
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
.catch(err => {
|
|
19
|
+
console.log(err)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const getFeatures = version => {
|
|
24
|
+
const featuresEnabled = []
|
|
25
|
+
|
|
26
|
+
featuresTeamServer.forEach(feature => {
|
|
27
|
+
const versionFrom = Object.values(feature)[0]
|
|
28
|
+
return semver.gte(version, versionFrom)
|
|
29
|
+
? featuresEnabled.push(Object.keys(feature)[0])
|
|
30
|
+
: null
|
|
31
|
+
})
|
|
32
|
+
return featuresEnabled
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const isFeatureEnabled = (features, featureName) => {
|
|
36
|
+
return features.includes(featureName)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
getGlobalProperties,
|
|
41
|
+
getFeatures,
|
|
42
|
+
isFeatureEnabled
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const request = require('request')
|
|
2
|
+
const Promise = require('bluebird')
|
|
3
|
+
|
|
4
|
+
Promise.promisifyAll(request)
|
|
5
|
+
|
|
6
|
+
function sendRequest({ options, method = 'put' }) {
|
|
7
|
+
return request[`${method}Async`](options.url, options)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const sleep = ms => {
|
|
11
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
sendRequest: sendRequest,
|
|
16
|
+
sleep: sleep
|
|
17
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
module.exports = exports = (analysis, next) => {
|
|
3
|
+
const {
|
|
4
|
+
language: { lockFilePath },
|
|
5
|
+
node
|
|
6
|
+
} = analysis
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
if (node.npmLockFile && node.npmLockFile.lockfileVersion > 1) {
|
|
10
|
+
const listOfTopDep = Object.keys(node.npmLockFile.dependencies)
|
|
11
|
+
Object.entries(node.npmLockFile.dependencies).forEach(([key, value]) => {
|
|
12
|
+
if (value.requires) {
|
|
13
|
+
const listOfRequiresDep = Object.keys(value.requires)
|
|
14
|
+
listOfRequiresDep.forEach(dep => {
|
|
15
|
+
if (!listOfTopDep.includes(dep)) {
|
|
16
|
+
addDepToLockFile(value['requires'], dep)
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (value.dependencies) {
|
|
22
|
+
Object.entries(value.dependencies).forEach(
|
|
23
|
+
([childKey, childValue]) => {
|
|
24
|
+
if (childValue.requires) {
|
|
25
|
+
const listOfRequiresDep = Object.keys(childValue.requires)
|
|
26
|
+
listOfRequiresDep.forEach(dep => {
|
|
27
|
+
if (!listOfTopDep.includes(dep)) {
|
|
28
|
+
addDepToLockFile(childValue['requires'], dep)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
} catch (err) {
|
|
38
|
+
next(
|
|
39
|
+
next(new Error(i18n.__('NodeParseNPM', lockFilePath) + `${err.message}`))
|
|
40
|
+
)
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function addDepToLockFile(depObj, key) {
|
|
45
|
+
node.npmLockFile.dependencies[key] = { version: depObj[key] }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
next()
|
|
49
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const AnalysisEngine = require('../AnalysisEngine')
|
|
2
|
+
|
|
3
|
+
const readProjectFileContents = require('./readProjectFileContents')
|
|
4
|
+
const readNPMLockFileContents = require('./readNPMLockFileContents')
|
|
5
|
+
const parseNPMLockFileContents = require('./parseNPMLockFileContents')
|
|
6
|
+
const readYarnLockFileContents = require('./readYarnLockFileContents')
|
|
7
|
+
const parseYarnLockFileContents = require('./parseYarnLockFileContents')
|
|
8
|
+
const parseYarn2LockFileContents = require('./parseYarn2LockFileContents')
|
|
9
|
+
const handleNPMLockFileV2 = require('./handleNPMLockFileV2')
|
|
10
|
+
const sanitizer = require('./sanitizer')
|
|
11
|
+
const i18n = require('i18n')
|
|
12
|
+
|
|
13
|
+
module.exports = exports = (language, config, callback) => {
|
|
14
|
+
const ae = new AnalysisEngine({ language, config, node: {} })
|
|
15
|
+
|
|
16
|
+
ae.use([
|
|
17
|
+
readProjectFileContents,
|
|
18
|
+
readNPMLockFileContents,
|
|
19
|
+
parseNPMLockFileContents,
|
|
20
|
+
readYarnLockFileContents,
|
|
21
|
+
parseYarnLockFileContents,
|
|
22
|
+
parseYarn2LockFileContents,
|
|
23
|
+
handleNPMLockFileV2,
|
|
24
|
+
sanitizer
|
|
25
|
+
])
|
|
26
|
+
|
|
27
|
+
ae.analyze((err, analysis) => {
|
|
28
|
+
if (err) {
|
|
29
|
+
callback(new Error(i18n.__('NodeAnalysisFailure') + `${err.message}`))
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
callback(null, analysis)
|
|
34
|
+
})
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
module.exports = exports = ({ language: { lockFilePath }, node }, next) => {
|
|
3
|
+
// If we never read the package-lock file then pass priority
|
|
4
|
+
if (node.rawLockFileContents === undefined) {
|
|
5
|
+
next()
|
|
6
|
+
} else {
|
|
7
|
+
try {
|
|
8
|
+
node.npmLockFile = JSON.parse(node.rawLockFileContents)
|
|
9
|
+
} catch (err) {
|
|
10
|
+
next(
|
|
11
|
+
new Error(
|
|
12
|
+
i18n.__('NodeParseNPM', lockFilePath ? lockFilePath : 'undefined') +
|
|
13
|
+
`${err.message}`
|
|
14
|
+
)
|
|
15
|
+
)
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
next()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
module.exports = exports = ({ language: { lockFilename }, node }, next) => {
|
|
3
|
+
// If we never read the lock file or its an earlier version then pass priority
|
|
4
|
+
if (node.rawYarnLockFileContents == undefined || node.yarnVersion == 1) {
|
|
5
|
+
next()
|
|
6
|
+
} else {
|
|
7
|
+
try {
|
|
8
|
+
node.yarnLockFile = {}
|
|
9
|
+
node.yarnLockFile['object'] = node.rawYarnLockFileContents
|
|
10
|
+
delete node.yarnLockFile['object'].__metadata
|
|
11
|
+
node.yarnLockFile['type'] = 'success'
|
|
12
|
+
|
|
13
|
+
Object.entries(node.rawYarnLockFileContents).forEach(([key, value]) => {
|
|
14
|
+
const rawKeyNames = key.split(',')
|
|
15
|
+
const keyNames = formatKey(rawKeyNames)
|
|
16
|
+
|
|
17
|
+
keyNames.forEach(name => {
|
|
18
|
+
node.yarnLockFile.object[name] = value
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
} catch (err) {
|
|
22
|
+
next(
|
|
23
|
+
new Error(
|
|
24
|
+
i18n.__('NodeParseYarn2', lockFilename.lockFilePath) +
|
|
25
|
+
`${err.message}`
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
next()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function formatKey(keyNames) {
|
|
37
|
+
let name = ''
|
|
38
|
+
let formattedNames = []
|
|
39
|
+
keyNames.forEach(dummyString => {
|
|
40
|
+
let nameArr = dummyString.split('@')
|
|
41
|
+
if (nameArr.length > 1) {
|
|
42
|
+
if (nameArr.length == 2) {
|
|
43
|
+
name = nameArr[0]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (nameArr.length == 3) {
|
|
47
|
+
name = '@' + nameArr[1]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let version = dummyString.split(':').pop('')
|
|
51
|
+
|
|
52
|
+
if (version.length == 1 && version != '*') {
|
|
53
|
+
version = version + '.0'
|
|
54
|
+
}
|
|
55
|
+
let reformattedKey = name.trim() + '@' + version
|
|
56
|
+
|
|
57
|
+
formattedNames.push(reformattedKey)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
return formattedNames
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
exports.formatKey = formatKey
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const yarnParser = require('@yarnpkg/lockfile')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = ({ language: { lockFilename }, node }, next) => {
|
|
5
|
+
// If we never read the lock file then pass priority
|
|
6
|
+
if (node.rawYarnLockFileContents === undefined || node.yarnVersion === 2) {
|
|
7
|
+
next()
|
|
8
|
+
} else {
|
|
9
|
+
try {
|
|
10
|
+
node.yarnLockFile = yarnParser.parse(node.rawYarnLockFileContents)
|
|
11
|
+
} catch (err) {
|
|
12
|
+
next(
|
|
13
|
+
new Error(
|
|
14
|
+
i18n.__(
|
|
15
|
+
'NodeParseYarn',
|
|
16
|
+
lockFilename.lockFilePath ? lockFilename.lockFilePath : 'undefined'
|
|
17
|
+
) + `${err.message}`
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
next()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = ({ language: { lockFilePath }, node }, next) => {
|
|
5
|
+
// check if the lockFilename is populated and if it is check to
|
|
6
|
+
// see if it has the package-lock if not then go on to next handler
|
|
7
|
+
if (!lockFilePath || !lockFilePath.includes('package-lock.json')) {
|
|
8
|
+
next()
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
node.rawLockFileContents = fs.readFileSync(lockFilePath)
|
|
14
|
+
} catch (err) {
|
|
15
|
+
next(
|
|
16
|
+
new Error(i18n.__('NodeReadNpmError', lockFilePath) + `${err.message}`)
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
next()
|
|
23
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = (analysis, next) => {
|
|
5
|
+
const {
|
|
6
|
+
language: { projectFilePath },
|
|
7
|
+
node
|
|
8
|
+
} = analysis
|
|
9
|
+
|
|
10
|
+
// Read the NODE project file contents. We are reading into memory presuming
|
|
11
|
+
// that the contents of the file aren't large which may be bad... Could look
|
|
12
|
+
// into streaming in the future
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
// package.json is stored in the projectFilePath other files have the word lock so are stored in lockFilename arr
|
|
16
|
+
node.packageJSON = JSON.parse(fs.readFileSync(projectFilePath, 'utf8'))
|
|
17
|
+
} catch (err) {
|
|
18
|
+
next(
|
|
19
|
+
new Error(
|
|
20
|
+
i18n.__('nodeReadProjectFileError', projectFilePath) + `${err.message}`
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
next()
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const yaml = require('js-yaml')
|
|
3
|
+
const i18n = require('i18n')
|
|
4
|
+
|
|
5
|
+
module.exports = exports = ({ language: { lockFilePath }, node }, next) => {
|
|
6
|
+
// check if the lockFilePath is populated and if it is check to
|
|
7
|
+
// see if it has the package-lock if not then go on to next handler
|
|
8
|
+
if (!lockFilePath || !lockFilePath.includes('yarn.lock')) {
|
|
9
|
+
next()
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
node.rawYarnLockFileContents = fs.readFileSync(lockFilePath, 'utf8')
|
|
15
|
+
node.yarnVersion = 1
|
|
16
|
+
|
|
17
|
+
if (
|
|
18
|
+
!node.rawYarnLockFileContents.includes('lockfile v1') ||
|
|
19
|
+
node.rawYarnLockFileContents.includes('__metadata')
|
|
20
|
+
) {
|
|
21
|
+
node.rawYarnLockFileContents = yaml.load(
|
|
22
|
+
fs.readFileSync(lockFilePath, 'utf8')
|
|
23
|
+
)
|
|
24
|
+
node.yarnVersion = 2
|
|
25
|
+
}
|
|
26
|
+
} catch (err) {
|
|
27
|
+
next(
|
|
28
|
+
new Error(
|
|
29
|
+
i18n.__('nodeReadYarnLockFileError', lockFilePath) + `${err.message}`
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
next()
|
|
36
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module.exports = exports = ({ node }, next) => {
|
|
2
|
+
// Remove anything sensitive or unnecessary from being sent to the backend as
|
|
3
|
+
// a result of our NODE project analysis
|
|
4
|
+
delete node.rawProjectFileContents
|
|
5
|
+
delete node.projectFileJSON
|
|
6
|
+
delete node.projectLockFileJSON
|
|
7
|
+
delete node.rawLockFileContents
|
|
8
|
+
delete node.rawYarnLockFileContents
|
|
9
|
+
|
|
10
|
+
next()
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const AnalysisEngine = require('../AnalysisEngine')
|
|
2
|
+
|
|
3
|
+
const readProjectFileContents = require('./readProjectFileContents')
|
|
4
|
+
const readLockFileContents = require('./readLockFileContents')
|
|
5
|
+
const parseLockFileContents = require('./parseLockFileContents')
|
|
6
|
+
const sanitizer = require('./sanitizer')
|
|
7
|
+
const i18n = require('i18n')
|
|
8
|
+
|
|
9
|
+
module.exports = exports = (language, config, callback) => {
|
|
10
|
+
const ae = new AnalysisEngine({ language, config, php: {} })
|
|
11
|
+
|
|
12
|
+
ae.use([
|
|
13
|
+
readProjectFileContents,
|
|
14
|
+
readLockFileContents,
|
|
15
|
+
parseLockFileContents,
|
|
16
|
+
sanitizer
|
|
17
|
+
])
|
|
18
|
+
|
|
19
|
+
ae.analyze((err, analysis) => {
|
|
20
|
+
if (err) {
|
|
21
|
+
callback(new Error(i18n.__('phpAnalysisFailure') + `${err.message}`))
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
callback(null, analysis)
|
|
26
|
+
})
|
|
27
|
+
}
|