@contrast/contrast 1.0.1 → 1.0.4

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.
Files changed (94) hide show
  1. package/.prettierignore +2 -0
  2. package/README.md +103 -133
  3. package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +26 -11
  4. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +62 -234
  5. package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
  6. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
  7. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
  8. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
  9. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
  10. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
  11. package/dist/commands/audit/auditController.js +6 -3
  12. package/dist/commands/audit/saveFile.js +11 -0
  13. package/dist/commands/auth/auth.js +19 -1
  14. package/dist/commands/config/config.js +19 -8
  15. package/dist/commands/scan/processScan.js +8 -25
  16. package/dist/common/HTTPClient.js +30 -26
  17. package/dist/common/errorHandling.js +17 -1
  18. package/dist/common/versionChecker.js +32 -0
  19. package/dist/constants/constants.js +4 -2
  20. package/dist/constants/lambda.js +3 -1
  21. package/dist/constants/locales.js +41 -18
  22. package/dist/constants.js +39 -3
  23. package/dist/index.js +49 -28
  24. package/dist/lambda/help.js +22 -14
  25. package/dist/lambda/lambda.js +6 -0
  26. package/dist/sbom/generateSbom.js +20 -0
  27. package/dist/scan/help.js +4 -2
  28. package/dist/scan/models/groupedResultsModel.js +10 -0
  29. package/dist/scan/models/resultContentModel.js +2 -0
  30. package/dist/scan/models/scanResultsModel.js +11 -0
  31. package/dist/scan/populateProjectIdAndProjectName.js +1 -0
  32. package/dist/scan/saveResults.js +9 -10
  33. package/dist/scan/scan.js +99 -74
  34. package/dist/scan/scanConfig.js +20 -1
  35. package/dist/scan/scanController.js +7 -2
  36. package/dist/scan/scanResults.js +6 -0
  37. package/dist/utils/getConfig.js +3 -0
  38. package/dist/utils/paramsUtil/commandlineParams.js +1 -1
  39. package/dist/utils/requestUtils.js +1 -1
  40. package/dist/utils/saveFile.js +19 -0
  41. package/package.json +2 -2
  42. package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +33 -15
  43. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +127 -0
  44. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
  45. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
  46. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
  47. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
  48. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
  49. package/src/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
  50. package/src/commands/audit/auditController.ts +12 -3
  51. package/src/commands/audit/processAudit.ts +0 -1
  52. package/src/commands/audit/saveFile.ts +6 -0
  53. package/src/commands/auth/auth.js +25 -1
  54. package/src/commands/config/config.js +22 -8
  55. package/src/commands/scan/processScan.js +8 -29
  56. package/src/common/HTTPClient.js +42 -36
  57. package/src/common/errorHandling.ts +29 -2
  58. package/src/common/versionChecker.ts +41 -0
  59. package/src/constants/constants.js +5 -4
  60. package/src/constants/lambda.js +3 -1
  61. package/src/constants/locales.js +51 -19
  62. package/src/constants.js +44 -3
  63. package/src/index.ts +63 -31
  64. package/src/lambda/help.ts +22 -14
  65. package/src/lambda/lambda.ts +8 -0
  66. package/src/sbom/generateSbom.ts +17 -0
  67. package/src/scan/help.js +4 -2
  68. package/src/scan/models/groupedResultsModel.ts +18 -0
  69. package/src/scan/models/resultContentModel.ts +86 -0
  70. package/src/scan/models/scanResultsModel.ts +52 -0
  71. package/src/scan/populateProjectIdAndProjectName.js +1 -0
  72. package/src/scan/saveResults.js +8 -9
  73. package/src/scan/scan.ts +192 -0
  74. package/src/scan/scanConfig.js +26 -1
  75. package/src/scan/scanController.js +11 -2
  76. package/src/scan/scanResults.js +11 -0
  77. package/src/utils/getConfig.ts +12 -0
  78. package/src/utils/paramsUtil/commandlineParams.js +1 -1
  79. package/src/utils/requestUtils.js +1 -1
  80. package/src/utils/saveFile.js +19 -0
  81. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
  82. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
  83. package/dist/common/findLatestCLIVersion.js +0 -23
  84. package/dist/lambda/scanDetail.js +0 -30
  85. package/dist/scan/fileFinder.js +0 -15
  86. package/dist/utils/fileUtils.js +0 -31
  87. package/dist/utils/paramsUtil/genericCommandLineParams.js +0 -12
  88. package/dist/utils/paramsUtil/yamlParams.js +0 -6
  89. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
  90. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
  91. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
  92. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
  93. package/src/common/findLatestCLIVersion.ts +0 -27
  94. package/src/scan/scan.js +0 -162
