@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.
- package/.prettierignore +2 -0
- package/README.md +103 -133
- package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +26 -11
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +62 -234
- package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
- package/dist/commands/audit/auditController.js +6 -3
- package/dist/commands/audit/saveFile.js +11 -0
- package/dist/commands/auth/auth.js +19 -1
- package/dist/commands/config/config.js +19 -8
- package/dist/commands/scan/processScan.js +8 -25
- package/dist/common/HTTPClient.js +30 -26
- package/dist/common/errorHandling.js +17 -1
- package/dist/common/versionChecker.js +32 -0
- package/dist/constants/constants.js +4 -2
- package/dist/constants/lambda.js +3 -1
- package/dist/constants/locales.js +41 -18
- package/dist/constants.js +39 -3
- package/dist/index.js +49 -28
- package/dist/lambda/help.js +22 -14
- package/dist/lambda/lambda.js +6 -0
- package/dist/sbom/generateSbom.js +20 -0
- package/dist/scan/help.js +4 -2
- package/dist/scan/models/groupedResultsModel.js +10 -0
- package/dist/scan/models/resultContentModel.js +2 -0
- package/dist/scan/models/scanResultsModel.js +11 -0
- package/dist/scan/populateProjectIdAndProjectName.js +1 -0
- package/dist/scan/saveResults.js +9 -10
- package/dist/scan/scan.js +99 -74
- package/dist/scan/scanConfig.js +20 -1
- package/dist/scan/scanController.js +7 -2
- package/dist/scan/scanResults.js +6 -0
- package/dist/utils/getConfig.js +3 -0
- package/dist/utils/paramsUtil/commandlineParams.js +1 -1
- package/dist/utils/requestUtils.js +1 -1
- package/dist/utils/saveFile.js +19 -0
- package/package.json +2 -2
- package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +33 -15
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +127 -0
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
- package/src/commands/audit/auditController.ts +12 -3
- package/src/commands/audit/processAudit.ts +0 -1
- package/src/commands/audit/saveFile.ts +6 -0
- package/src/commands/auth/auth.js +25 -1
- package/src/commands/config/config.js +22 -8
- package/src/commands/scan/processScan.js +8 -29
- package/src/common/HTTPClient.js +42 -36
- package/src/common/errorHandling.ts +29 -2
- package/src/common/versionChecker.ts +41 -0
- package/src/constants/constants.js +5 -4
- package/src/constants/lambda.js +3 -1
- package/src/constants/locales.js +51 -19
- package/src/constants.js +44 -3
- package/src/index.ts +63 -31
- package/src/lambda/help.ts +22 -14
- package/src/lambda/lambda.ts +8 -0
- package/src/sbom/generateSbom.ts +17 -0
- package/src/scan/help.js +4 -2
- package/src/scan/models/groupedResultsModel.ts +18 -0
- package/src/scan/models/resultContentModel.ts +86 -0
- package/src/scan/models/scanResultsModel.ts +52 -0
- package/src/scan/populateProjectIdAndProjectName.js +1 -0
- package/src/scan/saveResults.js +8 -9
- package/src/scan/scan.ts +192 -0
- package/src/scan/scanConfig.js +26 -1
- package/src/scan/scanController.js +11 -2
- package/src/scan/scanResults.js +11 -0
- package/src/utils/getConfig.ts +12 -0
- package/src/utils/paramsUtil/commandlineParams.js +1 -1
- package/src/utils/requestUtils.js +1 -1
- package/src/utils/saveFile.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
- package/dist/common/findLatestCLIVersion.js +0 -23
- package/dist/lambda/scanDetail.js +0 -30
- package/dist/scan/fileFinder.js +0 -15
- package/dist/utils/fileUtils.js +0 -31
- package/dist/utils/paramsUtil/genericCommandLineParams.js +0 -12
- package/dist/utils/paramsUtil/yamlParams.js +0 -6
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
- package/src/common/findLatestCLIVersion.ts +0 -27
- package/src/scan/scan.js +0 -162
package/src/constants/locales.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { lambda } = require('./lambda')
|
|
2
|
+
const chalk = require('chalk')
|
|
2
3
|
|
|
3
4
|
const en_locales = () => {
|
|
4
5
|
return {
|
|
@@ -13,8 +14,6 @@ const en_locales = () => {
|
|
|
13
14
|
vulnerabilitiesSuccessMessage: ' Vulnerability data successfully retrieved',
|
|
14
15
|
vulnerabilitiesFailureMessage:
|
|
15
16
|
' Unable to retrieve library vulnerabilities from Team Server.',
|
|
16
|
-
reportSuccessMessage: ' Report successfully retrieved',
|
|
17
|
-
reportFailureMessage: ' Unable to generate library report.',
|
|
18
17
|
catchErrorMessage: 'Contrast UI error: ',
|
|
19
18
|
dependenciesNote:
|
|
20
19
|
'Please Note: We currently only support projects with one .csproj AND *.package.lock.json',
|
|
@@ -171,13 +170,19 @@ const en_locales = () => {
|
|
|
171
170
|
constantsSeverity:
|
|
172
171
|
'Combined with the --report command, allows the user to report libraries with vulnerabilities above a chosen severity level. For example, cve_severity medium only reports libraries with vulnerabilities at medium or higher severity. Values for level are high, medium or low.',
|
|
173
172
|
constantsCount: "The number of CVE's that must be exceeded to fail a build",
|
|
174
|
-
constantsHeader: 'Contrast
|
|
173
|
+
constantsHeader: 'CodeSec by Contrast Security',
|
|
175
174
|
constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
|
|
176
175
|
constantsContrastContent:
|
|
177
|
-
'Use the Contrast CLI,
|
|
176
|
+
'Use the Contrast CLI to run a scan (Java, JavaScript and .NET ) or lambda command (Java and Python) to find your vulnerabilities and start securing your code.',
|
|
178
177
|
constantsUsageGuideContentRecommendation:
|
|
179
178
|
'Our recommendation is that this is invoked as part of a CI pipeline so that running the cli is automated as part of your build process.',
|
|
180
179
|
constantsPrerequisitesHeader: 'Pre-requisites',
|
|
180
|
+
constantsAuthUsageHeader: 'Usage',
|
|
181
|
+
constantsAuthUsageContents: 'contrast auth',
|
|
182
|
+
constantsAuthHeaderContents:
|
|
183
|
+
'Authorize with external identity provider to perform scans on code',
|
|
184
|
+
configHeader: 'Config',
|
|
185
|
+
constantsConfigUsageContents: 'view / clear the configuration',
|
|
181
186
|
constantsPrerequisitesContent:
|
|
182
187
|
'To scan a Java project you will need a .jar or .war file for analysis\n' +
|
|
183
188
|
'To scan a Javascript project you will need a .js or.zip file for analysis\n' +
|
|
@@ -185,7 +190,7 @@ const en_locales = () => {
|
|
|
185
190
|
constantsUsage: 'Usage',
|
|
186
191
|
constantsUsageCommandExample: 'contrast [command] [options]',
|
|
187
192
|
constantsUsageCommandInfo:
|
|
188
|
-
'The file argument is optional. If no file is given, Contrast will search for a .jar, .war, .
|
|
193
|
+
'The file argument is optional. If no file is given, Contrast will search for a .jar, .war, .exe or .zip file in the working directory.\n',
|
|
189
194
|
constantsUsageCommandInfo24Hours:
|
|
190
195
|
'Submitted files are encrypted during upload and deleted in 24 hours.',
|
|
191
196
|
constantsAnd: 'AND',
|
|
@@ -267,7 +272,9 @@ const en_locales = () => {
|
|
|
267
272
|
'Add the application code this application should use in the Contrast UI',
|
|
268
273
|
constantsIgnoreCertErrors:
|
|
269
274
|
' For EOP users with a local Teamserver install, this will bypass the SSL certificate and recognise a self signed certificate.',
|
|
270
|
-
constantsSave: ' Saves the Scan Results
|
|
275
|
+
constantsSave: ' Saves the Scan Results SARIF to file.',
|
|
276
|
+
scanLabel:
|
|
277
|
+
"adds a label to the scan - defaults to 'Started by CLI tool at current date'",
|
|
271
278
|
constantsIgnoreDev:
|
|
272
279
|
'Combined with the --report command excludes developer dependencies from the vulnerabilities report. By default all dependencies are included in a report.',
|
|
273
280
|
constantsCommands: 'Commands',
|
|
@@ -277,7 +284,7 @@ const en_locales = () => {
|
|
|
277
284
|
ignoreDevDep: 'No private libraries that are not scoped detected',
|
|
278
285
|
foundExistingProjectScan: 'Found existing project...',
|
|
279
286
|
projectCreatedScan: 'Project created',
|
|
280
|
-
uploadingScan: 'Uploading
|
|
287
|
+
uploadingScan: 'Uploading file to scan.',
|
|
281
288
|
uploadingScanSuccessful: 'Uploaded file successfully.',
|
|
282
289
|
uploadingScanFail: 'Unable to upload the file.',
|
|
283
290
|
waitingTimedOut: 'Timed out.',
|
|
@@ -288,14 +295,15 @@ const en_locales = () => {
|
|
|
288
295
|
specifyFileScanError:
|
|
289
296
|
'Java Scan requires a .war or .jar file. Javascript Scan requires a .js or .zip file.\nTo start a Scan enter "contrast scan -f <path-to-file>"',
|
|
290
297
|
populateProjectIdMessage: 'project ID is %s',
|
|
298
|
+
genericServiceError: 'returned with status code %s',
|
|
299
|
+
projectIdError: 'Your project ID is %s please check this is correct',
|
|
291
300
|
permissionsError:
|
|
292
301
|
'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
|
|
293
302
|
scanErrorFileMessage:
|
|
294
303
|
'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
|
|
295
304
|
helpAuthSummary:
|
|
296
305
|
'Authenticate Contrast using your Github or Google account',
|
|
297
|
-
helpScanSummary:
|
|
298
|
-
'Searches for a .jar, .war, .js or .zip file in the working directory, uploads for analysis and returns the results',
|
|
306
|
+
helpScanSummary: 'Perform static analysis on binaries / code artifacts',
|
|
299
307
|
helpLambdaSummary: 'Perform scan on AWS Lambda functions',
|
|
300
308
|
helpVersionSummary: 'Displays version of Contrast CLI',
|
|
301
309
|
helpConfigSummary: 'Displays stored credentials',
|
|
@@ -306,6 +314,7 @@ const en_locales = () => {
|
|
|
306
314
|
versionName: 'version',
|
|
307
315
|
configName: 'config',
|
|
308
316
|
helpName: 'help',
|
|
317
|
+
scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
|
|
309
318
|
scanOptionsLanguageSummaryOptional:
|
|
310
319
|
'Language of file to send for analysis. ',
|
|
311
320
|
scanOptionsLanguageSummaryRequired:
|
|
@@ -313,30 +322,41 @@ const en_locales = () => {
|
|
|
313
322
|
scanOptionsTimeoutSummary:
|
|
314
323
|
'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
|
|
315
324
|
scanOptionsFileNameSummary:
|
|
316
|
-
'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .
|
|
325
|
+
'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
|
|
317
326
|
scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
|
|
318
327
|
authSuccessMessage: 'Authentication successful',
|
|
319
|
-
runAuthSuccessMessage:
|
|
328
|
+
runAuthSuccessMessage:
|
|
329
|
+
"Now you can use Contrast CLI \nRun 'contrast scan' on your file \n" +
|
|
330
|
+
"or 'contrast help' to learn more about the capabilities.",
|
|
320
331
|
authWaitingMessage: 'Waiting for auth...',
|
|
321
332
|
authTimedOutMessage: 'Auth Timed out, try again',
|
|
322
333
|
zipErrorScan:
|
|
323
334
|
'We only support zip files for JAVASCRIPT language, please set the flag --language JAVASCRIPT',
|
|
324
335
|
unknownFileErrorScan: 'Unsupported file selected for Scan.',
|
|
325
|
-
foundScanFile: '
|
|
336
|
+
foundScanFile: 'Found: %s',
|
|
326
337
|
foundDetailedVulnerabilities:
|
|
327
|
-
'%s Critical
|
|
338
|
+
chalk.bold('%s Critical') +
|
|
339
|
+
' | ' +
|
|
340
|
+
chalk.bold('%s High') +
|
|
341
|
+
' | %s Medium | %s Low | %s Note',
|
|
328
342
|
requiredParams: 'All required parameters are not present.',
|
|
329
343
|
timeoutScan: 'Timeout set to 5 minutes.',
|
|
330
344
|
searchingScanFileDirectory: 'Searching for file to scan from %s...',
|
|
331
345
|
scanHeader: 'Contrast Scan CLI',
|
|
332
|
-
|
|
346
|
+
authHeader: 'Auth',
|
|
347
|
+
lambdaHeader: 'Contrast Lambda CLI',
|
|
333
348
|
lambdaSummary:
|
|
334
349
|
'Performs static security scan on an AWS Lambda Function.\nProduces CVE (Vulnerable Dependencies) and Least Privilege violations/remediation results.',
|
|
335
350
|
lambdaUsage: 'contrast lambda --function-name <function> [options]',
|
|
336
|
-
lambdaPrerequisitesContent: '
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
351
|
+
lambdaPrerequisitesContent: '',
|
|
352
|
+
lambdaPrerequisitesContentLambdaLanguages:
|
|
353
|
+
'Supported runtimes: Java & Python',
|
|
354
|
+
lambdaPrerequisitesContentLambdaDescriptionTitle: 'AWS Requirements\n',
|
|
355
|
+
lambdaPrerequisitesContentLambdaDescription:
|
|
356
|
+
'Make sure you have the AWS credentials configured on your local environment. \nYou need the following AWS permissions configured on your IAM user:\n - Lambda: GetFunction, GetLayerVersionֿ\n - IAM: GetRolePolicy, GetPolicy, GetPolicyVersion, ListRolePolicies, ListAttachedRolePolicies',
|
|
357
|
+
scanFileNameOption: '-f, --file',
|
|
358
|
+
lambdaFunctionNameOption: '-f, --function-name',
|
|
359
|
+
lambdaListFunctionsOption: '-l, --list-functions',
|
|
340
360
|
lambdaEndpointOption: '-e, --endpoint-url',
|
|
341
361
|
lambdaRegionOption: '-r, --region',
|
|
342
362
|
lambdaProfileOption: '-p, --profile',
|
|
@@ -399,7 +419,19 @@ const en_locales = () => {
|
|
|
399
419
|
'saves the output in specified format Txt text, sbom',
|
|
400
420
|
scanNoVulnerabilitiesFound: '👏 No vulnerabilities found',
|
|
401
421
|
scanNoFiletypeSpecifiedForSave:
|
|
402
|
-
'Please specify file type to save results to',
|
|
422
|
+
'Please specify file type to save results to, accepted value is SARIF',
|
|
423
|
+
auditSBOMSaveSuccess:
|
|
424
|
+
'\n Software Bill of Materials (SBOM) saved successfully',
|
|
425
|
+
auditNoFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold(
|
|
426
|
+
'No file type specified for --save option to save audit results to. Use audit --help to see valid --save options.'
|
|
427
|
+
)}`,
|
|
428
|
+
auditBadFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold(
|
|
429
|
+
'Bad file type specified for --save option. Use audit --help to see valid --save options.'
|
|
430
|
+
)}`,
|
|
431
|
+
auditReportWaiting: 'Waiting for report...',
|
|
432
|
+
auditReportFail: 'Report Retrieval Failed, please try again',
|
|
433
|
+
auditReportSuccessMessage: ' Report successfully retrieved',
|
|
434
|
+
auditReportFailureMessage: ' Unable to generate library report.',
|
|
403
435
|
...lambda
|
|
404
436
|
}
|
|
405
437
|
}
|
package/src/constants.js
CHANGED
|
@@ -20,6 +20,15 @@ const scanOptionDefinitions = [
|
|
|
20
20
|
'}: ' +
|
|
21
21
|
i18n.__('constantsProjectName')
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
name: 'language',
|
|
25
|
+
alias: 'l',
|
|
26
|
+
description:
|
|
27
|
+
'{bold ' +
|
|
28
|
+
i18n.__('constantsOptional') +
|
|
29
|
+
'}: ' +
|
|
30
|
+
i18n.__('scanOptionsLanguageSummary')
|
|
31
|
+
},
|
|
23
32
|
{
|
|
24
33
|
name: 'file',
|
|
25
34
|
alias: 'f',
|
|
@@ -75,7 +84,6 @@ const scanOptionDefinitions = [
|
|
|
75
84
|
},
|
|
76
85
|
{
|
|
77
86
|
name: 'host',
|
|
78
|
-
alias: 'h',
|
|
79
87
|
description:
|
|
80
88
|
'{bold ' +
|
|
81
89
|
i18n.__('constantsRequired') +
|
|
@@ -124,8 +132,14 @@ const scanOptionDefinitions = [
|
|
|
124
132
|
description:
|
|
125
133
|
'{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('constantsSave')
|
|
126
134
|
},
|
|
135
|
+
{
|
|
136
|
+
name: 'label',
|
|
137
|
+
description:
|
|
138
|
+
'{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
|
|
139
|
+
},
|
|
127
140
|
{
|
|
128
141
|
name: 'help',
|
|
142
|
+
alias: 'h',
|
|
129
143
|
type: Boolean
|
|
130
144
|
},
|
|
131
145
|
{
|
|
@@ -135,6 +149,29 @@ const scanOptionDefinitions = [
|
|
|
135
149
|
}
|
|
136
150
|
]
|
|
137
151
|
|
|
152
|
+
const authOptionDefinitions = [
|
|
153
|
+
{
|
|
154
|
+
name: 'help',
|
|
155
|
+
alias: 'h',
|
|
156
|
+
type: Boolean
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
const configOptionDefinitions = [
|
|
161
|
+
{
|
|
162
|
+
name: 'help',
|
|
163
|
+
alias: 'h',
|
|
164
|
+
type: Boolean,
|
|
165
|
+
description: 'Help text'
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'clear',
|
|
169
|
+
alias: 'c',
|
|
170
|
+
type: Boolean,
|
|
171
|
+
description: 'Clear the currently stored config'
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
|
|
138
175
|
const auditOptionDefinitions = [
|
|
139
176
|
{
|
|
140
177
|
name: 'application-id',
|
|
@@ -291,6 +328,7 @@ const mainUsageGuide = commandLineUsage([
|
|
|
291
328
|
header: i18n.__('constantsCommands'),
|
|
292
329
|
content: [
|
|
293
330
|
{ name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
|
|
331
|
+
{ name: i18n.__('scanName'), summary: i18n.__('helpScanSummary') },
|
|
294
332
|
{ name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
|
|
295
333
|
{ name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
|
|
296
334
|
{ name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
|
|
@@ -298,7 +336,8 @@ const mainUsageGuide = commandLineUsage([
|
|
|
298
336
|
]
|
|
299
337
|
},
|
|
300
338
|
{
|
|
301
|
-
content:
|
|
339
|
+
content:
|
|
340
|
+
'{underline https://developer.contrastsecurity.com/} \n For technical support head to {underline https://support.contrastsecurity.com}'
|
|
302
341
|
}
|
|
303
342
|
])
|
|
304
343
|
|
|
@@ -309,6 +348,8 @@ module.exports = {
|
|
|
309
348
|
mainUsageGuide,
|
|
310
349
|
mainDefinition,
|
|
311
350
|
scanOptionDefinitions,
|
|
312
|
-
auditOptionDefinitions
|
|
351
|
+
auditOptionDefinitions,
|
|
352
|
+
authOptionDefinitions,
|
|
353
|
+
configOptionDefinitions
|
|
313
354
|
}
|
|
314
355
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,11 @@ import constants from './constants'
|
|
|
7
7
|
import { APP_NAME, APP_VERSION } from './constants/constants'
|
|
8
8
|
import { processLambda } from './lambda/lambda'
|
|
9
9
|
import { localConfig } from './utils/getConfig'
|
|
10
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
findLatestCLIVersion,
|
|
12
|
+
isCorrectNodeVersion
|
|
13
|
+
} from './common/versionChecker'
|
|
14
|
+
import { findCommandOnError } from './common/errorHandling'
|
|
11
15
|
|
|
12
16
|
const {
|
|
13
17
|
commandLineDefinitions: { mainUsageGuide, mainDefinition }
|
|
@@ -30,46 +34,74 @@ const getMainOption = () => {
|
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
const start = async () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
if (await isCorrectNodeVersion(process.version)) {
|
|
38
|
+
const { mainOptions, argv: argvMain } = getMainOption()
|
|
39
|
+
const command =
|
|
40
|
+
mainOptions.command != undefined ? mainOptions.command.toLowerCase() : ''
|
|
41
|
+
if (
|
|
42
|
+
command === 'version' ||
|
|
43
|
+
argvMain.includes('--v') ||
|
|
44
|
+
argvMain.includes('--version')
|
|
45
|
+
) {
|
|
46
|
+
console.log(APP_VERSION)
|
|
47
|
+
await findLatestCLIVersion(config.get('updateMessageHidden') as boolean)
|
|
48
|
+
return
|
|
49
|
+
}
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
config.set('numOfRuns', config.get('numOfRuns') + 1)
|
|
42
53
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
if (config.get('numOfRuns') >= 5) {
|
|
56
|
+
await findLatestCLIVersion(config.get('updateMessageHidden') as boolean)
|
|
57
|
+
config.set('numOfRuns', 0)
|
|
58
|
+
}
|
|
46
59
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
if (command === 'config') {
|
|
61
|
+
return processConfig(argvMain, config)
|
|
62
|
+
}
|
|
50
63
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
if (command === 'auth') {
|
|
65
|
+
return await processAuth(argvMain, config)
|
|
66
|
+
}
|
|
54
67
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
if (command === 'lambda') {
|
|
69
|
+
return await processLambda(argvMain)
|
|
70
|
+
}
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
if (command === 'scan') {
|
|
73
|
+
return await processScan(argvMain)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (command === 'audit') {
|
|
77
|
+
return await processAudit(argvMain)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
command === 'help' ||
|
|
82
|
+
argvMain.includes('--help') ||
|
|
83
|
+
Object.keys(mainOptions).length === 0
|
|
84
|
+
) {
|
|
85
|
+
console.log(mainUsageGuide)
|
|
86
|
+
} else if (mainOptions._unknown !== undefined) {
|
|
87
|
+
const foundCommand = findCommandOnError(mainOptions._unknown)
|
|
62
88
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
foundCommand
|
|
90
|
+
? console.log(
|
|
91
|
+
`Unknown Command: Did you mean "${foundCommand}"? \nUse "${foundCommand} --help" for the full list of options`
|
|
92
|
+
)
|
|
93
|
+
: console.log(
|
|
94
|
+
`Unknown Command: ${command} \nUse --help for the full list`
|
|
95
|
+
)
|
|
96
|
+
} else {
|
|
97
|
+
console.log(`Unknown Command: ${command} \nUse --help for the full list`)
|
|
98
|
+
}
|
|
99
|
+
process.exit(9)
|
|
69
100
|
} else {
|
|
70
101
|
console.log(
|
|
71
|
-
'
|
|
102
|
+
'Contrast supports Node versions >=16.13.2 <17. Please use one of those versions.'
|
|
72
103
|
)
|
|
104
|
+
process.exit(9)
|
|
73
105
|
}
|
|
74
106
|
}
|
|
75
107
|
|
package/src/lambda/help.ts
CHANGED
|
@@ -8,7 +8,15 @@ const lambdaUsageGuide = commandLineUsage([
|
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
header: i18n.__('constantsPrerequisitesHeader'),
|
|
11
|
-
content: [
|
|
11
|
+
content: [
|
|
12
|
+
'{bold ' +
|
|
13
|
+
i18n.__('lambdaPrerequisitesContentLambdaLanguages') +
|
|
14
|
+
'}\n\n' +
|
|
15
|
+
'{bold ' +
|
|
16
|
+
i18n.__('lambdaPrerequisitesContentLambdaDescriptionTitle') +
|
|
17
|
+
'}' +
|
|
18
|
+
i18n.__('lambdaPrerequisitesContentLambdaDescription')
|
|
19
|
+
]
|
|
12
20
|
},
|
|
13
21
|
{
|
|
14
22
|
header: i18n.__('constantsUsage'),
|
|
@@ -18,49 +26,49 @@ const lambdaUsageGuide = commandLineUsage([
|
|
|
18
26
|
header: i18n.__('constantsOptions'),
|
|
19
27
|
content: [
|
|
20
28
|
{
|
|
21
|
-
name: i18n.__('lambdaFunctionNameOption'),
|
|
29
|
+
name: '{bold ' + i18n.__('lambdaFunctionNameOption') + '}',
|
|
22
30
|
summary: i18n.__('lambdaFunctionNameSummery')
|
|
23
31
|
},
|
|
24
32
|
{
|
|
25
|
-
name: i18n.__('lambdaListFunctionsOption'),
|
|
33
|
+
name: '{bold ' + i18n.__('lambdaListFunctionsOption') + '}',
|
|
26
34
|
summary: i18n.__('lambdaListFunctionsSummery')
|
|
27
35
|
},
|
|
28
36
|
{
|
|
29
|
-
name: i18n.__('lambdaEndpointOption'),
|
|
37
|
+
name: '{bold ' + i18n.__('lambdaEndpointOption') + '}',
|
|
30
38
|
summary:
|
|
31
|
-
'{
|
|
39
|
+
'{bold ' +
|
|
32
40
|
i18n.__('constantsOptional') +
|
|
33
41
|
'}: ' +
|
|
34
42
|
i18n.__('lambdaEndpointSummery')
|
|
35
43
|
},
|
|
36
44
|
{
|
|
37
|
-
name: i18n.__('lambdaRegionOption'),
|
|
45
|
+
name: '{bold ' + i18n.__('lambdaRegionOption') + '}',
|
|
38
46
|
summary:
|
|
39
|
-
'{
|
|
47
|
+
'{bold ' +
|
|
40
48
|
i18n.__('constantsOptional') +
|
|
41
49
|
'}: ' +
|
|
42
50
|
i18n.__('lambdaRegionSummery')
|
|
43
51
|
},
|
|
44
52
|
{
|
|
45
|
-
name: i18n.__('lambdaProfileOption'),
|
|
53
|
+
name: '{bold ' + i18n.__('lambdaProfileOption') + '}',
|
|
46
54
|
summary:
|
|
47
|
-
'{
|
|
55
|
+
'{bold ' +
|
|
48
56
|
i18n.__('constantsOptional') +
|
|
49
57
|
'}: ' +
|
|
50
58
|
i18n.__('lambdaProfileSummery')
|
|
51
59
|
},
|
|
52
60
|
{
|
|
53
|
-
name: i18n.__('lambdaJsonOption'),
|
|
61
|
+
name: '{bold ' + i18n.__('lambdaJsonOption') + '}',
|
|
54
62
|
summary:
|
|
55
|
-
'{
|
|
63
|
+
'{bold ' +
|
|
56
64
|
i18n.__('constantsOptional') +
|
|
57
65
|
'}: ' +
|
|
58
66
|
i18n.__('lambdaJsonSummery')
|
|
59
67
|
},
|
|
60
68
|
{
|
|
61
|
-
name: i18n.__('lambdaVerboseOption'),
|
|
69
|
+
name: '{bold ' + i18n.__('lambdaVerboseOption') + '}',
|
|
62
70
|
summary:
|
|
63
|
-
'{
|
|
71
|
+
'{bold ' +
|
|
64
72
|
i18n.__('constantsOptional') +
|
|
65
73
|
'}: ' +
|
|
66
74
|
i18n.__('lambdaVerbosSummery')
|
|
@@ -73,7 +81,7 @@ const lambdaUsageGuide = commandLineUsage([
|
|
|
73
81
|
]
|
|
74
82
|
},
|
|
75
83
|
{
|
|
76
|
-
content: '{underline https://www.contrastsecurity.com}'
|
|
84
|
+
content: '{underline https://www.contrastsecurity.com/developer/codesec}'
|
|
77
85
|
}
|
|
78
86
|
])
|
|
79
87
|
|
package/src/lambda/lambda.ts
CHANGED
|
@@ -12,6 +12,8 @@ import { requestScanFunctionPost } from './scanRequest'
|
|
|
12
12
|
import { getScanResults } from './scanResults'
|
|
13
13
|
import { printResults } from './utils'
|
|
14
14
|
import { getAllLambdas, printAvailableLambdas } from './lambdaUtils'
|
|
15
|
+
import { sleep } from '../utils/requestUtils'
|
|
16
|
+
import ora from '../utils/oraWrapper'
|
|
15
17
|
|
|
16
18
|
type LambdaOptions = {
|
|
17
19
|
functionName?: string
|
|
@@ -123,6 +125,12 @@ const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
|
|
|
123
125
|
})
|
|
124
126
|
}
|
|
125
127
|
|
|
128
|
+
// Wait to make sure we will have all the results
|
|
129
|
+
const startGetherResultsSpinner = ora.returnOra(i18n.__('gatherResults'))
|
|
130
|
+
ora.startSpinner(startGetherResultsSpinner)
|
|
131
|
+
await sleep(15 * 1000)
|
|
132
|
+
ora.succeedSpinner(startGetherResultsSpinner, 'Done gathering results')
|
|
133
|
+
|
|
126
134
|
const resultsResponse = await getScanResults(
|
|
127
135
|
auth,
|
|
128
136
|
params,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getHttpClient } from '../utils/commonApi'
|
|
2
|
+
|
|
3
|
+
export default function generateSbom(config: any) {
|
|
4
|
+
const client = getHttpClient(config)
|
|
5
|
+
return client
|
|
6
|
+
.getSbom(config)
|
|
7
|
+
.then((res: { statusCode: number; body: any }) => {
|
|
8
|
+
if (res.statusCode === 200) {
|
|
9
|
+
return res.body
|
|
10
|
+
} else {
|
|
11
|
+
console.log('Unable to retrieve Software Bill of Materials (SBOM)')
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
.catch((err: any) => {
|
|
15
|
+
console.log(err)
|
|
16
|
+
})
|
|
17
|
+
}
|
package/src/scan/help.js
CHANGED
|
@@ -21,14 +21,16 @@ const scanUsageGuide = commandLineUsage([
|
|
|
21
21
|
optionList: constants.commandLineDefinitions.scanOptionDefinitions,
|
|
22
22
|
hide: [
|
|
23
23
|
'project-id',
|
|
24
|
-
'language',
|
|
25
24
|
'organization-id',
|
|
26
25
|
'api-key',
|
|
27
26
|
'authorization',
|
|
28
27
|
'host',
|
|
29
28
|
'proxy',
|
|
29
|
+
'help',
|
|
30
30
|
'ff',
|
|
31
|
-
'ignore-cert-errors'
|
|
31
|
+
'ignore-cert-errors',
|
|
32
|
+
'verbose',
|
|
33
|
+
'debug'
|
|
32
34
|
]
|
|
33
35
|
},
|
|
34
36
|
{
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class GroupedResultsModel {
|
|
2
|
+
ruleId: string
|
|
3
|
+
lineInfoSet: Set<string>
|
|
4
|
+
cwe?: string[]
|
|
5
|
+
owasp?: string[]
|
|
6
|
+
reference?: string[]
|
|
7
|
+
recommendation?: string
|
|
8
|
+
severity?: string
|
|
9
|
+
advice?: string
|
|
10
|
+
learn?: string[]
|
|
11
|
+
issue?: string
|
|
12
|
+
message?: string
|
|
13
|
+
|
|
14
|
+
constructor(ruleId: string) {
|
|
15
|
+
this.ruleId = ruleId
|
|
16
|
+
this.lineInfoSet = new Set<string>
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
type Importance = 'important' | 'essential'
|
|
2
|
+
|
|
3
|
+
interface ArtifactLocation {
|
|
4
|
+
uri: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface Region {
|
|
8
|
+
startLine: number
|
|
9
|
+
snippet: Snippet
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface Snippet {
|
|
13
|
+
text: string
|
|
14
|
+
rendered: Rendered
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Rendered {
|
|
18
|
+
text: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface PhysicalLocation {
|
|
22
|
+
artifactLocation: ArtifactLocation
|
|
23
|
+
region: Region
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface LogicalLocation {
|
|
27
|
+
fullyQualifiedName: string
|
|
28
|
+
name: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface Location {
|
|
32
|
+
physicalLocation: PhysicalLocation
|
|
33
|
+
logicalLocations?: LogicalLocation[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ThreadFlowLocation {
|
|
37
|
+
importance: Importance
|
|
38
|
+
location: Location
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface ThreadFlow {
|
|
42
|
+
locations: ThreadFlowLocation[]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface Message {
|
|
46
|
+
text: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface CodeFlow {
|
|
50
|
+
message: Message
|
|
51
|
+
threadFlows: ThreadFlow[]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ResultContent {
|
|
55
|
+
message: {text: string};
|
|
56
|
+
id: string
|
|
57
|
+
organizationId: string
|
|
58
|
+
projectId: string
|
|
59
|
+
firstCreatedTime: string
|
|
60
|
+
ruleId: string
|
|
61
|
+
codeFlows: CodeFlow[]
|
|
62
|
+
lastSeenTime: string
|
|
63
|
+
locations: Location[]
|
|
64
|
+
name: string
|
|
65
|
+
description: string
|
|
66
|
+
recommendation: string | null
|
|
67
|
+
risk: string | null
|
|
68
|
+
category: string
|
|
69
|
+
confidence: string
|
|
70
|
+
standards: { [key: string]: string[] }
|
|
71
|
+
cwe: string[]
|
|
72
|
+
owasp: string[]
|
|
73
|
+
reference: string[]
|
|
74
|
+
sink: string
|
|
75
|
+
detailsTrigger: string
|
|
76
|
+
type: RuleType
|
|
77
|
+
source: string
|
|
78
|
+
severity: Severity
|
|
79
|
+
advice: string
|
|
80
|
+
learn: string[]
|
|
81
|
+
issue: string
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type Severity = 'critical' | 'high' | 'medium' | 'low' | 'note'
|
|
85
|
+
|
|
86
|
+
export type RuleType = 'DATA_FLOW' | 'CRYPTO' | 'CONFIG' | 'DEFAULT'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ResultContent } from './resultContentModel'
|
|
2
|
+
|
|
3
|
+
export class ScanResultsModel {
|
|
4
|
+
projectOverview: ProjectOverview
|
|
5
|
+
scanDetail: ScanDetail
|
|
6
|
+
scanResultsInstances: ScanResultsInstances
|
|
7
|
+
|
|
8
|
+
constructor(scan: any) {
|
|
9
|
+
this.projectOverview = scan.projectOverview as ProjectOverview
|
|
10
|
+
this.scanDetail = scan.scanDetail as ScanDetail
|
|
11
|
+
this.scanResultsInstances = scan.scanResultsInstances as ScanResultsInstances
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProjectOverview {
|
|
16
|
+
id: string
|
|
17
|
+
organizationId: string
|
|
18
|
+
name: string
|
|
19
|
+
archived: boolean
|
|
20
|
+
language: string
|
|
21
|
+
critical: number
|
|
22
|
+
high: number
|
|
23
|
+
medium: number
|
|
24
|
+
low: number
|
|
25
|
+
note: number
|
|
26
|
+
lastScanTime: string
|
|
27
|
+
completedScans: number
|
|
28
|
+
lastScanId: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ScanDetail {
|
|
32
|
+
critical: number
|
|
33
|
+
high: number
|
|
34
|
+
medium: number
|
|
35
|
+
low: number
|
|
36
|
+
note: number
|
|
37
|
+
id: string
|
|
38
|
+
organizationId: string
|
|
39
|
+
projectId: string
|
|
40
|
+
codeArtifactId: string
|
|
41
|
+
status: string
|
|
42
|
+
createdTime: string
|
|
43
|
+
startedTime: string
|
|
44
|
+
completedTime: string
|
|
45
|
+
language: string
|
|
46
|
+
label: string
|
|
47
|
+
errorMessage: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ScanResultsInstances {
|
|
51
|
+
content: ResultContent[]
|
|
52
|
+
}
|