@contrast/contrast 1.0.0

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 (88) hide show
  1. package/README.md +109 -0
  2. package/bin/contrast.js +2 -0
  3. package/dist/commands/auth/auth.js +61 -0
  4. package/dist/commands/config/config.js +24 -0
  5. package/dist/commands/scan/processScan.js +23 -0
  6. package/dist/common/HTTPClient.js +192 -0
  7. package/dist/common/errorHandling.js +60 -0
  8. package/dist/constants/constants.js +30 -0
  9. package/dist/constants/lambda.js +31 -0
  10. package/dist/constants/locales.js +259 -0
  11. package/dist/constants.js +150 -0
  12. package/dist/index.js +56 -0
  13. package/dist/lambda/__mocks__/aws.js +21 -0
  14. package/dist/lambda/__mocks__/lambdaConfig.json +42 -0
  15. package/dist/lambda/arn.js +21 -0
  16. package/dist/lambda/aws.js +169 -0
  17. package/dist/lambda/cliError.js +76 -0
  18. package/dist/lambda/constants.js +11 -0
  19. package/dist/lambda/help.js +75 -0
  20. package/dist/lambda/lambda.js +130 -0
  21. package/dist/lambda/logUtils.js +36 -0
  22. package/dist/lambda/scanDetail.js +30 -0
  23. package/dist/lambda/scanDetailCompletion.js +56 -0
  24. package/dist/lambda/scanRequest.js +93 -0
  25. package/dist/lambda/scanResults.js +16 -0
  26. package/dist/lambda/utils.js +90 -0
  27. package/dist/scan/autoDetection.js +76 -0
  28. package/dist/scan/fileFinder.js +15 -0
  29. package/dist/scan/fileUtils.js +31 -0
  30. package/dist/scan/help.js +68 -0
  31. package/dist/scan/populateProjectIdAndProjectName.js +55 -0
  32. package/dist/scan/scan.js +96 -0
  33. package/dist/scan/scanController.js +54 -0
  34. package/dist/scan/scanResults.js +85 -0
  35. package/dist/utils/commonApi.js +45 -0
  36. package/dist/utils/filterProjectPath.js +20 -0
  37. package/dist/utils/getConfig.js +30 -0
  38. package/dist/utils/oraWrapper.js +20 -0
  39. package/dist/utils/paramsUtil/commandlineParams.js +31 -0
  40. package/dist/utils/paramsUtil/configStoreParams.js +18 -0
  41. package/dist/utils/paramsUtil/envVariableParams.js +10 -0
  42. package/dist/utils/paramsUtil/paramHandler.js +28 -0
  43. package/dist/utils/paramsUtil/yamlParams.js +6 -0
  44. package/dist/utils/parsedCLIOptions.js +13 -0
  45. package/dist/utils/requestUtils.js +18 -0
  46. package/dist/utils/validationCheck.js +26 -0
  47. package/package.json +123 -0
  48. package/src/commands/auth/auth.js +73 -0
  49. package/src/commands/config/config.js +25 -0
  50. package/src/commands/scan/processScan.js +29 -0
  51. package/src/common/HTTPClient.js +269 -0
  52. package/src/common/errorHandling.ts +79 -0
  53. package/src/constants/constants.js +34 -0
  54. package/src/constants/lambda.js +41 -0
  55. package/src/constants/locales.js +381 -0
  56. package/src/constants.js +168 -0
  57. package/src/index.ts +69 -0
  58. package/src/lambda/__mocks__/aws.ts +32 -0
  59. package/src/lambda/__mocks__/lambdaConfig.json +42 -0
  60. package/src/lambda/arn.ts +32 -0
  61. package/src/lambda/aws.ts +247 -0
  62. package/src/lambda/cliError.ts +72 -0
  63. package/src/lambda/constants.ts +11 -0
  64. package/src/lambda/help.ts +76 -0
  65. package/src/lambda/lambda.ts +174 -0
  66. package/src/lambda/logUtils.ts +46 -0
  67. package/src/lambda/scanDetailCompletion.ts +78 -0
  68. package/src/lambda/scanRequest.ts +142 -0
  69. package/src/lambda/scanResults.ts +29 -0
  70. package/src/lambda/utils.ts +125 -0
  71. package/src/scan/autoDetection.js +77 -0
  72. package/src/scan/fileUtils.js +33 -0
  73. package/src/scan/help.js +74 -0
  74. package/src/scan/populateProjectIdAndProjectName.js +62 -0
  75. package/src/scan/scan.js +126 -0
  76. package/src/scan/scanController.js +69 -0
  77. package/src/scan/scanResults.js +96 -0
  78. package/src/utils/commonApi.js +54 -0
  79. package/src/utils/filterProjectPath.js +21 -0
  80. package/src/utils/getConfig.ts +42 -0
  81. package/src/utils/oraWrapper.js +24 -0
  82. package/src/utils/paramsUtil/commandlineParams.js +37 -0
  83. package/src/utils/paramsUtil/configStoreParams.js +19 -0
  84. package/src/utils/paramsUtil/envVariableParams.js +10 -0
  85. package/src/utils/paramsUtil/paramHandler.js +28 -0
  86. package/src/utils/parsedCLIOptions.js +17 -0
  87. package/src/utils/requestUtils.js +22 -0
  88. package/src/utils/validationCheck.js +34 -0
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ const { lambda } = require('./lambda');
3
+ const en_locales = () => {
4
+ return {
5
+ successHeader: 'SUCCESS',
6
+ snapshotSuccessMessage: ' Please go to the Contrast UI to view your dependency tree.',
7
+ snapshotFailureHeader: 'FAIL',
8
+ snapshotFailureMessage: ' Unable to send library analysis to your Contrast UI.',
9
+ snapshotHostMessage: " No host supplied. Using default host 'app.contrastsecurity.com'. Please ensure this is correct.",
10
+ vulnerabilitiesSuccessMessage: ' Vulnerability data successfully retrieved',
11
+ vulnerabilitiesFailureMessage: ' Unable to retrieve library vulnerabilities from Team Server.',
12
+ reportSuccessMessage: ' Report successfully retrieved',
13
+ reportFailureMessage: ' Unable to generate library report.',
14
+ catchErrorMessage: 'Contrast UI error: ',
15
+ dependenciesNote: 'Please Note: We currently only support projects with one .csproj AND *.package.lock.json',
16
+ languageAnalysisFailureMessage: 'LANGUAGE ANALYSIS FAILED',
17
+ languageAnalysisFactoryFailureHeader: 'FAIL',
18
+ projectPathParameter: 'Please set the %s to locate the source code for the project',
19
+ apiKeyParameter: 'Please set the %s to connect to the Contrast UI',
20
+ applicationNameParameter: 'Please provide a value for %s, to appear in the Contrast UI',
21
+ languageParameter: 'Please set the %s to the language of the source project. Allowable values are JAVA, DOTNET, NODE, PYTHON and RUBY.',
22
+ hostParameter: 'Please set the %s to the hostname and (optionally) the port expressed as <host>:<port> of the Contrast UI',
23
+ organizationIdParameter: 'Please set the %s to correctly identify your organization within the Contrast UI',
24
+ authorizationParameter: 'Please set the %s to your authorization header, found in the Contrast UI',
25
+ applicationIdParameter: 'Please set the %s to the value provided within the Contrast UI for the target application',
26
+ libraryAnalysisError: 'Please ensure the language parameter is set in accordance to the language specified on the project path.\nThe Contrast-CLI must be run in the same directory as the project manifest file OR the project_path parameter must be used to identify the directory containing the project manifest file.\n\nFor further information please read our usage guide, which can be accessed with the following command:\n\ncontrast-cli --help',
27
+ yamlMissingParametersHeader: 'Missing Parameters',
28
+ yamlMissingParametersMessage: 'The following parameters are required: \n \norganization_id \napi_key \nauthorization \nhost \napplication_name or application_id \nlanguage \n \nThey must be specified as a command line argument or within the yaml file. \nFor further information please read our usage guide, which can be accessed with the following command:\ncontrast-cli --help',
29
+ unauthenticatedErrorHeader: '401 error - Unauthenticated',
30
+ unauthenticatedErrorMessage: 'Please check the following keys are correct:\n--organization_id, --api_key or --authorization',
31
+ badRequestErrorHeader: '400 error - Bad Request',
32
+ badRequestErrorMessage: 'Please check the following key is correct: \n--application_id',
33
+ badRequestCatalogueErrorMessage: 'The application name already exists, please use a unique name',
34
+ forbiddenRequestErrorHeader: '403 error - Forbidden',
35
+ forbiddenRequestErrorMessage: 'You do not have permission to access this server.',
36
+ proxyErrorHeader: '407 error - Proxy Authentication Required',
37
+ proxyErrorMessage: 'Please provide valid authentication credentials for the proxy server.',
38
+ downgradeHttpsHttp: 'Connection to ContrastUI using https failed. Attempting to connect using http...',
39
+ setSpecifiedParameter: 'Please set the %s ',
40
+ catalogueFailureCommand: 'Failed to catalogue a new application for reason: ',
41
+ catalogueFailureHostCommand: 'Failed to catalogue a new application, please ensure you have the correct host and authentication. Error: ',
42
+ catalogueSuccessCommand: 'This application ID can now be used to send dependency data to Contrast: ',
43
+ dotnetAnalysisFailure: '.NET analysis failed because: ',
44
+ dotnetReadLockfile: 'Failed to read the lock file @ %s because: ',
45
+ dotnetParseLockfile: "Failed to parse .NET lock file @ '%s' because: ",
46
+ dotnetParseProjectFile: "Failed to parse MSBuild project file @ '%s' because: ",
47
+ dotnetReadProjectFile: 'Failed to read the project file @ "%s" because: ',
48
+ javaAnalysisError: 'JAVA analysis failed because: ',
49
+ javaParseProjectFile: 'Failed to parse mvn output because: ',
50
+ languageAnalysisMultipleLanguages1: 'Identified multiple languages for the project\n',
51
+ languageAnalysisMultipleLanguages2: 'Please specify which project file you would like analyzed with the %s CLI option.',
52
+ languageAnalysisProjectFiles: "Identified project language as '%s' but found multiple project files: %s. Please specify which project file you would like analyzed with the %s CLI option.",
53
+ languageAnalysisHasNoLockFile: "Identified project language as '%s' but no project lock file was found.",
54
+ languageAnalysisHasMultipleLockFiles: "Identified project language as '%s' but multiple project lock files were found: %s \n",
55
+ languageAnalysisProjectFileError: "Identified project language as '%s' but no project file was found.",
56
+ languageAnalysisProjectRootFileNameReadError: 'Failed to read the contents of the directory @ %s because: ',
57
+ languageAnalysisProjectRootFileNameMissingError: "%s isn't a file or directory",
58
+ languageAnalysisProjectRootFileNameFailure: 'Failed to get information about the file or directory @ %s because: ',
59
+ languageAnalysisFailure: ' analysis failed because: ',
60
+ languageAnalysisNoLanguage: 'No language detected in project path @ %s',
61
+ NodeAnalysisFailure: 'NODE analysis failed because: ',
62
+ phpAnalysisFailure: 'PHP analysis failed because: ',
63
+ NodeParseNPM: "Failed to parse NODE package-lock.json file @ '%s' because: ",
64
+ phpParseComposerLock: "Failed to parse PHP composer.lock file @ '%s' because: ",
65
+ NodeReadNpmError: 'Failed to read the package-lock.json file @ "%s" because: ',
66
+ phpReadError: 'Failed to read the composer.lock file @ "%s" because: ',
67
+ NodeParseYarn: "Failed to parse Node yarn.lock version 1 @ '%s' because: ",
68
+ NodeParseYarn2: "Failed to parse Node yarn.lock version 2 @ '%s' because: ",
69
+ nodeReadProjectFileError: 'Failed to read the NODE project file @ "%s" because: ',
70
+ phpReadProjectFileError: 'Failed to read the PHP project file @ "%s" because: ',
71
+ nodeReadYarnLockFileError: 'Failed to read the yarn.lock file @ "%s" because: ',
72
+ pythonAnalysisEngineError: 'Python analysis failed because: ',
73
+ pythonAnalysisEnginePipError: "Failed to parse python Pipfile.lock file @ '%s' because: ",
74
+ pythonAnalysisParseProjectFileError: 'Failed to parse python output "%s" because: ',
75
+ pythonAnalysisReadPipFileError: 'Failed to read the python Pipfile.lock file @ "%s" because: ',
76
+ pythonAnalysisReadPythonProjectFileError: 'Failed to read the python pipfile @ "%s" because: ',
77
+ rubyAnalysisEngineError: 'Ruby analysis failed because: ',
78
+ rubyAnalysisEngineParsedGemFileError: 'Failed to parse ruby output "%s" because: ',
79
+ rubyAnalysisEngineParsedGemLockFileError: 'Failed to parse ruby Gemfile.lock output because: ',
80
+ rubyAnalysisEngineReadGemFileError: 'Failed to read the ruby project file @ "%s" because: ',
81
+ rubyAnalysisEngineReadGemLockFileError: 'Failed to read the ruby Gemfile.lock @ "%s" because: ',
82
+ constantsOptional: '(optional)',
83
+ constantsOptionalForCatalogue: '(optional for catalogue)',
84
+ constantsRequired: '(required)',
85
+ constantsRequiredCatalogue: '(required for catalogue)',
86
+ constantsYamlPath: 'If you want to read params from the yaml file then enter the path to the file',
87
+ constantsApiKey: 'An agent API key as provided by Contrast UI',
88
+ constantsAuthorization: 'An agent Authorization credentials as provided by Contrast UI',
89
+ constantsOrganizationId: 'The ID of your organization in Contrast UI',
90
+ constantsApplicationId: 'The ID of the application cataloged by Contrast UI',
91
+ constantsHostId: 'Provide the name of the host and optionally the port expressed as "<host>:<port>".',
92
+ constantsApplicationName: 'The name of the application cataloged by Contrast UI',
93
+ constantsCatalogueApplication: 'Provide this if you want to catalogue an application',
94
+ constantsLanguage: 'Valid values are JAVA, DOTNET, NODE, PYTHON and RUBY. If there are multiple project configuration files in the project_path, language is also required. Also, provide this when cataloguing an application',
95
+ constantsProjectPath: 'The directory root of a project/application that you would like analyzed. Defaults to current directory.',
96
+ constantsSilent: 'Silences JSON output.',
97
+ constantsAppGroups: 'Assign your application to one or more pre-existing groups when using the catalogue command. Group lists should be comma separated.',
98
+ constantsVersion: 'Displays CLI Version you are currently on.',
99
+ constantsProxyServer: 'Allows for connection via a proxy server. If authentication is required please provide the username and password with the protocol, host and port. For instance: "http://username:password@<host>:<port>".',
100
+ constantsHelp: 'Display this usage guide.',
101
+ constantsGradleMultiProject: 'Specify the sub project within your gradle application.',
102
+ constantsScan: 'Upload java binaries to the static scan service',
103
+ constantsWaitForScan: 'Waits for the result of the scan',
104
+ constantsProjectName: 'The name of the scan project in Contrast',
105
+ constantsFileName: 'The name of the file to Scan',
106
+ constantsProjectId: 'The ID associated with a scan project. Replace <ProjectID> with the ID for the scan project. To find the ID, select a scan project in Contrast and locate the last number in the URL.',
107
+ constantsScanTimeout: 'Set a specific time span before the function times out. Default timeout is 300 seconds if scan_timeout is not set. The format of the value of the parameter is "20" seconds or "80" seconds.',
108
+ constantsReport: 'Display vulnerability information for this application',
109
+ constantsFail: 'Set the process to fail if this option is set in combination with the --report and --cve_severity.',
110
+ failOptionErrorMessage: " FAIL - CVE's have been detected that match at least the cve_severity or cve_threshold option specified.",
111
+ constantsSeverity: '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.',
112
+ constantsCount: "The number of CVE's that must be exceeded to fail a build",
113
+ constantsHeader: 'Contrast CLI',
114
+ constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
115
+ constantsContrastContent: 'Use the Contrast CLI, the fastest and most accurate code scan, to help find and eliminate security bugs in your code.',
116
+ constantsUsageGuideContentRecommendation: '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.',
117
+ constantsPrerequisitesHeader: 'Pre-requisites',
118
+ constantsPrerequisitesContent: 'To scan a Java project you will need a .jar or .war file for analysis\n' +
119
+ 'To scan a Javascript project you will need a .js or.zip file for analysis\n',
120
+ constantsUsage: 'Usage',
121
+ constantsUsageCommandExample: 'contrast [command] [options]',
122
+ constantsUsageCommandInfo: 'The file argument is optional. If no file is given, Contrast will search for a .jar, .war, .js or .zip file in the working directory.\n',
123
+ constantsUsageCommandInfo24Hours: 'Submitted files are encrypted during upload and deleted in 24 hours.',
124
+ constantsAnd: 'AND',
125
+ constantsJava: 'AND Maven build platform, including the dependency plugin. For a Gradle project, use build.gradle. A gradle-wrapper.properties file is also required. Kotlin is also supported requiring a build.gradle.kts file.',
126
+ constantsJavaNote: '*Please Note: Running "mvn dependency:tree" or "./gradlew dependencies" in the project directory locally must be successful.',
127
+ constantsJavaNoteGradle: 'We currently support v4.8 and upwards on Gradle projects',
128
+ constantsDotNet: 'MSBuild 15.0 or greater and have a packages.lock.json file are supported.',
129
+ constantsDotNetNote: 'Please Note: If the packages.lock.json file is not in place it can be generated by setting RestorePackagesWithLockFile to true within each *.csproj and running dotnet build',
130
+ constantsNode: '%s AND a lock file either %s or %s',
131
+ constantsRuby: 'gemfile AND gemfile.lock',
132
+ constantsPython: 'pipfile AND pipfile.lock',
133
+ constantsHowToRunHeader: 'How to run:',
134
+ constantsHowToRunDev1: 'Begin with contrast auth to authenticate the CLI to perform actions',
135
+ constantsHowToRunDev2: 'After successful auth try the following command: contrast scan -f "<file>"',
136
+ constantsHowToRunDev3: 'Allowable languages are java (.jar and .war) and javascript (.js or .zip), if the language is not autodetected please use --language to specify',
137
+ constantsHowToRunContent1: 'You can run the tool on the command line and manually add the parameters, or you can put the parameters in a YAML file.',
138
+ constantsHowToRunContent2: 'If you are assessing an application that has not been instrumented by a Contrast agent you must first use the tool to register the application (Catalogue command). This will give you an application ID that you can then use in the Run Command.',
139
+ constantsHowToRunContent3: 'Allowable language values are JAVA, NODE, PYTHON, RUBY and GO.',
140
+ constantsManualInputHeader: 'Manual Input of Command:',
141
+ constantsManualInputCatalogue: 'Catalogue Command:',
142
+ constantsManualInputCatalogueInstruction: 'To analyse a new application not already instrumented by Contrast, run the following command:',
143
+ constantsManualInputCatalogueRun: 'After you run this command, you are provided a new application ID in the console. Use this ID in the Run command:',
144
+ constantsManualInputCatalogueRunTitle: 'Run Command:',
145
+ constantsManualInputCatalogueRunInstruction: 'To analyse an application catalogued by Contrast, run the following command:',
146
+ constantsYaml: 'Yaml:',
147
+ constantsYamlRunCommand: 'After you catalogue your application go to Run Command above.',
148
+ constantsOptions: 'Options',
149
+ constantsCatalogueCommand: '%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationName %s YourApplicationLanguage',
150
+ constantsRunCommand: '%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationId',
151
+ constantsSpecialCharacterWarning: 'Please Note: Parameters may need to be quoted to avoid issues with special characters.',
152
+ yamlCatalogueCommand: '%s PathToYaml',
153
+ yamlCommand: '%s PathToYaml',
154
+ agentProxyAndTlsEnabledError: 'Please Note: We currently do not support having a proxy server and TLS enabled at the same time.',
155
+ TlsHeader: 'TLS',
156
+ TlsBody: 'To enable TLS please use the YAML file with the following parameters:',
157
+ TlsKey: 'key: pathToKey',
158
+ TlsCert: 'cert: pathToCert',
159
+ TlsCaCert: 'cacert: pathToCaCert',
160
+ goReadProjectFile: 'Failed to read the project file @ "%s" because: "%s"',
161
+ goAnalysisError: 'GO analysis failed because: ',
162
+ goParseProjectFile: 'Failed to parse go mod graph output because: ',
163
+ mavenNotInstalledError: " 'mvn' is not available. Please ensure you have Maven installed and available on your path.",
164
+ mavenDependencyTreeNonZero: 'Building maven dependancy tree failed with a non 0 exit code',
165
+ gradleWrapperUnavailable: ' Gradle wrapper not found in root of project. Please ensure gradlew or gradlew.bat is in root of the project.',
166
+ gradleDependencyTreeNonZero: "Building gradle dependancy tree failed with a non 0 exit code. \n Please check you have the correct version of Java installed to compile your project? \n If running against a muti module project ensure you are using the '--sub-project' flag",
167
+ yamlPathCamelCaseError: ' Warning: The "yamlPath" parameter will be deprecated in a future release. Please look at our documentation for further guidance.',
168
+ constantsSbom: ' Generate the Software Bill of Materials (SBOM) for the given application',
169
+ constantsMetadata: 'Define a set of key=value pairs (which conforms to RFC 2253) for specifying user-defined metadata associated with the application.',
170
+ constantsTags: 'Apply labels to an application. Labels must be formatted as a comma-delimited list. Example - label1,label2,label3',
171
+ constantsCode: 'Add the application code this application should use in the Contrast UI',
172
+ constantsIgnoreCertErrors: ' For EOP users with a local Teamserver install, this will bypass the SSL certificate and recognise a self signed certificate.',
173
+ constantsIgnoreDev: 'Combined with the --report command excludes developer dependencies from the vulnerabilities report. By default all dependencies are included in a report.',
174
+ constantsCommands: 'Commands',
175
+ constantsScanOptions: 'Scan Options',
176
+ sbomError: 'All required parameters are not present.',
177
+ sbomRetrievalError: 'Unable to retrieve Software Bill of Materials (SBOM)',
178
+ ignoreDevDep: 'No private libraries that are not scoped detected',
179
+ foundExistingProjectScan: 'Found existing project...',
180
+ projectCreatedScan: 'Project created',
181
+ uploadingScan: 'Uploading...',
182
+ uploadingScanSuccessful: 'Uploaded file successfully.',
183
+ uploadingScanFail: 'Unable to upload the file.',
184
+ waitingTimedOut: 'Timed out.',
185
+ responseMessage: 'Response: %s',
186
+ searchingDirectoryScan: 'Searched 3 directory levels & found: ',
187
+ noFileFoundScan: "We could't find a suitable file in your directories (we go 3 deep)",
188
+ specifyFileScanError: '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>"',
189
+ populateProjectIdMessage: 'project ID is %s',
190
+ scanErrorFileMessage: 'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
191
+ helpAuthSummary: 'Authenticate Contrast using your Github or Google account',
192
+ helpScanSummary: 'Searches for a .jar, .war, .js or .zip file in the working directory, uploads for analysis and returns the results',
193
+ helpLambdaSummary: 'Perform scan on AWS Lambda functions',
194
+ helpVersionSummary: 'Displays version of Contrast CLI',
195
+ helpConfigSummary: 'Displays stored credentials',
196
+ helpSummary: 'Displays usage guide',
197
+ authName: 'auth',
198
+ scanName: 'scan',
199
+ lambdaName: 'lambda',
200
+ versionName: 'version',
201
+ configName: 'config',
202
+ helpName: 'help',
203
+ scanOptionsFileName: '-f, --file',
204
+ scanOptionsLanguage: '-l, --language',
205
+ scanOptionsName: '-n, --name',
206
+ scanOptionsTimeout: '-t, --time-out',
207
+ scanOptionsVerbose: '-v, --verbose',
208
+ scanOptionsFileNameSummary: 'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .js. or .zip file in the working directory.',
209
+ scanOptionsLanguageSummaryOptional: 'Language of file to send for analysis. ',
210
+ scanOptionsLanguageSummaryRequired: 'If you scan a .zip file or you use the --file option.',
211
+ scanOptionsNameSummary: 'Contrast project name. If not specified, Contrast uses contrast.settings to identify the project or creates a project.',
212
+ scanOptionsTimeoutSummary: 'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
213
+ scanOptionsVerboseSummary: 'Returns extended information to the terminal.',
214
+ authSuccessMessage: 'Authentication successful',
215
+ runScanMessage: 'Now run Contrast Scan',
216
+ authWaitingMessage: 'Waiting for auth...',
217
+ authTimedOutMessage: 'Auth Timed out, try again',
218
+ zipErrorScan: 'We only support zip files for JAVASCRIPT language, please set the flag --language JAVASCRIPT',
219
+ unknownFileErrorScan: 'Unsupported file selected for Scan.',
220
+ foundScanFile: 'found: %s',
221
+ foundVulnerabilities: 'Found %s vulnerabilities',
222
+ foundDetailedVulnerabilities: '%s Critical %s High %s Medium %s Low %s Note',
223
+ requiredParams: 'All required parameters are not present.',
224
+ timeoutScan: 'Timeout set to 5 minutes.',
225
+ searchingScanFileDirectory: 'Searching for file to scan from %s...',
226
+ scanHeader: 'Contrast Scan CLI',
227
+ lambdaHeader: 'Contrast lambda help',
228
+ lambdaSummary: 'Performs static security scan on an AWS Lambda Function.\nProduces CVE (Vulnerable Dependencies) and Least Privilege violations/remediation results.',
229
+ lambdaUsage: 'contrast lambda --function-name <function> [options]',
230
+ lambdaPrerequisitesContent: 'contrast cli',
231
+ scanFileNameOption: ' -f, --file',
232
+ lambdaFunctionNameOption: ' -f, --function-name',
233
+ lambdaEndpointOption: '-e, --endpoint-url',
234
+ lambdaRegionOption: '-r, --region',
235
+ lambdaProfileOption: '-p, --profile',
236
+ lambdaJsonOption: '-j, --json-output',
237
+ lambdaVerboseOption: '-v, --verbose',
238
+ lambdaHelpOption: '-h, --help',
239
+ lambdaFunctionNameSummery: 'Name of AWS lambda function to scan.',
240
+ lambdaEndpointSummery: 'AWS Endpoint override, works like in AWS CLI.',
241
+ lambdaRegionSummery: 'Region override, default to AWS_DEAFAULT_REGION env var, works like in AWS CLI.',
242
+ lambdaProfileSummery: 'AWS configuration profile override, works like in AWS CLI.',
243
+ lambdaJsonSummery: 'Return response in JSON (versus default human readable format).',
244
+ lambdaVerbosSummery: 'Returns extended information to the terminal.',
245
+ configNotFound: 'Configuration details not found. Try authenticating by using ‘contrast auth’.',
246
+ redirectAuth: '\nOpening the authentication page in your web browser.\nSign in and complete the steps.\nReturn here to start using Contrast.\n\nIf your browser has trouble loading, try this:\n%s \n',
247
+ scanZipError: 'A .zip archive can be used for Javascript Scan. Archive found %s does not contain .JS files for Scan.',
248
+ fileNotExist: 'File specified does not exist, please check and try again.',
249
+ fileHasWhiteSpacesError: 'File cannot have spaces, please rename or choose another file to Scan.',
250
+ zipFileException: 'Error reading zip file',
251
+ connectionError: 'An error has occurred when trying to get the Project Id please check your internet connection or provide the Project Id manually',
252
+ internalServerErrorHeader: '500 error - Internal server error',
253
+ resourceLockedErrorHeader: '423 error - Resource is locked',
254
+ ...lambda
255
+ };
256
+ };
257
+ module.exports = {
258
+ en_locales
259
+ };
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ const commandLineUsage = require('command-line-usage');
3
+ const i18n = require('i18n');
4
+ const { en_locales } = require('./constants/locales.js');
5
+ i18n.configure({
6
+ staticCatalog: {
7
+ en: en_locales()
8
+ },
9
+ defaultLocale: 'en'
10
+ });
11
+ const scanOptionDefinitions = [
12
+ {
13
+ name: 'name',
14
+ alias: 'n',
15
+ description: '{bold ' +
16
+ i18n.__('constantsOptional') +
17
+ '}: ' +
18
+ i18n.__('constantsProjectName')
19
+ },
20
+ {
21
+ name: 'file',
22
+ alias: 'f',
23
+ description: '{bold ' +
24
+ i18n.__('constantsOptional') +
25
+ '}: ' +
26
+ i18n.__('constantsFileName')
27
+ },
28
+ {
29
+ name: 'project-id',
30
+ alias: 'p',
31
+ description: '{bold ' +
32
+ i18n.__('constantsOptional') +
33
+ '}: ' +
34
+ i18n.__('constantsProjectId')
35
+ },
36
+ {
37
+ name: 'timeout',
38
+ alias: 't',
39
+ type: Number,
40
+ description: '{bold ' +
41
+ i18n.__('constantsOptional') +
42
+ '}: ' +
43
+ i18n.__('constantsScanTimeout')
44
+ },
45
+ {
46
+ name: 'language',
47
+ alias: 'l',
48
+ description: '{bold ' +
49
+ i18n.__('constantsRequiredCatalogue') +
50
+ '}: ' +
51
+ i18n.__('constantsLanguage')
52
+ },
53
+ {
54
+ name: 'organization-id',
55
+ alias: 'o',
56
+ description: '{bold ' +
57
+ i18n.__('constantsRequired') +
58
+ '}: ' +
59
+ i18n.__('constantsOrganizationId')
60
+ },
61
+ {
62
+ name: 'yaml-path',
63
+ alias: 'y',
64
+ description: '{bold ' +
65
+ i18n.__('constantsOptional') +
66
+ '}: ' +
67
+ i18n.__('constantsYamlPath')
68
+ },
69
+ {
70
+ name: 'api-key',
71
+ description: '{bold ' +
72
+ i18n.__('constantsRequired') +
73
+ '}: ' +
74
+ i18n.__('constantsApiKey')
75
+ },
76
+ {
77
+ name: 'authorization',
78
+ description: '{bold ' +
79
+ i18n.__('constantsRequired') +
80
+ '}: ' +
81
+ i18n.__('constantsAuthorization')
82
+ },
83
+ {
84
+ name: 'host',
85
+ alias: 'h',
86
+ defaultValue: 'app.contrastsecurity.com',
87
+ description: '{bold ' +
88
+ i18n.__('constantsRequired') +
89
+ '}: ' +
90
+ i18n.__('constantsHostId')
91
+ },
92
+ {
93
+ name: 'proxy',
94
+ description: '{bold ' +
95
+ i18n.__('constantsOptional') +
96
+ '}: ' +
97
+ i18n.__('constantsProxyServer')
98
+ },
99
+ {
100
+ name: 'ff',
101
+ type: Boolean,
102
+ description: '{bold ' +
103
+ i18n.__('constantsOptional') +
104
+ '}: ' +
105
+ i18n.__('constantsProxyServer')
106
+ },
107
+ {
108
+ name: 'ignore-cert-errors',
109
+ type: Boolean,
110
+ description: '{bold ' +
111
+ i18n.__('constantsOptional') +
112
+ '}:' +
113
+ i18n.__('constantsIgnoreCertErrors')
114
+ },
115
+ {
116
+ name: 'help',
117
+ type: Boolean
118
+ }
119
+ ];
120
+ const mainUsageGuide = commandLineUsage([
121
+ {
122
+ header: i18n.__('constantsHeader'),
123
+ content: [i18n.__('constantsContrastContent')]
124
+ },
125
+ {
126
+ header: i18n.__('constantsUsage'),
127
+ content: [i18n.__('constantsUsageCommandExample')]
128
+ },
129
+ {
130
+ header: i18n.__('constantsCommands'),
131
+ content: [
132
+ { name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
133
+ { name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
134
+ { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
135
+ { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
136
+ { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
137
+ ]
138
+ },
139
+ {
140
+ content: '{underline https://www.contrastsecurity.com}'
141
+ }
142
+ ]);
143
+ const mainDefinition = [{ name: 'command', defaultOption: true }];
144
+ module.exports = {
145
+ commandLineDefinitions: {
146
+ mainUsageGuide,
147
+ mainDefinition,
148
+ scanOptionDefinitions
149
+ }
150
+ };
package/dist/index.js ADDED
@@ -0,0 +1,56 @@
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 command_line_args_1 = __importDefault(require("command-line-args"));
7
+ const auth_1 = require("./commands/auth/auth");
8
+ const config_1 = require("./commands/config/config");
9
+ const processScan_1 = require("./commands/scan/processScan");
10
+ const constants_1 = __importDefault(require("./constants"));
11
+ const constants_2 = require("./constants/constants");
12
+ const lambda_1 = require("./lambda/lambda");
13
+ const getConfig_1 = require("./utils/getConfig");
14
+ const { commandLineDefinitions: { mainUsageGuide, mainDefinition } } = constants_1.default;
15
+ const config = (0, getConfig_1.localConfig)(constants_2.APP_NAME, constants_2.APP_VERSION);
16
+ const getMainOption = () => {
17
+ const mainOptions = (0, command_line_args_1.default)(mainDefinition, {
18
+ stopAtFirstUnknown: true,
19
+ camelCase: true,
20
+ caseInsensitive: true
21
+ });
22
+ const argv = mainOptions._unknown || [];
23
+ return {
24
+ mainOptions,
25
+ argv
26
+ };
27
+ };
28
+ const start = async () => {
29
+ const { mainOptions, argv: argvMain } = getMainOption();
30
+ const command = mainOptions.command != undefined ? mainOptions.command.toLowerCase() : '';
31
+ if (command === 'version') {
32
+ console.log(constants_2.APP_VERSION);
33
+ return;
34
+ }
35
+ if (command === 'config') {
36
+ return (0, config_1.processConfig)(argvMain, config);
37
+ }
38
+ if (command === 'auth') {
39
+ return await (0, auth_1.processAuth)(config);
40
+ }
41
+ if (command === 'lambda') {
42
+ return await (0, lambda_1.processLambda)(argvMain);
43
+ }
44
+ if (command === 'scan') {
45
+ return await (0, processScan_1.processScan)();
46
+ }
47
+ if (command === 'help' ||
48
+ argvMain.includes('--help') ||
49
+ Object.keys(mainOptions).length === 0) {
50
+ console.log(mainUsageGuide);
51
+ }
52
+ else {
53
+ console.log('Unknown Command: ' + command + ' \nUse --help for the full list');
54
+ }
55
+ };
56
+ start();
@@ -0,0 +1,21 @@
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
+ exports.getLambdaPolicies = exports.getLayersLinks = exports.getLambdaFunctionConfiguration = exports.getLambdaClient = void 0;
7
+ const lambdaConfig_json_1 = __importDefault(require("./lambdaConfig.json"));
8
+ const getLambdaClient = (lambdaOptions) => {
9
+ return {};
10
+ };
11
+ exports.getLambdaClient = getLambdaClient;
12
+ const getLambdaFunctionConfiguration = async (client, lambdaOptions) => {
13
+ return Promise.resolve(lambdaConfig_json_1.default);
14
+ };
15
+ exports.getLambdaFunctionConfiguration = getLambdaFunctionConfiguration;
16
+ const getLayersLinks = async (client, functionConfiguration) => {
17
+ return [];
18
+ };
19
+ exports.getLayersLinks = getLayersLinks;
20
+ const getLambdaPolicies = async (functionConfiguration, lambdaOptions) => [];
21
+ exports.getLambdaPolicies = getLambdaPolicies;
@@ -0,0 +1,42 @@
1
+ {
2
+ "$metadata": {
3
+ "httpStatusCode": 200,
4
+ "requestId": "c1495998-4606-46ba-b4fc-f7d0d165172d",
5
+ "attempts": 1,
6
+ "totalRetryDelay": 0
7
+ },
8
+ "Code": {
9
+ "Location": "https://awslambda-eu-cent-1-tasks.s3.eu-central-1.amazonaws.com/snapshots/123456789012/FunctionLambda-90e7680-c598cb5f-6bc9-4107-9fe7-13c126eb3b9e?versionId=ThxUComOVL.qnyEN9Bmi3xzK1JshuKA3&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEGcaDGV1LWNlbnRyYWwtMSJIMEYCIQDAMKTGQ5WEMHM9H7cZQugjEX8QWvq5zRxtXg%2Fz6m9lmAIhAMst%2F5iQkOPJ%2BNfflPiwD4GQchajTfvbNvVeGlz%2BdFi%2FKokECPD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQAxoMNjgwNjg2NTU5NDM0IgwPQDJYINU9W7Csw4sq3QO52WKm5PvlVEeLrwstuDqPPKxhdK57A6z2foEF0Bp%2Bz%2Fp%2Flei2DzbpqjPDluzljZmzh3kP8QKPwq25Yk59%2BfXnxlSkHYe3GXO6W6VLBkPk81T0C9keVwdMijW1ZV94KN8qBB17kERR3sFIhBWXJRLhXSAdLREAfNLaE%2FgnP1eC1b5MZCBW46lbjmYHhHshgZJEUD2fy%2BRuOB4HijldLkpHKgZfwiD0ICXkvxF5NQT6tUhlQPNN%2BCrC2RQ0NSkmjXiaL2BXaDxaQVhZwMTGzBEyLAonA9bSisObWrVEjJcC4%2Bqz9ce25l2yYf77lEXWymEp9NvFFcUNAt6tt%2FAm2qMixcLxV0Y2NuBUBjIvPnNnTvBop%2FvAC1Rh6033AmWpmkK0tD65wEsTS4XAEtnD%2B%2Bku4r6kzatRJ88Lq9YOTbjs%2BMEccy9YIFp7Rwf2%2Bdw3EKHSqz4aB0R9KYa07NooZ%2Bym1VZWfGLfhFRJwKRLk3qKkY%2Bj4laizIE%2BBgqC7f7%2FYXcFk8RGX8vlX5y%2BMKWhBXoMPqAPG7ruoG1RbjQX8TEJvuG0G8c5x76fRjB2VRlykY78wa7%2B83a8oBqMfojq7hQWByNv%2B13KHVIIqrG87tL%2BtrmS7GAoils0vXf0Mvowqt6RkgY6pAGKzTtWpXiIhFLe5n2CNNDMuT9xCSCpQIWf2M9GcNabj%2FAUHIa81gvZwuHzB6DYpEj2cZ7wO22Ve%2FRLIrzdkBROoRYnT0GFevXUJAoO2WolWU13JS7owlBPTW7aET6o7fHJUhwAxPZPCp1cSaFMO5cDN%2BTOVm7V6P4es6m87S1yozp5SzHx3KblhJJF6krPHX6YCWC%2B%2FAu9tu7PqgiZ3RQTZ26f4A%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220330T153702Z&X-Amz-SignedHeaders=host&X-Amz-Expires=600&X-Amz-Credential=ASIAZ47AUUDFFU2TD45R%2F20220330%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Signature=4f9187001f127561afee310d9a127acacb5064c51688f7cd65f98ccb0a7aaa10",
10
+ "RepositoryType": "S3"
11
+ },
12
+ "Configuration": {
13
+ "Architectures": ["x86_64"],
14
+ "CodeSha256": "KNNSfx0YOrZ+pG3fK0qbGBJv/b8V0/gWFFkFw581i4o=",
15
+ "CodeSize": 39577174,
16
+ "DeadLetterConfig": {
17
+ "TargetArn": "arn:aws:sqs:eu-central-1:123456789012:devlocaleuDeadLetterQ-89016d3"
18
+ },
19
+ "Description": "",
20
+ "Environment": {
21
+ "Variables": {
22
+ "EVENTS_BUCKET": "devlocaleu-cn-events-4h6eig-eu-central-1-1676820",
23
+ "AGENTS_TABLE": "devlocaleu.agent.agents"
24
+ }
25
+ },
26
+ "EphemeralStorage": { "Size": 512 },
27
+ "FunctionArn": "arn:aws:lambda:eu-central-1:123456789012:function:FunctionLambda-90e7680",
28
+ "FunctionName": "FunctionLambda-90e7680",
29
+ "Handler": "com.contrastsecurity.scan.ScanHandler::handleEventDataWithContext",
30
+ "LastModified": "2022-03-28T11:14:56.000+0000",
31
+ "LastUpdateStatus": "Successful",
32
+ "MemorySize": 1024,
33
+ "PackageType": "Zip",
34
+ "RevisionId": "d174710a-23ff-499b-a7ba-61036beabd7a",
35
+ "Role": "arn:aws:iam::123456789012:role/Function_Role",
36
+ "Runtime": "java11",
37
+ "State": "Active",
38
+ "Timeout": 900,
39
+ "TracingConfig": { "Mode": "PassThrough" },
40
+ "Version": "$LATEST"
41
+ }
42
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseARN = void 0;
4
+ const cliError_1 = require("./cliError");
5
+ const constants_1 = require("./constants");
6
+ const ARN_REGEX = /arn:(?<partition>[^:\n]*):(?<service>[^:\n]*):(?<region>[^:\n]*):(?<accountId>[^:\n]*):(?<ignore>(?<resource>[^:/\n]*)[:/])?(?<resourceId>.*)/;
7
+ const parseARN = (arn) => {
8
+ if (!arn) {
9
+ throw new cliError_1.CliError(constants_1.ERRORS.FAILED_TO_START_SCAN, {
10
+ errorCode: 'failedToParseArn'
11
+ });
12
+ }
13
+ const arnMatch = arn.match(ARN_REGEX);
14
+ if (!arnMatch) {
15
+ throw new cliError_1.CliError(constants_1.ERRORS.FAILED_TO_START_SCAN, {
16
+ errorCode: 'failedToParseArn'
17
+ });
18
+ }
19
+ return arnMatch.groups;
20
+ };
21
+ exports.parseARN = parseARN;