@@ -23,6 +23,7 @@ const createProjectId = async (config, client) => {
23
23
  }
24
24
  if (res.statusCode === 403) {
25
25
  console.log(i18n.__('permissionsError'))
26
+ process.exit(1)
26
27
  return
27
28
  }
28
29
 
@@ -1,15 +1,14 @@
1
1
  const fs = require('fs')
2
2
 
3
- const writeResultsToFile = (responseBody, name = 'results.sarif') => {
4
- fs.writeFile(name, JSON.stringify(responseBody, null, 2), err => {
5
- if (err) {
6
- console.log('Error writing Scan Results to file')
7
- } else {
8
- console.log(`Scan Results saved to ${name}`)
9
- }
10
- })
3
+ const writeResultsToFile = async (responseBody, name = 'results.sarif') => {
4
+ try {
5
+ fs.writeFileSync(name, JSON.stringify(responseBody, null, 2))
6
+ console.log(`Scan Results saved to ${name}`)
7
+ } catch (err) {
8
+ console.log('Error writing Scan Results to file')
9
+ }
11
10
  }
12
11
 
13
12
  module.exports = {
14
- writeResultsToFile
13
+ writeResultsToFile: writeResultsToFile
15
14
  }
@@ -0,0 +1,192 @@
1
+ import commonApi from '../utils/commonApi.js'
2
+ import fileUtils from '../scan/fileUtils'
3
+ import i18n from 'i18n'
4
+ import oraWrapper from '../utils/oraWrapper'
5
+ import chalk from 'chalk'
6
+ import { ProjectOverview, ScanResultsModel } from './models/scanResultsModel'
7
+ import { Location, ResultContent } from './models/resultContentModel'
8
+ import { GroupedResultsModel } from './models/groupedResultsModel'
9
+
10
+ export const allowedFileTypes = ['.jar', '.war', '.js', '.zip', '.exe']
11
+
12
+ export const isFileAllowed = (scanOption: string) => {
13
+ let valid = false
14
+ allowedFileTypes.forEach(fileType => {
15
+ if (scanOption.endsWith(fileType)) {
16
+ valid = true
17
+ }
18
+ })
19
+ return valid
20
+ }
21
+
22
+ export const sendScan = async (config: any) => {
23
+ if (!isFileAllowed(config.file)) {
24
+ console.log(i18n.__('scanErrorFileMessage'))
25
+ process.exit(9)
26
+ } else {
27
+ fileUtils.checkFilePermissions(config.file)
28
+ const client = commonApi.getHttpClient(config)
29
+
30
+ const startUploadSpinner = oraWrapper.returnOra(i18n.__('uploadingScan'))
31
+ oraWrapper.startSpinner(startUploadSpinner)
32
+
33
+ return await client
34
+ .sendArtifact(config)
35
+ .then(res => {
36
+ if (res.statusCode === 201) {
37
+ oraWrapper.succeedSpinner(
38
+ startUploadSpinner,
39
+ i18n.__('uploadingScanSuccessful')
40
+ )
41
+ if (config.verbose) {
42
+ console.log(i18n.__('responseMessage', res.body))
43
+ }
44
+ return res.body.id
45
+ } else {
46
+ if (config.debug) {
47
+ console.log(res.statusCode)
48
+ console.log(config)
49
+ }
50
+ oraWrapper.failSpinner(
51
+ startUploadSpinner,
52
+ i18n.__('uploadingScanFail')
53
+ )
54
+ if (res.statusCode === 403) {
55
+ console.log(i18n.__('permissionsError'))
56
+ process.exit(1)
57
+ }
58
+ console.log(i18n.__('genericServiceError', res.statusCode))
59
+ process.exit(1)
60
+ }
61
+ })
62
+ .catch(err => {
63
+ console.log(err)
64
+ })
65
+ }
66
+ }
67
+
68
+ export function formatScanOutput(scanResults: ScanResultsModel) {
69
+ const { projectOverview, scanResultsInstances } = scanResults
70
+
71
+ if (scanResultsInstances.content.length === 0) {
72
+ console.log(i18n.__('scanNoVulnerabilitiesFound'))
73
+ } else {
74
+ const message =
75
+ projectOverview.critical || projectOverview.high
76
+ ? 'Here are your top priorities to fix'
77
+ : "No major issues, here's what we found"
78
+ console.log(chalk.bold(message))
79
+ console.log()
80
+
81
+ const groups = getGroups(scanResultsInstances.content)
82
+
83
+ groups.forEach(entry => {
84
+ console.log(
85
+ chalk.bold(
86
+ `[ ${entry.severity} ] | ${entry.ruleId} (${entry.lineInfoSet.size}) - ` +
87
+ `${entry.message}`
88
+ )
89
+ )
90
+
91
+ let count = 1
92
+ entry.lineInfoSet.forEach(lineInfo => {
93
+ console.log(`\t ${count}. ${lineInfo}`)
94
+ count++
95
+ })
96
+
97
+ if (entry?.issue) {
98
+ console.log(chalk.bold('Issue' + ': ') + entry.issue)
99
+ }
100
+
101
+ if (entry?.advice) {
102
+ console.log(chalk.bold('Advice' + ': ') + entry.advice)
103
+ }
104
+
105
+ if (entry?.learn && entry?.learn.length > 0) {
106
+ formatLinks('Learn', entry.learn)
107
+ }
108
+ console.log()
109
+ })
110
+
111
+ printVulnInfo(projectOverview)
112
+ }
113
+ }
114
+
115
+ function printVulnInfo(projectOverview: ProjectOverview) {
116
+ const totalVulnerabilities = getTotalVulns(projectOverview)
117
+
118
+ const vulMessage =
119
+ totalVulnerabilities === 1 ? `vulnerability` : `vulnerabilities`
120
+ console.log(chalk.bold(`Found ${totalVulnerabilities} ${vulMessage}`))
121
+ console.log(
122
+ i18n.__(
123
+ 'foundDetailedVulnerabilities',
124
+ String(projectOverview.critical),
125
+ String(projectOverview.high),
126
+ String(projectOverview.medium),
127
+ String(projectOverview.low),
128
+ String(projectOverview.note)
129
+ )
130
+ )
131
+ }
132
+
133
+ function getTotalVulns(projectOverview: ProjectOverview) {
134
+ return (
135
+ projectOverview.critical +
136
+ projectOverview.high +
137
+ projectOverview.medium +
138
+ projectOverview.low +
139
+ projectOverview.note
140
+ )
141
+ }
142
+
143
+ export function formatLinks(objName: string, entry: any[]) {
144
+ console.log(chalk.bold(objName + ':'))
145
+ entry.forEach(link => {
146
+ console.log(link)
147
+ })
148
+ }
149
+
150
+ export function getGroups(content: ResultContent[]) {
151
+ const groupTypeSet = new Set(content.map(({ ruleId }) => ruleId))
152
+ const groupTypeResults = [] as GroupedResultsModel[]
153
+
154
+ groupTypeSet.forEach(groupName => {
155
+ const groupResultsObj = new GroupedResultsModel(groupName)
156
+
157
+ content.forEach(resultEntry => {
158
+ if (resultEntry.ruleId === groupName) {
159
+ groupResultsObj.severity = resultEntry.severity
160
+ groupResultsObj.issue = stripMustacheTags(resultEntry.issue)
161
+ groupResultsObj.advice = resultEntry.advice
162
+ groupResultsObj.learn = resultEntry.learn
163
+ groupResultsObj.message = resultEntry.message?.text
164
+
165
+ groupResultsObj.lineInfoSet.add(getMessage(resultEntry.locations))
166
+ }
167
+ })
168
+ groupTypeResults.push(groupResultsObj)
169
+ })
170
+
171
+ return groupTypeResults
172
+ }
173
+
174
+ export function getMessage(locations: Location[]) {
175
+ const message = locations[0]?.physicalLocation?.artifactLocation?.uri || ''
176
+ const lineNumber = locations[0]?.physicalLocation?.region?.startLine || ''
177
+
178
+ if (!lineNumber) {
179
+ return '@' + message
180
+ }
181
+
182
+ return '@' + message + ':' + lineNumber
183
+ }
184
+
185
+ export function stripMustacheTags(oldString: string) {
186
+ return oldString
187
+ .replace(/\n/g, ' ')
188
+ .replace(/{{.*?}}/g, '\n')
189
+ .replace(/\$\$LINK_DELIM\$\$/g, '\n')
190
+ .replace(/\s+/g, ' ')
191
+ .trim()
192
+ }
@@ -2,14 +2,34 @@ const paramHandler = require('../utils/paramsUtil/paramHandler')
2
2
  const constants = require('../../src/constants.js')
3
3
  const parsedCLIOptions = require('../../src/utils/parsedCLIOptions')
4
4
  const path = require('path')
5
+ const {
6
+ supportedLanguages
7
+ } = require('../audit/languageAnalysisEngine/constants')
8
+ const i18n = require('i18n')
9
+ const { scanUsageGuide } = require('./help')
5
10
 
6
11
  const getScanConfig = argv => {
7
12
  let scanParams = parsedCLIOptions.getCommandLineArgsCustom(
8
13
  argv,
9
14
  constants.commandLineDefinitions.scanOptionDefinitions
10
15
  )
16
+
17
+ if (scanParams.help) {
18
+ printHelpMessage()
19
+ process.exit(0)
20
+ }
21
+
11
22
  const paramsAuth = paramHandler.getAuth(scanParams)
12
23
 
24
+ if (scanParams.language) {
25
+ scanParams.language = scanParams.language.toUpperCase()
26
+ if (!Object.values(supportedLanguages).includes(scanParams.language)) {
27
+ console.log(`Did not recognise --language ${scanParams.language}`)
28
+ console.log(i18n.__('constantsHowToRunDev3'))
29
+ process.exit(1)
30
+ }
31
+ }
32
+
13
33
  // if no name, take the full file path and use it as the project name
14
34
  if (!scanParams.name && scanParams.file) {
15
35
  scanParams.name = getFileName(scanParams.file)
@@ -23,7 +43,12 @@ const getFileName = file => {
23
43
  return file.split(path.sep).pop()
24
44
  }
25
45
 
46
+ const printHelpMessage = () => {
47
+ console.log(scanUsageGuide)
48
+ }
49
+
26
50
  module.exports = {
27
51
  getScanConfig,
28
- getFileName
52
+ getFileName,
53
+ printHelpMessage
29
54
  }
@@ -9,6 +9,7 @@ const scan = require('./scan')
9
9
  const scanResults = require('./scanResults')
10
10
  const autoDetection = require('./autoDetection')
11
11
  const fileFunctions = require('./fileUtils')
12
+ const { performance } = require('perf_hooks')
12
13
 
13
14
  const getTimeout = config => {
14
15
  if (config.timeout) {
@@ -25,7 +26,7 @@ const fileAndLanguageLogic = async configToUse => {
25
26
  if (configToUse.file) {
26
27
  if (!fileFunctions.fileExists(configToUse.file)) {
27
28
  console.log(i18n.__('fileNotExist'))
28
- process.exit(0)
29
+ process.exit(1)
29
30
  }
30
31
  return configToUse
31
32
  } else {
@@ -36,6 +37,7 @@ const fileAndLanguageLogic = async configToUse => {
36
37
  }
37
38
 
38
39
  const startScan = async configToUse => {
40
+ const startTime = performance.now()
39
41
  await fileAndLanguageLogic(configToUse)
40
42
 
41
43
  if (!configToUse.projectId) {
@@ -46,7 +48,7 @@ const startScan = async configToUse => {
46
48
  const codeArtifactId = await scan.sendScan(configToUse)
47
49
 
48
50
  if (!configToUse.ff) {
49
- const startScanSpinner = returnOra('Contrast Scan started')
51
+ const startScanSpinner = returnOra('🚀 Contrast Scan started')
50
52
  startSpinner(startScanSpinner)
51
53
  const scanDetail = await scanResults.returnScanResults(
52
54
  configToUse,
@@ -54,11 +56,18 @@ const startScan = async configToUse => {
54
56
  getTimeout(configToUse),
55
57
  startScanSpinner
56
58
  )
59
+
57
60
  const scanResultsInstances = await scanResults.returnScanResultsInstances(
58
61
  configToUse,
59
62
  scanDetail.id
60
63
  )
64
+
65
+ const endTime = performance.now()
66
+ const scanDurationMs = endTime - startTime
61
67
  succeedSpinner(startScanSpinner, 'Contrast Scan complete')
68
+ console.log(
69
+ `----- Scan completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
70
+ )
62
71
  const projectOverview = await scanResults.returnScanProjectById(configToUse)
63
72
  return { projectOverview, scanDetail, scanResultsInstances }
64
73
  }
@@ -2,6 +2,7 @@ const commonApi = require('../utils/commonApi')
2
2
  const requestUtils = require('../../src/utils/requestUtils')
3
3
  const oraFunctions = require('../utils/oraWrapper')
4
4
  const _ = require('lodash')
5
+ const i18n = require('i18n')
5
6
 
6
7
  const getScanId = async (config, codeArtifactId, client) => {
7
8
  return client
@@ -47,6 +48,16 @@ const returnScanResults = async (
47
48
  if (result.body.status === 'FAILED') {
48
49
  complete = true
49
50
  oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan Failed.')
51
+ console.log(result.body.errorMessage)
52
+ if (
53
+ result.body.errorMessage ===
54
+ 'Unable to determine language for code artifact'
55
+ ) {
56
+ console.log(
57
+ 'Try scanning again using --language param. ',
58
+ i18n.__('scanOptionsLanguageSummary')
59
+ )
60
+ }
50
61
  process.exit(1)
51
62
  }
52
63
  }
@@ -6,6 +6,8 @@ type ContrastConfOptions = Partial<{
6
6
  apiKey: string
7
7
  orgId: string
8
8
  authHeader: string
9
+ numOfRuns: number
10
+ updateMessageHidden: boolean
9
11
  }>
10
12
 
11
13
  type ContrastConf = Conf<ContrastConfOptions>
@@ -15,6 +17,16 @@ const localConfig = (name: string, version: string) => {
15
17
  configName: name
16
18
  })
17
19
  config.set('version', version)
20
+
21
+ if (process.env.CONTRAST_CODSEC_DISABLE_UPDATE_MESSAGE) {
22
+ config.set(
23
+ 'updateMessageHidden',
24
+ JSON.parse(
25
+ process.env.CONTRAST_CODSEC_DISABLE_UPDATE_MESSAGE.toLowerCase()
26
+ )
27
+ )
28
+ }
29
+
18
30
  if (!config.has('host')) {
19
31
  config.set('host', 'https://ce.contrastsecurity.com/')
20
32
  }
@@ -1,4 +1,4 @@
1
- const getAuth = parsedCLIOptions => {
1
+ const getAuth = (parsedCLIOptions = {}) => {
2
2
  let params = {}
3
3
  params.apiKey = parsedCLIOptions['apiKey']
4
4
  params.authorization = parsedCLIOptions['authorization']
@@ -8,7 +8,7 @@ function sendRequest({ options, method = 'put' }) {
8
8
  }
9
9
 
10
10
  const millisToSeconds = millis => {
11
- return ((millis % 60000) / 1000).toFixed(0)
11
+ return (millis / 1000).toFixed(0)
12
12
  }
13
13
 
14
14
  const sleep = ms => {
@@ -0,0 +1,19 @@
1
+ const { SARIF_FILE } = require('../constants/constants')
2
+ const commonApi = require('./commonApi')
3
+ const saveResults = require('../scan/saveResults')
4
+ const i18n = require('i18n')
5
+
6
+ const saveScanFile = async (config, scanResults) => {
7
+ if (config.save === null || config.save.toUpperCase() === SARIF_FILE) {
8
+ const scanId = scanResults.scanDetail.id
9
+ const client = commonApi.getHttpClient(config)
10
+ const rawResults = await client.getSpecificScanResultSarif(config, scanId)
11
+ await saveResults.writeResultsToFile(rawResults?.body)
12
+ } else {
13
+ console.log(i18n.__('scanNoFiletypeSpecifiedForSave'))
14
+ }
15
+ }
16
+
17
+ module.exports = {
18
+ saveScanFile: saveScanFile
19
+ }
@@ -1,17 +0,0 @@
1
- "use strict";
2
- const { getGlobalProperties, getFeatures, isFeatureEnabled } = require('../util/generalAPI');
3
- const { CLI_IGNORE_DEV_DEPS } = require('../util/capabilities');
4
- const checkDevDeps = async (config) => {
5
- const shouldIgnoreDev = config.ignoreDev;
6
- const globalProperties = await getGlobalProperties();
7
- const features = getFeatures(globalProperties.internal_version);
8
- const isfeatureEnabled = isFeatureEnabled(features, CLI_IGNORE_DEV_DEPS);
9
- let ignoreDevUrl = false;
10
- if (shouldIgnoreDev) {
11
- ignoreDevUrl = isfeatureEnabled;
12
- }
13
- return ignoreDevUrl;
14
- };
15
- module.exports = {
16
- checkDevDeps
17
- };
@@ -1,81 +0,0 @@
1
- "use strict";
2
- const commonReport = require('./commonReportingFunctions');
3
- const { handleResponseErrors } = require('../commonApi');
4
- const { getHttpClient } = require('../../../utils/commonApi');
5
- const vulnReportWithoutDevDep = async (analysis, applicationId, snapshotId, config) => {
6
- if (config.report) {
7
- const reportResponse = await getSpecReport(snapshotId, config);
8
- if (reportResponse !== undefined) {
9
- const severity = config.cveSeverity;
10
- const id = applicationId;
11
- const name = config.applicationName;
12
- const hasSomeVulnerabilitiesReported = formatVulnerabilityOutput(reportResponse.vulnerabilities, severity, id, name, config);
13
- commonReport.analyseReportOptions(hasSomeVulnerabilitiesReported);
14
- }
15
- }
16
- };
17
- const getSpecReport = async (reportId, config) => {
18
- const client = getHttpClient(config);
19
- return client
20
- .getSpecificReport(config, reportId)
21
- .then(res => {
22
- if (res.statusCode === 200) {
23
- commonReport.displaySuccessMessageReport();
24
- return res.body;
25
- }
26
- else {
27
- handleResponseErrors(res, 'report');
28
- }
29
- })
30
- .catch(err => {
31
- console.log(err);
32
- });
33
- };
34
- const countSeverity = vulnerabilities => {
35
- const severityCount = {
36
- critical: 0,
37
- high: 0,
38
- medium: 0,
39
- low: 0
40
- };
41
- for (const key of Object.keys(vulnerabilities)) {
42
- vulnerabilities[key].forEach(vuln => {
43
- if (vuln.severityCode === 'HIGH') {
44
- severityCount['high'] += 1;
45
- }
46
- else if (vuln.severityCode === 'MEDIUM') {
47
- severityCount['medium'] += 1;
48
- }
49
- else if (vuln.severityCode === 'LOW') {
50
- severityCount['low'] += 1;
51
- }
52
- else if (vuln.severityCode === 'CRITICAL') {
53
- severityCount['critical'] += 1;
54
- }
55
- });
56
- }
57
- return severityCount;
58
- };
59
- const formatVulnerabilityOutput = (vulnerabilities, severity, id, name, config) => {
60
- const numberOfVulnerableLibraries = Object.keys(vulnerabilities).length;
61
- let numberOfCves = 0;
62
- for (const key of Object.keys(vulnerabilities)) {
63
- numberOfCves += vulnerabilities[key].length;
64
- }
65
- commonReport.createLibraryHeader(id, numberOfVulnerableLibraries, numberOfCves, name);
66
- const severityCount = countSeverity(vulnerabilities);
67
- const filteredVulns = commonReport.filterVulnerabilitiesBySeverity(severity, vulnerabilities);
68
- let hasSomeVulnerabilitiesReported;
69
- hasSomeVulnerabilitiesReported = commonReport.printVulnerabilityResponse(severity, filteredVulns, vulnerabilities);
70
- console.log('\n **************************' +
71
- ` Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVE's ` +
72
- '************************** ');
73
- console.log(' \n Please go to the Contrast UI to view your dependency tree: \n' +
74
- ` \n ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
75
- return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount];
76
- };
77
- module.exports = {
78
- vulnReportWithoutDevDep: vulnReportWithoutDevDep,
79
- formatVulnerabilityOutput: formatVulnerabilityOutput,
80
- getSpecReport: getSpecReport
81
- };
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const latest_version_1 = __importDefault(require("latest-version"));
7
- const constants_1 = require("../constants/constants");
8
- const boxen_1 = __importDefault(require("boxen"));
9
- const chalk_1 = __importDefault(require("chalk"));
10
- const semver_1 = __importDefault(require("semver"));
11
- async function findLatestCLIVersion() {
12
- const latestCLIVersion = await (0, latest_version_1.default)('@contrast/contrast');
13
- if (semver_1.default.lt(constants_1.APP_VERSION, latestCLIVersion)) {
14
- const updateAvailableMessage = `Update available ${chalk_1.default.yellow(constants_1.APP_VERSION)} → ${chalk_1.default.green(latestCLIVersion)}`;
15
- const updateAvailableCommand = `Run ${chalk_1.default.cyan('npm i @contrast/contrast')} to update`;
16
- console.log((0, boxen_1.default)(`${updateAvailableMessage}\n${updateAvailableCommand}`, {
17
- margin: 1,
18
- padding: 1,
19
- align: 'center'
20
- }));
21
- }
22
- }
23
- exports.default = findLatestCLIVersion;
@@ -1,30 +0,0 @@
1
- 'use strict'
2
- Object.defineProperty(exports, '__esModule', { value: true })
3
- exports.pollScanDetail = void 0
4
- const requestUtils_1 = require('../utils/requestUtils')
5
- const pollScanDetail = async (
6
- config,
7
- params,
8
- scanId,
9
- httpClient,
10
- pollCount,
11
- showProgress = false
12
- ) => {
13
- await (0, requestUtils_1.sleep)(5000)
14
- return httpClient.getFunctionScan(config, params, scanId).then(res => {
15
- const { resultsCount = 0 } = res?.body?.data?.scan || {}
16
- if (showProgress) {
17
- process.stdout.write(
18
- `\rScanning (${resultsCount} results found so far)${'.'.repeat(
19
- pollCount
20
- )}`
21
- )
22
- }
23
- if (res.statusCode === 200) {
24
- return res
25
- } else {
26
- throw Error(`Failed to get scan detail: ${res.statusCode} ${res.body}`)
27
- }
28
- })
29
- }
30
- exports.pollScanDetail = pollScanDetail
@@ -1,15 +0,0 @@
1
- 'use strict'
2
- const fg = require('fast-glob')
3
- const i18n = require('i18n')
4
- const findFile = async () => {
5
- console.log(i18n.__('searchingScanFileDirectory', process.cwd()))
6
- const entries = fg(['**/*.jar', '**/*.war', '**/*.zip', '**/*.dll'], {
7
- dot: false,
8
- deep: 3,
9
- onlyFiles: true
10
- })
11
- return entries
12
- }
13
- module.exports = {
14
- findFile
15
- }
@@ -1,31 +0,0 @@
1
- "use strict";
2
- const fg = require('fast-glob');
3
- const fs = require('fs');
4
- const i18n = require('i18n');
5
- const findFile = async () => {
6
- console.log(i18n.__('searchingScanFileDirectory', process.cwd()));
7
- return fg(['**/*.jar', '**/*.war', '**/*.zip', '**/*.dll'], {
8
- dot: false,
9
- deep: 3,
10
- onlyFiles: true
11
- });
12
- };
13
- const checkFilePermissions = file => {
14
- let readableFile = false;
15
- try {
16
- fs.accessSync(file, fs.constants.R_OK);
17
- return (readableFile = true);
18
- }
19
- catch (err) {
20
- console.log('Invalid permissions found on ', file);
21
- process.exit(0);
22
- }
23
- };
24
- const fileExists = path => {
25
- return fs.existsSync(path);
26
- };
27
- module.exports = {
28
- findFile,
29
- fileExists,
30
- checkFilePermissions
31
- };
@@ -1,12 +0,0 @@
1
- "use strict";
2
- const cliOptions = require('../parsedCLIOptions');
3
- const getGenericCommandLineParams = () => {
4
- return cliOptions.getCommandLineArgsGeneric();
5
- };
6
- const getSpecificCommandLineParams = (parameterList, optionDefinition) => {
7
- return cliOptions.getCommandLineArgsCustom(parameterList, optionDefinition);
8
- };
9
- module.exports = {
10
- getSpecificCommandLineParams,
11
- getGenericCommandLineParams
12
- };
@@ -1,6 +0,0 @@
1
- 'use strict'
2
- const fs = require('fs')
3
- const yaml = require('js-yaml')
4
- const getAuth = yamlPath => {
5
- const yamlParams = yaml.load(fs.readFileSync(yamlPath, 'utf8'))
6
- }
@@ -1,27 +0,0 @@
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
- }