@contrast/contrast 1.0.6 → 1.0.7
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 +0 -6
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +2 -0
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +10 -1
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +6 -9
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
- package/dist/commands/audit/processAudit.js +1 -1
- package/dist/commands/scan/sca/scaAnalysis.js +13 -2
- package/dist/common/HTTPClient.js +50 -15
- package/dist/common/errorHandling.js +6 -1
- package/dist/common/versionChecker.js +1 -1
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +3 -1
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +35 -4
- package/dist/lambda/types.js +13 -0
- package/dist/scaAnalysis/common/formatMessage.js +17 -1
- package/dist/scaAnalysis/java/analysis.js +3 -6
- package/dist/scaAnalysis/java/index.js +2 -2
- package/dist/scaAnalysis/python/analysis.js +41 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +226 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +6 -2
- package/dist/scan/fileUtils.js +14 -7
- package/dist/scan/formatScanOutput.js +9 -11
- package/dist/scan/models/groupedResultsModel.js +1 -1
- package/dist/scan/models/scanResultsModel.js +3 -1
- package/dist/scan/populateProjectIdAndProjectName.js +2 -1
- package/dist/scan/scan.js +1 -0
- package/dist/scan/scanConfig.js +6 -1
- package/dist/scan/scanController.js +16 -3
- package/dist/scan/scanResults.js +5 -1
- package/dist/utils/commonApi.js +4 -1
- package/package.json +11 -7
- package/src/audit/catalogueApplication/catalogueApplication.js +0 -1
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +8 -0
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +10 -9
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +34 -29
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +15 -11
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +6 -1
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +43 -27
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
- package/src/commands/audit/processAudit.ts +1 -1
- package/src/commands/scan/sca/scaAnalysis.js +13 -5
- package/src/common/HTTPClient.js +65 -25
- package/src/common/errorHandling.ts +10 -1
- package/src/common/versionChecker.ts +1 -1
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +3 -1
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +37 -17
- package/src/lambda/types.ts +35 -0
- package/src/lambda/utils.ts +2 -7
- package/src/scaAnalysis/common/formatMessage.js +19 -1
- package/src/scaAnalysis/go/goAnalysis.js +2 -3
- package/src/scaAnalysis/java/analysis.js +5 -6
- package/src/scaAnalysis/java/index.js +2 -2
- package/src/scaAnalysis/python/analysis.js +48 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +282 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +9 -5
- package/src/scan/fileUtils.js +15 -7
- package/src/scan/formatScanOutput.ts +11 -12
- package/src/scan/models/groupedResultsModel.ts +3 -3
- package/src/scan/models/resultContentModel.ts +1 -1
- package/src/scan/models/scanResultsModel.ts +5 -2
- package/src/scan/populateProjectIdAndProjectName.js +3 -1
- package/src/scan/scan.ts +1 -0
- package/src/scan/scanConfig.js +5 -1
- package/src/scan/scanController.js +18 -4
- package/src/scan/scanResults.js +10 -0
- package/src/utils/commonApi.js +4 -1
package/src/common/HTTPClient.js
CHANGED
|
@@ -22,7 +22,8 @@ function HTTPClient(config) {
|
|
|
22
22
|
Authorization: authToken,
|
|
23
23
|
'API-Key': apiKey,
|
|
24
24
|
SuperAuthorization: superAuthToken,
|
|
25
|
-
'Super-API-Key': superApiKey
|
|
25
|
+
'Super-API-Key': superApiKey,
|
|
26
|
+
'User-Agent': 'contrast-cli-v2'
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -33,7 +34,7 @@ function HTTPClient(config) {
|
|
|
33
34
|
this.maybeAddCertsToRequest(config)
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
HTTPClient.prototype.maybeAddCertsToRequest = function(config) {
|
|
37
|
+
HTTPClient.prototype.maybeAddCertsToRequest = function (config) {
|
|
37
38
|
// cacert
|
|
38
39
|
const caCertFilePath = config.cacert
|
|
39
40
|
if (caCertFilePath) {
|
|
@@ -91,13 +92,30 @@ HTTPClient.prototype.getSpecificScanResult = function getSpecificScanResult(
|
|
|
91
92
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
HTTPClient.prototype.getSpecificScanResultSarif =
|
|
95
|
+
HTTPClient.prototype.getSpecificScanResultSarif =
|
|
96
|
+
function getSpecificScanResultSarif(config, scanId) {
|
|
97
|
+
const options = _.cloneDeep(this.requestOptions)
|
|
98
|
+
options.url = createRawOutputURL(config, scanId)
|
|
99
|
+
return requestUtils.sendRequest({ method: 'get', options })
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
HTTPClient.prototype.createNewEvent = function createNewEvent(
|
|
95
103
|
config,
|
|
96
|
-
scanId
|
|
104
|
+
scanId,
|
|
105
|
+
newProject
|
|
97
106
|
) {
|
|
98
107
|
const options = _.cloneDeep(this.requestOptions)
|
|
99
|
-
options.url =
|
|
100
|
-
|
|
108
|
+
options.url = createEventCollectorURL(config, scanId)
|
|
109
|
+
|
|
110
|
+
options.body = {
|
|
111
|
+
eventSource: process.env.CODESEC_INVOCATION_ENVIRONMENT,
|
|
112
|
+
trackingProperties: {
|
|
113
|
+
projectNameSource: config.projectNameSource,
|
|
114
|
+
waitedForResults: !config.ff,
|
|
115
|
+
newProject
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return requestUtils.sendRequest({ method: 'post', options })
|
|
101
119
|
}
|
|
102
120
|
|
|
103
121
|
HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
|
|
@@ -190,9 +208,6 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
|
|
|
190
208
|
}
|
|
191
209
|
|
|
192
210
|
HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
193
|
-
if (config.language.toUpperCase() === 'RUBY') {
|
|
194
|
-
//console.log('sendSnapshot requestBody', requestBody.snapshot.ruby)
|
|
195
|
-
}
|
|
196
211
|
const options = _.cloneDeep(this.requestOptions)
|
|
197
212
|
let url = createSnapshotURL(config)
|
|
198
213
|
options.url = url
|
|
@@ -210,17 +225,24 @@ HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
|
210
225
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
211
226
|
}
|
|
212
227
|
|
|
213
|
-
HTTPClient.prototype.
|
|
228
|
+
HTTPClient.prototype.getReportStatusById = function getReportStatusById(
|
|
214
229
|
config,
|
|
215
|
-
|
|
230
|
+
snapshotId
|
|
216
231
|
) {
|
|
217
232
|
const options = _.cloneDeep(this.requestOptions)
|
|
218
|
-
options.url =
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return requestUtils.sendRequest({ method: 'put', options })
|
|
233
|
+
options.url = createSpecificReportStatusURL(config, snapshotId)
|
|
234
|
+
return requestUtils.sendRequest({ method: 'get', options })
|
|
222
235
|
}
|
|
223
236
|
|
|
237
|
+
HTTPClient.prototype.getLibraryVulnerabilities =
|
|
238
|
+
function getLibraryVulnerabilities(config, requestBody) {
|
|
239
|
+
const options = _.cloneDeep(this.requestOptions)
|
|
240
|
+
options.url = createLibraryVulnerabilitiesUrl(config)
|
|
241
|
+
options.body = requestBody
|
|
242
|
+
|
|
243
|
+
return requestUtils.sendRequest({ method: 'put', options })
|
|
244
|
+
}
|
|
245
|
+
|
|
224
246
|
HTTPClient.prototype.getAppId = function getAppId(config) {
|
|
225
247
|
const options = _.cloneDeep(this.requestOptions)
|
|
226
248
|
let url = createAppNameUrl(config)
|
|
@@ -295,17 +317,13 @@ HTTPClient.prototype.getScanResources = async function getScanResources(
|
|
|
295
317
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
296
318
|
}
|
|
297
319
|
|
|
298
|
-
HTTPClient.prototype.getFunctionScanResults =
|
|
299
|
-
config,
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
functionArn
|
|
303
|
-
) {
|
|
304
|
-
const url = createScanResultsGetUrl(config, params, scanId, functionArn)
|
|
305
|
-
const options = { ...this.requestOptions, url }
|
|
320
|
+
HTTPClient.prototype.getFunctionScanResults =
|
|
321
|
+
async function getFunctionScanResults(config, params, scanId, functionArn) {
|
|
322
|
+
const url = createScanResultsGetUrl(config, params, scanId, functionArn)
|
|
323
|
+
const options = { ...this.requestOptions, url }
|
|
306
324
|
|
|
307
|
-
|
|
308
|
-
}
|
|
325
|
+
return requestUtils.sendRequest({ method: 'get', options })
|
|
326
|
+
}
|
|
309
327
|
|
|
310
328
|
HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
|
|
311
329
|
const options = _.cloneDeep(this.requestOptions)
|
|
@@ -321,6 +339,20 @@ HTTPClient.prototype.getSbom = function getSbom(config) {
|
|
|
321
339
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
322
340
|
}
|
|
323
341
|
|
|
342
|
+
// analytics
|
|
343
|
+
|
|
344
|
+
HTTPClient.prototype.postAnalyticsFunction = function (config, provider, body) {
|
|
345
|
+
const url = createAnalyticsFunctionPostUrl(config, provider)
|
|
346
|
+
const options = { ...this.requestOptions, body, url }
|
|
347
|
+
|
|
348
|
+
return requestUtils.sendRequest({ method: 'post', options })
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const createAnalyticsFunctionPostUrl = (config, provider) => {
|
|
352
|
+
const url = getServerlessHost(config)
|
|
353
|
+
return `${url}/organizations/${config.organizationId}/providers/${provider}/analytics`
|
|
354
|
+
}
|
|
355
|
+
|
|
324
356
|
// scan
|
|
325
357
|
const createGetScanIdURL = config => {
|
|
326
358
|
return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`
|
|
@@ -350,6 +382,10 @@ function createScanProjectUrl(config) {
|
|
|
350
382
|
return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}`
|
|
351
383
|
}
|
|
352
384
|
|
|
385
|
+
const createEventCollectorURL = (config, scanId) => {
|
|
386
|
+
return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/events`
|
|
387
|
+
}
|
|
388
|
+
|
|
353
389
|
const createGlobalPropertiesUrl = protocol => {
|
|
354
390
|
return `${protocol}/Contrast/api/ng/global/properties`
|
|
355
391
|
}
|
|
@@ -384,6 +420,10 @@ function createSpecificReportWithProdUrl(config, reportId) {
|
|
|
384
420
|
)
|
|
385
421
|
}
|
|
386
422
|
|
|
423
|
+
function createSpecificReportStatusURL(config, reportId) {
|
|
424
|
+
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots/${reportId}/status`
|
|
425
|
+
}
|
|
426
|
+
|
|
387
427
|
function createDataUrl() {
|
|
388
428
|
return `https://ardy.contrastsecurity.com/production`
|
|
389
429
|
}
|
|
@@ -64,6 +64,14 @@ const proxyError = () => {
|
|
|
64
64
|
generalError('proxyErrorHeader', 'proxyErrorMessage')
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
const maxAppError = () => {
|
|
68
|
+
generalError(
|
|
69
|
+
'No applications remaining',
|
|
70
|
+
'You have reached the maximum number of application you can create.'
|
|
71
|
+
)
|
|
72
|
+
process.exit(1)
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
const failOptionError = () => {
|
|
68
76
|
console.log(
|
|
69
77
|
'\n ******************************** ' +
|
|
@@ -140,5 +148,6 @@ export {
|
|
|
140
148
|
findCommandOnError,
|
|
141
149
|
snapshotFailureError,
|
|
142
150
|
vulnerabilitiesFailureError,
|
|
143
|
-
reportFailureError
|
|
151
|
+
reportFailureError,
|
|
152
|
+
maxAppError
|
|
144
153
|
}
|
|
@@ -37,5 +37,5 @@ export async function findLatestCLIVersion(updateMessageHidden: boolean) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export async function isCorrectNodeVersion(currentVersion: string) {
|
|
40
|
-
return semver.satisfies(currentVersion, '>=16
|
|
40
|
+
return semver.satisfies(currentVersion, '>=16')
|
|
41
41
|
}
|
|
@@ -13,7 +13,7 @@ const MEDIUM = 'MEDIUM'
|
|
|
13
13
|
const HIGH = 'HIGH'
|
|
14
14
|
const CRITICAL = 'CRITICAL'
|
|
15
15
|
const APP_NAME = 'contrast'
|
|
16
|
-
const APP_VERSION = '1.0.
|
|
16
|
+
const APP_VERSION = '1.0.7'
|
|
17
17
|
const TIMEOUT = 120000
|
|
18
18
|
const HIGH_COLOUR = '#ff9900'
|
|
19
19
|
const CRITICAL_COLOUR = '#e35858'
|
package/src/constants/locales.js
CHANGED
|
@@ -146,7 +146,7 @@ const en_locales = () => {
|
|
|
146
146
|
constantsHeader: 'CodeSec by Contrast Security',
|
|
147
147
|
constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
|
|
148
148
|
constantsContrastContent:
|
|
149
|
-
|
|
149
|
+
"Use the 'contrast' command for fast and accurate security analysis of your applications and APIs (Java, JavaScript and .NET ) as well as serverless functions (AWS lambda, Java and Python).",
|
|
150
150
|
constantsUsageGuideContentRecommendation:
|
|
151
151
|
'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.',
|
|
152
152
|
constantsPrerequisitesHeader: 'Pre-requisites',
|
|
@@ -356,6 +356,7 @@ const en_locales = () => {
|
|
|
356
356
|
scanZipError:
|
|
357
357
|
'A .zip archive can be used for Javascript Scan. Archive found %s does not contain .JS files for Scan.',
|
|
358
358
|
fileNotExist: 'File specified does not exist, please check and try again.',
|
|
359
|
+
scanFileIsEmpty: 'File specified is empty. Please choose another.',
|
|
359
360
|
fileHasWhiteSpacesError:
|
|
360
361
|
'File cannot have spaces, please rename or choose another file to Scan.',
|
|
361
362
|
zipFileException: 'Error reading zip file',
|
|
@@ -395,6 +396,7 @@ const en_locales = () => {
|
|
|
395
396
|
'saves the output in specified format Txt text, sbom',
|
|
396
397
|
scanNotCompleted:
|
|
397
398
|
'Scan not completed. Check for framework and language support here: %s',
|
|
399
|
+
auditNotCompleted: 'audit not completed. Please try again',
|
|
398
400
|
scanNoVulnerabilitiesFound: '👏 No vulnerabilities found',
|
|
399
401
|
scanNoVulnerabilitiesFoundSecureCode: '👍 Your code looks secure.',
|
|
400
402
|
scanNoVulnerabilitiesFoundGoodWork: '👏 Keep up the good work.',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getHttpClient } from '../utils/commonApi'
|
|
2
|
+
import { getAuth } from '../utils/paramsUtil/paramHandler'
|
|
3
|
+
import { AnalyticsOption } from './types'
|
|
4
|
+
|
|
5
|
+
export const postAnalytics = (data: AnalyticsOption, provider = 'aws') => {
|
|
6
|
+
const config = getAuth()
|
|
7
|
+
const client = getHttpClient(config)
|
|
8
|
+
return client.postAnalyticsFunction(config, provider, data)
|
|
9
|
+
}
|
package/src/lambda/arn.ts
CHANGED
|
@@ -10,7 +10,8 @@ type ARN = {
|
|
|
10
10
|
resourceId?: string
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const ARN_REGEX =
|
|
13
|
+
const ARN_REGEX =
|
|
14
|
+
/arn:(?<partition>[^:\n]*):(?<service>[^:\n]*):(?<region>[^:\n]*):(?<accountId>[^:\n]*):(?<ignore>(?<resource>[^:/\n]*)[:/])?(?<resourceId>.*)/
|
|
14
15
|
|
|
15
16
|
const parseARN = (arn: string | undefined) => {
|
|
16
17
|
if (!arn) {
|
package/src/lambda/lambda.ts
CHANGED
|
@@ -14,18 +14,8 @@ import { printResults } from './utils'
|
|
|
14
14
|
import { getAllLambdas, printAvailableLambdas } from './lambdaUtils'
|
|
15
15
|
import { sleep } from '../utils/requestUtils'
|
|
16
16
|
import ora from '../utils/oraWrapper'
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
functionName?: string
|
|
20
|
-
listFunctions?: boolean
|
|
21
|
-
region?: string
|
|
22
|
-
endpointUrl?: string
|
|
23
|
-
profile?: string
|
|
24
|
-
help?: boolean
|
|
25
|
-
verbose?: boolean
|
|
26
|
-
jsonOutput?: boolean
|
|
27
|
-
_unknown?: string[]
|
|
28
|
-
}
|
|
17
|
+
import { postAnalytics } from './analytics'
|
|
18
|
+
import { LambdaOptions, AnalyticsOption, StatusType, EventType } from './types'
|
|
29
19
|
|
|
30
20
|
type ApiParams = {
|
|
31
21
|
organizationId: string
|
|
@@ -74,10 +64,20 @@ const getLambdaOptions = (argv: string[]) => {
|
|
|
74
64
|
}
|
|
75
65
|
|
|
76
66
|
const processLambda = async (argv: string[]) => {
|
|
67
|
+
let errorMsg
|
|
68
|
+
let scanInfo: { functionArn: string; scanId: string } | undefined
|
|
69
|
+
const commandSessionId = Date.now().toString(36)
|
|
77
70
|
try {
|
|
78
71
|
const lambdaOptions = getLambdaOptions(argv)
|
|
79
72
|
const { help } = lambdaOptions
|
|
80
|
-
|
|
73
|
+
const startCommandAnalytics: AnalyticsOption = {
|
|
74
|
+
arguments: lambdaOptions,
|
|
75
|
+
sessionId: commandSessionId,
|
|
76
|
+
eventType: EventType.START
|
|
77
|
+
}
|
|
78
|
+
postAnalytics(startCommandAnalytics).catch((error: Error) => {
|
|
79
|
+
/* ignore */
|
|
80
|
+
})
|
|
81
81
|
if (help) {
|
|
82
82
|
return handleLambdaHelp()
|
|
83
83
|
}
|
|
@@ -87,15 +87,33 @@ const processLambda = async (argv: string[]) => {
|
|
|
87
87
|
if (lambdaOptions.listFunctions) {
|
|
88
88
|
await getAvailableFunctions(lambdaOptions)
|
|
89
89
|
} else {
|
|
90
|
-
await actualProcessLambda(lambdaOptions)
|
|
90
|
+
scanInfo = await actualProcessLambda(lambdaOptions)
|
|
91
91
|
}
|
|
92
92
|
} catch (error) {
|
|
93
93
|
if (error instanceof CliError) {
|
|
94
|
-
|
|
94
|
+
errorMsg = error.getErrorMessage()
|
|
95
95
|
} else if (error instanceof Error) {
|
|
96
|
-
|
|
96
|
+
errorMsg = error.message
|
|
97
|
+
}
|
|
98
|
+
} finally {
|
|
99
|
+
const endCommandAnalytics: AnalyticsOption = {
|
|
100
|
+
sessionId: commandSessionId,
|
|
101
|
+
eventType: EventType.END,
|
|
102
|
+
status: errorMsg ? StatusType.FAILED : StatusType.SUCCESS
|
|
103
|
+
}
|
|
104
|
+
if (errorMsg) {
|
|
105
|
+
endCommandAnalytics.errorMsg = errorMsg
|
|
106
|
+
console.error(errorMsg)
|
|
107
|
+
}
|
|
108
|
+
if (scanInfo) {
|
|
109
|
+
endCommandAnalytics.scanFunctionData = scanInfo
|
|
110
|
+
}
|
|
111
|
+
await postAnalytics(endCommandAnalytics).catch((error: Error) => {
|
|
112
|
+
/* ignore */
|
|
113
|
+
})
|
|
114
|
+
if (errorMsg) {
|
|
115
|
+
process.exit(1)
|
|
97
116
|
}
|
|
98
|
-
process.exit(1)
|
|
99
117
|
}
|
|
100
118
|
}
|
|
101
119
|
|
|
@@ -162,6 +180,8 @@ const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
|
|
|
162
180
|
if (results?.length) {
|
|
163
181
|
printResults(results)
|
|
164
182
|
}
|
|
183
|
+
|
|
184
|
+
return { functionArn, scanId }
|
|
165
185
|
}
|
|
166
186
|
|
|
167
187
|
const validateRequiredLambdaParams = (options: LambdaOptions) => {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export enum StatusType {
|
|
2
|
+
FAILED = 'failed',
|
|
3
|
+
SUCCESS = 'success'
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum EventType {
|
|
7
|
+
START = 'start_command_session',
|
|
8
|
+
END = 'end_command_session'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type LambdaOptions = {
|
|
12
|
+
functionName?: string
|
|
13
|
+
listFunctions?: boolean
|
|
14
|
+
region?: string
|
|
15
|
+
endpointUrl?: string
|
|
16
|
+
profile?: string
|
|
17
|
+
help?: boolean
|
|
18
|
+
verbose?: boolean
|
|
19
|
+
jsonOutput?: boolean
|
|
20
|
+
_unknown?: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type ScanFunctionData = {
|
|
24
|
+
functionArn: string
|
|
25
|
+
scanId: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type AnalyticsOption = {
|
|
29
|
+
sessionId: string
|
|
30
|
+
eventType: EventType
|
|
31
|
+
arguments?: LambdaOptions
|
|
32
|
+
scanFunctionData?: ScanFunctionData
|
|
33
|
+
status?: StatusType
|
|
34
|
+
errorMsg?: string
|
|
35
|
+
}
|
package/src/lambda/utils.ts
CHANGED
|
@@ -19,13 +19,8 @@ class PrintVulnerability {
|
|
|
19
19
|
whatHappened: string
|
|
20
20
|
|
|
21
21
|
constructor(index: number, vulnerability: any, group?: any[]) {
|
|
22
|
-
const {
|
|
23
|
-
|
|
24
|
-
title,
|
|
25
|
-
description,
|
|
26
|
-
remediation,
|
|
27
|
-
categoryText
|
|
28
|
-
} = vulnerability
|
|
22
|
+
const { severityText, title, description, remediation, categoryText } =
|
|
23
|
+
vulnerability
|
|
29
24
|
|
|
30
25
|
this.group = group
|
|
31
26
|
this.vulnerability = vulnerability
|
|
@@ -14,7 +14,25 @@ const createGoTSMessage = goTree => {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
const createRubyTSMessage = rubyTree => {
|
|
18
|
+
return {
|
|
19
|
+
ruby: {
|
|
20
|
+
rubyDependencyTrees: rubyTree
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const createPythonTSMessage = pythonTree => {
|
|
26
|
+
return {
|
|
27
|
+
python: {
|
|
28
|
+
pythonDependencyTrees: pythonTree
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
17
33
|
module.exports = {
|
|
18
34
|
createJavaTSMessage,
|
|
19
|
-
createGoTSMessage
|
|
35
|
+
createGoTSMessage,
|
|
36
|
+
createRubyTSMessage,
|
|
37
|
+
createPythonTSMessage
|
|
20
38
|
}
|
|
@@ -5,9 +5,8 @@ const goParseDeps = require('./goParseDeps')
|
|
|
5
5
|
const goAnalysis = (config, languageFiles) => {
|
|
6
6
|
try {
|
|
7
7
|
const rawGoDependencies = goReadDepFile.getGoDependencies(config)
|
|
8
|
-
const parsedGoDependencies =
|
|
9
|
-
rawGoDependencies
|
|
10
|
-
)
|
|
8
|
+
const parsedGoDependencies =
|
|
9
|
+
goParseDeps.parseGoDependencies(rawGoDependencies)
|
|
11
10
|
|
|
12
11
|
return createGoTSMessage(parsedGoDependencies)
|
|
13
12
|
} catch (e) {
|
|
@@ -11,16 +11,15 @@ const determineProjectTypeAndCwd = (files, projectPath) => {
|
|
|
11
11
|
|
|
12
12
|
if (files[0].includes('pom.xml')) {
|
|
13
13
|
projectData.projectType = MAVEN
|
|
14
|
-
projectData.cwd = projectPath
|
|
15
|
-
? projectPath
|
|
16
|
-
: files[0].replace('pom.xml', '')
|
|
17
14
|
} else if (files[0].includes('build.gradle')) {
|
|
18
15
|
projectData.projectType = GRADLE
|
|
19
|
-
projectData.cwd = projectPath
|
|
20
|
-
? projectPath
|
|
21
|
-
: files[0].replace('pom.xml', '')
|
|
22
16
|
}
|
|
23
17
|
|
|
18
|
+
//clean up the path to be a folder not a file
|
|
19
|
+
projectData.cwd = projectPath
|
|
20
|
+
? projectPath.replace('pom.xml', '').replace('build.gradle', '')
|
|
21
|
+
: projectPath
|
|
22
|
+
|
|
24
23
|
return projectData
|
|
25
24
|
}
|
|
26
25
|
|
|
@@ -3,11 +3,11 @@ const { parseBuildDeps } = require('./javaBuildDepsParser')
|
|
|
3
3
|
const { createJavaTSMessage } = require('../common/formatMessage')
|
|
4
4
|
|
|
5
5
|
const javaAnalysis = (config, languageFiles) => {
|
|
6
|
-
languageFiles.
|
|
6
|
+
languageFiles.JAVA.forEach(file => {
|
|
7
7
|
file.replace('build.gradle.kts', 'build.gradle')
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
const javaDeps = buildJavaTree(config, languageFiles.
|
|
10
|
+
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
11
11
|
return createJavaTSMessage(javaDeps)
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const multiReplace = require('string-multiple-replace')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
|
|
4
|
+
const readAndParseProjectFile = projectPath => {
|
|
5
|
+
const filePath = filePathForWindows(projectPath + '/Pipfile')
|
|
6
|
+
const pipFile = fs.readFileSync(filePath, 'utf8')
|
|
7
|
+
|
|
8
|
+
const matcherObj = { '"': '' }
|
|
9
|
+
const sequencer = ['"']
|
|
10
|
+
const parsedPipfile = multiReplace(pipFile, matcherObj, sequencer)
|
|
11
|
+
|
|
12
|
+
const pythonArray = parsedPipfile.split('\n')
|
|
13
|
+
|
|
14
|
+
return pythonArray.filter(element => element !== '' && !element.includes('#'))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const readAndParseLockFile = projectPath => {
|
|
18
|
+
const filePath = filePathForWindows(projectPath + '/Pipfile.lock')
|
|
19
|
+
const lockFile = fs.readFileSync(filePath, 'utf8')
|
|
20
|
+
let parsedPipLock = JSON.parse(lockFile)
|
|
21
|
+
parsedPipLock['defaults'] = parsedPipLock['default']
|
|
22
|
+
return parsedPipLock
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const getPythonDeps = config => {
|
|
26
|
+
try {
|
|
27
|
+
const parseProject = readAndParseProjectFile(config.projectPath)
|
|
28
|
+
const parsePip = readAndParseLockFile(config.projectPath)
|
|
29
|
+
|
|
30
|
+
return { pipfileLock: parseProject, pipfilDependanceies: parsePip }
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.log(err.message.toString())
|
|
33
|
+
process.exit(1)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const filePathForWindows = path => {
|
|
38
|
+
if (process.platform === 'win32') {
|
|
39
|
+
path = path.replace(/\//g, '\\')
|
|
40
|
+
}
|
|
41
|
+
return path
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = {
|
|
45
|
+
getPythonDeps,
|
|
46
|
+
readAndParseProjectFile,
|
|
47
|
+
readAndParseLockFile
|
|
48
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const { createPythonTSMessage } = require('../common/formatMessage')
|
|
2
|
+
const { getPythonDeps } = require('./analysis')
|
|
3
|
+
|
|
4
|
+
const pythonAnalysis = (config, languageFiles) => {
|
|
5
|
+
const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
|
|
6
|
+
return createPythonTSMessage(pythonDeps)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
pythonAnalysis
|
|
11
|
+
}
|