@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,177 @@
|
|
|
1
|
+
const {
|
|
2
|
+
supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT }
|
|
3
|
+
} = require('./constants')
|
|
4
|
+
const i18n = require('i18n')
|
|
5
|
+
|
|
6
|
+
const DOT_NET_PROJECT_FILE_REGEX = /.+\.csproj$/
|
|
7
|
+
const DOT_NET_LOCK_FILENAME = 'packages.lock.json'
|
|
8
|
+
|
|
9
|
+
const isDotNetProjectFilename = filename =>
|
|
10
|
+
filename.search(DOT_NET_PROJECT_FILE_REGEX) !== -1
|
|
11
|
+
const isDotNetLockFilename = filename => filename === DOT_NET_LOCK_FILENAME
|
|
12
|
+
function isJavaMavenProjectFilename(filename) {
|
|
13
|
+
return filename === 'pom.xml'
|
|
14
|
+
}
|
|
15
|
+
function isJavaGradleProjectFilename(filename) {
|
|
16
|
+
return filename === 'build.gradle' || filename === 'build.gradle.kts'
|
|
17
|
+
}
|
|
18
|
+
const isRubyProjectFilename = filename => filename === 'Gemfile'
|
|
19
|
+
const isNodeProjectFilename = filename => filename === 'package.json'
|
|
20
|
+
const isPythonProjectFilename = filename =>
|
|
21
|
+
filename === 'requirements.txt' || filename === 'Pipfile'
|
|
22
|
+
const isPhpProjectFilename = filename => filename === 'composer.json'
|
|
23
|
+
const isPhpLockFilename = filename => filename === 'composer.lock'
|
|
24
|
+
function isNodeLockFilename(filename) {
|
|
25
|
+
return filename === 'package-lock.json' || filename === 'yarn.lock'
|
|
26
|
+
}
|
|
27
|
+
const isRubyLockFilename = filename => filename === 'Gemfile.lock'
|
|
28
|
+
const isPipfileLockLockFilename = filename => filename === 'Pipfile.lock'
|
|
29
|
+
const isGoProjectFilename = filename => filename === 'go.mod'
|
|
30
|
+
|
|
31
|
+
const deduceLanguage = filename => {
|
|
32
|
+
const deducedLanguages = []
|
|
33
|
+
|
|
34
|
+
// In theory there shouldn't be multiple languages supported for a single
|
|
35
|
+
// project filename or lock filename but to protect ourselves and consumers we
|
|
36
|
+
// will try to detect it
|
|
37
|
+
|
|
38
|
+
// Check for project filenames...
|
|
39
|
+
if (isJavaMavenProjectFilename(filename)) {
|
|
40
|
+
deducedLanguages.push({ language: JAVA, projectFilename: filename })
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (isJavaGradleProjectFilename(filename)) {
|
|
44
|
+
deducedLanguages.push({ language: JAVA, projectFilename: filename })
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isNodeProjectFilename(filename)) {
|
|
48
|
+
deducedLanguages.push({ language: NODE, projectFilename: filename })
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isDotNetProjectFilename(filename)) {
|
|
52
|
+
deducedLanguages.push({ language: DOTNET, projectFilename: filename })
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (isRubyProjectFilename(filename)) {
|
|
56
|
+
deducedLanguages.push({ language: RUBY, projectFilename: filename })
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (isPythonProjectFilename(filename)) {
|
|
60
|
+
deducedLanguages.push({ language: PYTHON, projectFilename: filename })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (isPhpProjectFilename(filename)) {
|
|
64
|
+
deducedLanguages.push({ language: PHP, projectFilename: filename })
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check for lock filenames...
|
|
68
|
+
if (isDotNetLockFilename(filename)) {
|
|
69
|
+
deducedLanguages.push({ language: DOTNET, lockFilename: filename })
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (isNodeLockFilename(filename)) {
|
|
73
|
+
deducedLanguages.push({ language: NODE, lockFilename: filename })
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (isRubyLockFilename(filename)) {
|
|
77
|
+
deducedLanguages.push({ language: RUBY, lockFilename: filename })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// this is pipfileLock rather than python lock as there can be different python locks
|
|
81
|
+
if (isPipfileLockLockFilename(filename)) {
|
|
82
|
+
deducedLanguages.push({ language: PYTHON, lockFilename: filename })
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (isPhpLockFilename(filename)) {
|
|
86
|
+
deducedLanguages.push({ language: PHP, lockFilename: filename })
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// go does not have a lockfile, it should have a go.mod file containing the modules
|
|
90
|
+
if (isGoProjectFilename(filename)) {
|
|
91
|
+
deducedLanguages.push({ language: GO, projectFilename: filename })
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return deducedLanguages
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const reduceIdentifiedLanguages = identifiedLanguages =>
|
|
98
|
+
identifiedLanguages.reduce((accumulator, identifiedLanguageInfo) => {
|
|
99
|
+
const { language, projectFilename, lockFilename } = identifiedLanguageInfo
|
|
100
|
+
|
|
101
|
+
// Add an entry to our map for an identified language (and its filename)
|
|
102
|
+
// if we haven't accumulated it yet. Otherwise simply add the filename to the
|
|
103
|
+
// existing list.
|
|
104
|
+
if (!(language in accumulator)) {
|
|
105
|
+
accumulator[language] = { projectFilenames: [], lockFilenames: [] }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (projectFilename) {
|
|
109
|
+
accumulator[language].projectFilenames.push(projectFilename)
|
|
110
|
+
} else {
|
|
111
|
+
accumulator[language].lockFilenames.push(lockFilename)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return accumulator
|
|
115
|
+
}, {})
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Look at each filename and using a heuristic see if we can determine that it
|
|
119
|
+
* specifies a specific language
|
|
120
|
+
*/
|
|
121
|
+
module.exports = exports = (analysis, next) => {
|
|
122
|
+
const { projectPath, languageAnalysis, config } = analysis
|
|
123
|
+
|
|
124
|
+
let identifiedLanguages = languageAnalysis.projectRootFilenames.reduce(
|
|
125
|
+
(accumulator, filename) => {
|
|
126
|
+
const deducedLanguages = deduceLanguage(filename)
|
|
127
|
+
return [...accumulator, ...deducedLanguages]
|
|
128
|
+
},
|
|
129
|
+
[]
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
if (Object.keys(identifiedLanguages).length === 0) {
|
|
133
|
+
next(new Error(i18n.__('languageAnalysisNoLanguage', projectPath)))
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let language = config.language
|
|
138
|
+
if (language === undefined) {
|
|
139
|
+
languageAnalysis.identifiedLanguages = reduceIdentifiedLanguages(
|
|
140
|
+
identifiedLanguages
|
|
141
|
+
)
|
|
142
|
+
} else {
|
|
143
|
+
let refinedIdentifiedLanguages = []
|
|
144
|
+
for (let x in identifiedLanguages) {
|
|
145
|
+
if (
|
|
146
|
+
identifiedLanguages[x].language === language.toUpperCase() ||
|
|
147
|
+
(identifiedLanguages[x].language === NODE &&
|
|
148
|
+
language.toUpperCase() === JAVASCRIPT)
|
|
149
|
+
) {
|
|
150
|
+
refinedIdentifiedLanguages.push(identifiedLanguages[x])
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//languages found do not meet that supplied by the user
|
|
154
|
+
if (refinedIdentifiedLanguages.length === 0) {
|
|
155
|
+
console.log(`Could not detect language as specified: ${config.language}`)
|
|
156
|
+
process.exit(1)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
languageAnalysis.identifiedLanguages = reduceIdentifiedLanguages(
|
|
160
|
+
refinedIdentifiedLanguages
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
next()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
//For testing purposes
|
|
168
|
+
exports.isJavaMavenProjectFilename = isJavaMavenProjectFilename
|
|
169
|
+
exports.isJavaGradleProjectFilename = isJavaGradleProjectFilename
|
|
170
|
+
exports.isNodeProjectFilename = isNodeProjectFilename
|
|
171
|
+
exports.isDotNetProjectFilename = isDotNetProjectFilename
|
|
172
|
+
exports.isDotNetLockFilename = isDotNetLockFilename
|
|
173
|
+
exports.isGoProjectFilename = isGoProjectFilename
|
|
174
|
+
exports.isPhpProjectFilename = isPhpProjectFilename
|
|
175
|
+
exports.isPhpLockFilename = isPhpLockFilename
|
|
176
|
+
exports.deduceLanguage = deduceLanguage
|
|
177
|
+
exports.reduceIdentifiedLanguages = reduceIdentifiedLanguages
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const {
|
|
2
|
+
getGlobalProperties,
|
|
3
|
+
getFeatures,
|
|
4
|
+
isFeatureEnabled
|
|
5
|
+
} = require('../util/generalAPI')
|
|
6
|
+
const { CLI_IGNORE_DEV_DEPS } = require('../util/capabilities')
|
|
7
|
+
|
|
8
|
+
const checkDevDeps = async config => {
|
|
9
|
+
const shouldIgnoreDev = config.ignoreDev
|
|
10
|
+
const globalProperties = await getGlobalProperties()
|
|
11
|
+
|
|
12
|
+
// returns [ 'CLI_IGNORE_DEV_DEPS' ] if teamserver version is above 3.8.1
|
|
13
|
+
const features = getFeatures(globalProperties.internal_version)
|
|
14
|
+
|
|
15
|
+
// providing user is on version >= 3.8.1, isfeatureEnabled will always return true,
|
|
16
|
+
// therefore shouldIgnoreDev flag (from params) is needed to disable ignore dev deps
|
|
17
|
+
const isfeatureEnabled = isFeatureEnabled(features, CLI_IGNORE_DEV_DEPS)
|
|
18
|
+
let ignoreDevUrl = false
|
|
19
|
+
if (shouldIgnoreDev) {
|
|
20
|
+
ignoreDevUrl = isfeatureEnabled
|
|
21
|
+
}
|
|
22
|
+
return ignoreDevUrl
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
checkDevDeps
|
|
27
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
const { getHttpClient } = require('../../../utils/commonApi')
|
|
3
|
+
|
|
4
|
+
function displaySuccessMessageReport() {
|
|
5
|
+
console.log('\n' + i18n.__('reportSuccessMessage'))
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function getAllDependenciesArray(packageJson) {
|
|
9
|
+
const {
|
|
10
|
+
dependencies,
|
|
11
|
+
optionalDependencies,
|
|
12
|
+
devDependencies,
|
|
13
|
+
peerDependencies
|
|
14
|
+
} = packageJson
|
|
15
|
+
|
|
16
|
+
const allDep = {
|
|
17
|
+
...dependencies,
|
|
18
|
+
...devDependencies,
|
|
19
|
+
...optionalDependencies,
|
|
20
|
+
...peerDependencies
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return Object.entries(allDep)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function checkIfDepIsScoped(arrDep) {
|
|
27
|
+
let count = 0
|
|
28
|
+
arrDep.forEach(([key, value]) => {
|
|
29
|
+
if (!key.startsWith('@')) {
|
|
30
|
+
console.log(` WARNING not scoped: ${key}:${value}`)
|
|
31
|
+
count++
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
return count
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const dependencyRiskReport = async (packageJson, config) => {
|
|
38
|
+
const arrDep = getAllDependenciesArray(packageJson)
|
|
39
|
+
const unRegisteredDeps = await checkIfDepIsRegisteredOnNPM(arrDep, config)
|
|
40
|
+
let scopedCount = checkIfDepIsScoped(unRegisteredDeps)
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
scopedCount: scopedCount,
|
|
44
|
+
unRegisteredCount: unRegisteredDeps.length
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const checkIfDepIsRegisteredOnNPM = async (arrDep, config) => {
|
|
49
|
+
let promises = []
|
|
50
|
+
let unRegisteredDeps = []
|
|
51
|
+
const client = getHttpClient(config)
|
|
52
|
+
|
|
53
|
+
for (const [index, element] of arrDep) {
|
|
54
|
+
const query = `query artifactByGAV($name: String!, $language: String!, $groupName: String, $version: String!, $nameCheck: Boolean) {
|
|
55
|
+
artifact: exactVersion(name: $name, language: $language, groupName: $groupName, version: $version, nameCheck: $nameCheck) {
|
|
56
|
+
version
|
|
57
|
+
cves {
|
|
58
|
+
baseScore
|
|
59
|
+
}}}`
|
|
60
|
+
|
|
61
|
+
const data = {
|
|
62
|
+
query: query,
|
|
63
|
+
variables: {
|
|
64
|
+
name: index,
|
|
65
|
+
version: element,
|
|
66
|
+
language: 'node',
|
|
67
|
+
nameCheck: true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
promises.push(client.checkLibrary(data))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await Promise.all(promises).then(response => {
|
|
75
|
+
response.forEach(res => {
|
|
76
|
+
const libName = JSON.parse(res.request.body)
|
|
77
|
+
if (res.statusCode === 200) {
|
|
78
|
+
if (res.body.data.artifact == null) {
|
|
79
|
+
unRegisteredDeps.push([
|
|
80
|
+
libName.variables.name,
|
|
81
|
+
libName.variables.version
|
|
82
|
+
])
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (unRegisteredDeps.length !== 0) {
|
|
89
|
+
console.log(
|
|
90
|
+
'\n Dependencies Risk Report',
|
|
91
|
+
'\n\n Private libraries that are not scoped. We recommend these libraries are reviewed and the scope claimed to prevent dependency confusion breaches'
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return unRegisteredDeps
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const createLibraryHeader = (
|
|
99
|
+
id,
|
|
100
|
+
numberOfVulnerableLibraries,
|
|
101
|
+
numberOfCves,
|
|
102
|
+
name
|
|
103
|
+
) => {
|
|
104
|
+
name
|
|
105
|
+
? console.log(` Application Name: ${name} | Application ID: ${id}`)
|
|
106
|
+
: console.log(` Application ID: ${id}`)
|
|
107
|
+
console.log(
|
|
108
|
+
` Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVE's`
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const breakPipeline = () => {
|
|
113
|
+
failOptionError()
|
|
114
|
+
process.exit(1)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const parameterOptions = hasSomeVulnerabilitiesReported => {
|
|
118
|
+
const inputtedCLIOptions = cliOptions.getCommandLineArgs()
|
|
119
|
+
let cveSeverityOption = inputtedCLIOptions['cve_severity']
|
|
120
|
+
let fail = inputtedCLIOptions['fail']
|
|
121
|
+
let cve_threshold = inputtedCLIOptions['cve_threshold']
|
|
122
|
+
let expr
|
|
123
|
+
if (cveSeverityOption && fail && cve_threshold) {
|
|
124
|
+
expr = 'SeverityAndThreshold'
|
|
125
|
+
} else if (!cveSeverityOption && fail && cve_threshold) {
|
|
126
|
+
expr = 'ThresholdOnly'
|
|
127
|
+
} else if (!cve_threshold && fail && hasSomeVulnerabilitiesReported[0]) {
|
|
128
|
+
expr = 'FailOnly'
|
|
129
|
+
}
|
|
130
|
+
return expr
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const analyseReportOptions = hasSomeVulnerabilitiesReported => {
|
|
134
|
+
const inputtedCLIOptions = cliOptions.getCommandLineArgs()
|
|
135
|
+
let cve_threshold = inputtedCLIOptions['cve_threshold']
|
|
136
|
+
let cveSeverity
|
|
137
|
+
let criticalSeverity
|
|
138
|
+
let highSeverity
|
|
139
|
+
let mediumSeverity
|
|
140
|
+
let lowSeverity
|
|
141
|
+
|
|
142
|
+
switch (parameterOptions(hasSomeVulnerabilitiesReported)) {
|
|
143
|
+
case 'SeverityAndThreshold':
|
|
144
|
+
cveSeverity = inputtedCLIOptions['cve_severity'].severity
|
|
145
|
+
criticalSeverity = hasSomeVulnerabilitiesReported[2].critical
|
|
146
|
+
highSeverity = hasSomeVulnerabilitiesReported[2].high
|
|
147
|
+
mediumSeverity = hasSomeVulnerabilitiesReported[2].medium
|
|
148
|
+
lowSeverity = hasSomeVulnerabilitiesReported[2].low
|
|
149
|
+
|
|
150
|
+
if (cveSeverity === 'HIGH') {
|
|
151
|
+
if (cve_threshold < highSeverity + criticalSeverity) {
|
|
152
|
+
breakPipeline()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (cveSeverity === 'MEDIUM') {
|
|
157
|
+
if (cve_threshold < mediumSeverity + highSeverity) {
|
|
158
|
+
breakPipeline()
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (cveSeverity === 'LOW') {
|
|
163
|
+
if (cve_threshold < lowSeverity + mediumSeverity + highSeverity) {
|
|
164
|
+
breakPipeline()
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
break
|
|
168
|
+
case 'ThresholdOnly':
|
|
169
|
+
if (cve_threshold < hasSomeVulnerabilitiesReported[1]) {
|
|
170
|
+
breakPipeline()
|
|
171
|
+
}
|
|
172
|
+
break
|
|
173
|
+
case 'FailOnly':
|
|
174
|
+
breakPipeline()
|
|
175
|
+
break
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const getReport = async applicationId => {
|
|
180
|
+
const userParams = await util.getParams(applicationId)
|
|
181
|
+
const addParams = agent.getAdditionalParams()
|
|
182
|
+
const protocol = getValidHost(userParams.host)
|
|
183
|
+
const client = commonApi.getHttpClient(userParams, protocol, addParams)
|
|
184
|
+
return client
|
|
185
|
+
.getReport(userParams)
|
|
186
|
+
.then(res => {
|
|
187
|
+
if (res.statusCode === 200) {
|
|
188
|
+
displaySuccessMessageReport()
|
|
189
|
+
return res.body
|
|
190
|
+
} else {
|
|
191
|
+
handleResponseErrors(res, 'report')
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
.catch(err => {
|
|
195
|
+
console.log(err)
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const printVulnerabilityResponse = (
|
|
200
|
+
severity,
|
|
201
|
+
filteredVulns,
|
|
202
|
+
vulnerabilities
|
|
203
|
+
) => {
|
|
204
|
+
let hasSomeVulnerabilitiesReported = false
|
|
205
|
+
if (severity) {
|
|
206
|
+
returnCveData(filteredVulns)
|
|
207
|
+
if (Object.keys(filteredVulns).length > 0)
|
|
208
|
+
hasSomeVulnerabilitiesReported = true
|
|
209
|
+
} else {
|
|
210
|
+
returnCveData(vulnerabilities)
|
|
211
|
+
if (Object.keys(vulnerabilities).length > 0)
|
|
212
|
+
hasSomeVulnerabilitiesReported = true
|
|
213
|
+
}
|
|
214
|
+
return hasSomeVulnerabilitiesReported
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const returnCveData = libraries => {
|
|
218
|
+
console.log('\n ************************************************************')
|
|
219
|
+
|
|
220
|
+
for (const [key, value] of Object.entries(libraries)) {
|
|
221
|
+
const parts = key.split('/')
|
|
222
|
+
const nameVersion = parts[1].split('@')
|
|
223
|
+
const group = parts[0]
|
|
224
|
+
const name = nameVersion[0]
|
|
225
|
+
const version = nameVersion[1]
|
|
226
|
+
|
|
227
|
+
const libName =
|
|
228
|
+
group !== 'null'
|
|
229
|
+
? `${group}/${name}/${version} is vulnerable`
|
|
230
|
+
: `${name}/${version} is vulnerable`
|
|
231
|
+
|
|
232
|
+
console.log('\n\n ' + libName)
|
|
233
|
+
value.forEach(vuln => {
|
|
234
|
+
let sevCode = vuln.severityCode || vuln.severity_code
|
|
235
|
+
console.log('\n ' + vuln.name + ' ' + sevCode + '\n ' + vuln.description)
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function searchHighCVEs(vuln) {
|
|
241
|
+
let sevCode = vuln.severityCode || vuln.severity_code
|
|
242
|
+
if (sevCode === 'HIGH') {
|
|
243
|
+
return vuln
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function searchMediumCVEs(vuln) {
|
|
248
|
+
let sevCode = vuln.severityCode || vuln.severity_code
|
|
249
|
+
if (sevCode === 'HIGH' || sevCode === 'MEDIUM') {
|
|
250
|
+
return vuln
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function searchLowCVEs(vuln) {
|
|
255
|
+
let sevCode = vuln.severityCode || vuln.severity_code
|
|
256
|
+
if (sevCode === 'HIGH' || sevCode === 'MEDIUM' || sevCode === 'LOW') {
|
|
257
|
+
return vuln
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const filterVulnerabilitiesBySeverity = (severity, vulnerabilities) => {
|
|
262
|
+
let filteredVulns = []
|
|
263
|
+
if (severity) {
|
|
264
|
+
for (let x in vulnerabilities) {
|
|
265
|
+
if (severity.severity === 'HIGH') {
|
|
266
|
+
let highVulnerability = vulnerabilities[x].filter(searchHighCVEs)
|
|
267
|
+
if (highVulnerability.length > 0) {
|
|
268
|
+
filteredVulns[x] = highVulnerability
|
|
269
|
+
}
|
|
270
|
+
} else if (severity.severity === 'MEDIUM') {
|
|
271
|
+
let mediumVulnerability = vulnerabilities[x].filter(searchMediumCVEs)
|
|
272
|
+
if (mediumVulnerability.length > 0) {
|
|
273
|
+
filteredVulns[x] = mediumVulnerability
|
|
274
|
+
}
|
|
275
|
+
} else if (severity.severity === 'LOW') {
|
|
276
|
+
let lowVulnerability = vulnerabilities[x].filter(searchLowCVEs)
|
|
277
|
+
if (lowVulnerability.length > 0) {
|
|
278
|
+
filteredVulns[x] = lowVulnerability
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return filteredVulns
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
module.exports = {
|
|
287
|
+
displaySuccessMessageReport: displaySuccessMessageReport,
|
|
288
|
+
getAllDependenciesArray: getAllDependenciesArray,
|
|
289
|
+
dependencyRiskReport: dependencyRiskReport,
|
|
290
|
+
createLibraryHeader: createLibraryHeader,
|
|
291
|
+
breakPipeline: breakPipeline,
|
|
292
|
+
parameterOptions: parameterOptions,
|
|
293
|
+
analyseReportOptions: analyseReportOptions,
|
|
294
|
+
getReport: getReport,
|
|
295
|
+
checkIfDepIsScoped: checkIfDepIsScoped,
|
|
296
|
+
checkIfDepIsRegisteredOnNPM: checkIfDepIsRegisteredOnNPM,
|
|
297
|
+
filterVulnerabilitiesBySeverity: filterVulnerabilitiesBySeverity,
|
|
298
|
+
searchLowCVEs: searchLowCVEs,
|
|
299
|
+
searchMediumCVEs: searchMediumCVEs,
|
|
300
|
+
searchHighCVEs: searchHighCVEs,
|
|
301
|
+
returnCveData: returnCveData,
|
|
302
|
+
printVulnerabilityResponse: printVulnerabilityResponse
|
|
303
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const commonReport = require('./commonReportingFunctions')
|
|
2
|
+
const { handleResponseErrors } = require('../commonApi')
|
|
3
|
+
const { getHttpClient } = require('../../../utils/commonApi')
|
|
4
|
+
|
|
5
|
+
const vulnReportWithoutDevDep = async (
|
|
6
|
+
analysis,
|
|
7
|
+
applicationId,
|
|
8
|
+
snapshotId,
|
|
9
|
+
config
|
|
10
|
+
) => {
|
|
11
|
+
if (config.report) {
|
|
12
|
+
const reportResponse = await getSpecReport(snapshotId, config)
|
|
13
|
+
if (reportResponse !== undefined) {
|
|
14
|
+
const severity = config.cveSeverity
|
|
15
|
+
const id = applicationId
|
|
16
|
+
const name = config.applicationName
|
|
17
|
+
const hasSomeVulnerabilitiesReported = formatVulnerabilityOutput(
|
|
18
|
+
reportResponse.vulnerabilities,
|
|
19
|
+
severity,
|
|
20
|
+
id,
|
|
21
|
+
name,
|
|
22
|
+
config
|
|
23
|
+
)
|
|
24
|
+
commonReport.analyseReportOptions(hasSomeVulnerabilitiesReported)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const getSpecReport = async (reportId, config) => {
|
|
30
|
+
const client = getHttpClient(config)
|
|
31
|
+
|
|
32
|
+
return client
|
|
33
|
+
.getSpecificReport(config, reportId)
|
|
34
|
+
.then(res => {
|
|
35
|
+
if (res.statusCode === 200) {
|
|
36
|
+
commonReport.displaySuccessMessageReport()
|
|
37
|
+
return res.body
|
|
38
|
+
} else {
|
|
39
|
+
handleResponseErrors(res, 'report')
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
.catch(err => {
|
|
43
|
+
console.log(err)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const countSeverity = vulnerabilities => {
|
|
48
|
+
const severityCount = {
|
|
49
|
+
critical: 0,
|
|
50
|
+
high: 0,
|
|
51
|
+
medium: 0,
|
|
52
|
+
low: 0
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// eslint-disable-next-line
|
|
56
|
+
for (const key of Object.keys(vulnerabilities)) {
|
|
57
|
+
vulnerabilities[key].forEach(vuln => {
|
|
58
|
+
if (vuln.severityCode === 'HIGH') {
|
|
59
|
+
severityCount['high'] += 1
|
|
60
|
+
} else if (vuln.severityCode === 'MEDIUM') {
|
|
61
|
+
severityCount['medium'] += 1
|
|
62
|
+
} else if (vuln.severityCode === 'LOW') {
|
|
63
|
+
severityCount['low'] += 1
|
|
64
|
+
} else if (vuln.severityCode === 'CRITICAL') {
|
|
65
|
+
severityCount['critical'] += 1
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
return severityCount
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const formatVulnerabilityOutput = (
|
|
73
|
+
vulnerabilities,
|
|
74
|
+
severity,
|
|
75
|
+
id,
|
|
76
|
+
name,
|
|
77
|
+
config
|
|
78
|
+
) => {
|
|
79
|
+
const numberOfVulnerableLibraries = Object.keys(vulnerabilities).length
|
|
80
|
+
let numberOfCves = 0
|
|
81
|
+
|
|
82
|
+
// eslint-disable-next-line
|
|
83
|
+
for (const key of Object.keys(vulnerabilities)) {
|
|
84
|
+
numberOfCves += vulnerabilities[key].length
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
commonReport.createLibraryHeader(
|
|
88
|
+
id,
|
|
89
|
+
numberOfVulnerableLibraries,
|
|
90
|
+
numberOfCves,
|
|
91
|
+
name
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
const severityCount = countSeverity(vulnerabilities)
|
|
95
|
+
const filteredVulns = commonReport.filterVulnerabilitiesBySeverity(
|
|
96
|
+
severity,
|
|
97
|
+
vulnerabilities
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
let hasSomeVulnerabilitiesReported
|
|
101
|
+
hasSomeVulnerabilitiesReported = commonReport.printVulnerabilityResponse(
|
|
102
|
+
severity,
|
|
103
|
+
filteredVulns,
|
|
104
|
+
vulnerabilities
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
console.log(
|
|
108
|
+
'\n **************************' +
|
|
109
|
+
` Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVE's ` +
|
|
110
|
+
'************************** '
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
console.log(
|
|
114
|
+
' \n Please go to the Contrast UI to view your dependency tree: \n' +
|
|
115
|
+
` \n ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
|
|
116
|
+
)
|
|
117
|
+
return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = {
|
|
121
|
+
vulnReportWithoutDevDep: vulnReportWithoutDevDep,
|
|
122
|
+
formatVulnerabilityOutput: formatVulnerabilityOutput,
|
|
123
|
+
getSpecReport: getSpecReport
|
|
124
|
+
}
|