@contrast/contrast 1.0.16 → 1.0.17
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/dist/audit/catalogueApplication/catalogueApplication.js +1 -1
- package/dist/cliConstants.js +6 -1
- package/dist/commands/audit/auditConfig.js +10 -12
- package/dist/commands/audit/auditController.js +12 -16
- package/dist/commands/audit/help.js +24 -26
- package/dist/commands/audit/processAudit.js +16 -22
- package/dist/commands/audit/saveFile.js +3 -9
- package/dist/commands/scan/processScan.js +5 -7
- package/dist/commands/scan/sca/scaAnalysis.js +104 -88
- package/dist/common/commonHelp.js +35 -17
- package/dist/common/errorHandling.js +28 -57
- package/dist/common/versionChecker.js +24 -27
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +6 -3
- package/dist/lambda/help.js +2 -1
- package/dist/lambda/lambda.js +2 -7
- package/dist/scaAnalysis/java/analysis.js +40 -5
- package/dist/scaAnalysis/java/index.js +15 -2
- package/dist/scan/autoDetection.js +12 -3
- package/dist/scan/fileUtils.js +24 -1
- package/dist/scan/help.js +2 -1
- package/dist/scan/saveResults.js +1 -1
- package/dist/utils/commonApi.js +10 -1
- package/dist/utils/generalAPI.js +1 -2
- package/dist/utils/paramsUtil/configStoreParams.js +12 -1
- package/dist/utils/paramsUtil/paramHandler.js +7 -1
- package/dist/utils/saveFile.js +2 -1
- package/package.json +2 -1
- package/src/audit/catalogueApplication/catalogueApplication.js +1 -1
- package/src/cliConstants.js +6 -1
- package/src/commands/audit/auditConfig.js +19 -0
- package/src/commands/audit/{auditController.ts → auditController.js} +17 -12
- package/src/commands/audit/{help.ts → help.js} +10 -7
- package/src/commands/audit/processAudit.js +37 -0
- package/src/commands/audit/{saveFile.ts → saveFile.js} +2 -2
- package/src/commands/scan/processScan.js +4 -10
- package/src/commands/scan/sca/scaAnalysis.js +134 -116
- package/src/common/commonHelp.js +43 -0
- package/src/common/{errorHandling.ts → errorHandling.js} +6 -31
- package/src/common/{versionChecker.ts → versionChecker.js} +15 -10
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +7 -3
- package/src/lambda/help.ts +2 -1
- package/src/lambda/lambda.ts +2 -10
- package/src/scaAnalysis/java/analysis.js +43 -10
- package/src/scaAnalysis/java/index.js +19 -2
- package/src/scan/autoDetection.js +14 -3
- package/src/scan/fileUtils.js +29 -1
- package/src/scan/help.js +2 -1
- package/src/scan/saveResults.js +1 -1
- package/src/utils/commonApi.js +13 -1
- package/src/utils/generalAPI.js +1 -2
- package/src/utils/getConfig.ts +1 -0
- package/src/utils/paramsUtil/configStoreParams.js +14 -1
- package/src/utils/paramsUtil/paramHandler.js +9 -1
- package/src/utils/saveFile.js +2 -1
- package/src/commands/audit/auditConfig.ts +0 -21
- package/src/commands/audit/processAudit.ts +0 -40
- package/src/common/commonHelp.ts +0 -13
package/src/lambda/lambda.ts
CHANGED
|
@@ -17,7 +17,7 @@ import ora from '../utils/oraWrapper'
|
|
|
17
17
|
import { postAnalytics } from './analytics'
|
|
18
18
|
import { LambdaOptions, AnalyticsOption, StatusType, EventType } from './types'
|
|
19
19
|
import { APP_VERSION } from '../constants/constants'
|
|
20
|
-
import
|
|
20
|
+
import { postRunMessage } from '../common/commonHelp'
|
|
21
21
|
|
|
22
22
|
type ApiParams = {
|
|
23
23
|
organizationId: string
|
|
@@ -116,7 +116,7 @@ const processLambda = async (argv: string[]) => {
|
|
|
116
116
|
/* ignore */
|
|
117
117
|
})
|
|
118
118
|
|
|
119
|
-
postRunMessage()
|
|
119
|
+
postRunMessage('lambda')
|
|
120
120
|
|
|
121
121
|
if (errorMsg) {
|
|
122
122
|
process.exit(1)
|
|
@@ -225,12 +225,4 @@ const handleLambdaHelp = () => {
|
|
|
225
225
|
process.exit(0)
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
const postRunMessage = () => {
|
|
229
|
-
console.log('\n' + chalk.underline.bold('Other Codesec Features:'))
|
|
230
|
-
console.log("'contrast scan' to run CodeSec’s industry leading SAST scanner")
|
|
231
|
-
console.log(
|
|
232
|
-
"'contrast audit' to find vulnerabilities in your open source dependencies\n"
|
|
233
|
-
)
|
|
234
|
-
}
|
|
235
|
-
|
|
236
228
|
export { processLambda, LambdaOptions, ApiParams, getAvailableFunctions }
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const child_process = require('child_process')
|
|
2
|
+
const spawn = require('cross-spawn')
|
|
2
3
|
const path = require('path')
|
|
3
4
|
const i18n = require('i18n')
|
|
4
5
|
const fs = require('fs')
|
|
6
|
+
const readLine = require('readline')
|
|
7
|
+
const paramHandler = require('../../utils/paramsUtil/paramHandler')
|
|
5
8
|
|
|
6
9
|
const MAVEN = 'maven'
|
|
7
10
|
const GRADLE = 'gradle'
|
|
@@ -29,20 +32,23 @@ const determineProjectTypeAndCwd = (files, config) => {
|
|
|
29
32
|
|
|
30
33
|
const buildMaven = (config, projectData, timeout) => {
|
|
31
34
|
let cmdStdout
|
|
32
|
-
let mvn_settings = ''
|
|
33
|
-
|
|
34
35
|
try {
|
|
35
|
-
|
|
36
|
+
let command = 'mvn'
|
|
37
|
+
let args = ['dependency:tree', '-B']
|
|
36
38
|
if (config.mavenSettingsPath) {
|
|
37
|
-
|
|
39
|
+
args.push('-s')
|
|
40
|
+
args.push(config.mavenSettingsPath)
|
|
38
41
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
// Allow users to provide a custom location for their settings.xml
|
|
43
|
+
|
|
44
|
+
cmdStdout = spawn
|
|
45
|
+
.sync(command, args, {
|
|
46
|
+
env: process.env,
|
|
42
47
|
cwd: projectData.cwd,
|
|
43
48
|
timeout
|
|
44
|
-
}
|
|
45
|
-
|
|
49
|
+
})
|
|
50
|
+
.stdout.toString()
|
|
51
|
+
|
|
46
52
|
return cmdStdout.toString()
|
|
47
53
|
} catch (err) {
|
|
48
54
|
throw new Error(
|
|
@@ -141,7 +147,34 @@ const getJavaBuildDeps = (config, files) => {
|
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
149
|
|
|
150
|
+
const agreementPrompt = async config => {
|
|
151
|
+
const rl = readLine.createInterface({
|
|
152
|
+
input: process.stdin,
|
|
153
|
+
output: process.stdout
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
rl.question('❔ Do you want to continue? Type Y or N', async input => {
|
|
158
|
+
if (input.toLowerCase() === 'yes' || input.toLowerCase() === 'y') {
|
|
159
|
+
config.javaAgreement = paramHandler.setAgreement(true)
|
|
160
|
+
rl.close()
|
|
161
|
+
resolve(config)
|
|
162
|
+
} else if (input.toLowerCase() === 'no' || input.toLowerCase() === 'n') {
|
|
163
|
+
rl.close()
|
|
164
|
+
resolve(process.exit(1))
|
|
165
|
+
} else {
|
|
166
|
+
rl.close()
|
|
167
|
+
console.log('Invalid Input: Exiting')
|
|
168
|
+
resolve(process.exit(1))
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
}).catch(e => {
|
|
172
|
+
throw e
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
144
176
|
module.exports = {
|
|
145
177
|
getJavaBuildDeps,
|
|
146
|
-
determineProjectTypeAndCwd
|
|
178
|
+
determineProjectTypeAndCwd,
|
|
179
|
+
agreementPrompt
|
|
147
180
|
}
|
|
@@ -4,12 +4,16 @@ const { createJavaTSMessage } = require('../common/formatMessage')
|
|
|
4
4
|
const {
|
|
5
5
|
parseDependenciesForSCAServices
|
|
6
6
|
} = require('../common/scaParserForGoAndJava')
|
|
7
|
+
const chalk = require('chalk')
|
|
8
|
+
const _ = require('lodash')
|
|
7
9
|
|
|
8
|
-
const javaAnalysis = (config, languageFiles) => {
|
|
10
|
+
const javaAnalysis = async (config, languageFiles) => {
|
|
9
11
|
languageFiles.JAVA.forEach(file => {
|
|
10
12
|
file.replace('build.gradle.kts', 'build.gradle')
|
|
11
13
|
})
|
|
12
14
|
|
|
15
|
+
await getAgreement(config)
|
|
16
|
+
|
|
13
17
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
14
18
|
|
|
15
19
|
if (config.experimental) {
|
|
@@ -19,11 +23,24 @@ const javaAnalysis = (config, languageFiles) => {
|
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
const getAgreement = async config => {
|
|
27
|
+
console.log(chalk.bold('Java project detected'))
|
|
28
|
+
console.log(
|
|
29
|
+
'Java analysis uses maven / gradle which are potentially susceptible to command injection. Be sure that the code you are running Contrast CLI on is trusted before continuing.'
|
|
30
|
+
)
|
|
31
|
+
if (_.isNil(!process.env.CI) && _.isNil(!config.javaAgreement)) {
|
|
32
|
+
console.log('should print')
|
|
33
|
+
return await analysis.agreementPrompt(config)
|
|
34
|
+
}
|
|
35
|
+
return config
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
const buildJavaTree = (config, files) => {
|
|
23
39
|
const javaBuildDeps = analysis.getJavaBuildDeps(config, files)
|
|
24
40
|
return parseBuildDeps(config, javaBuildDeps)
|
|
25
41
|
}
|
|
26
42
|
|
|
27
43
|
module.exports = {
|
|
28
|
-
javaAnalysis
|
|
44
|
+
javaAnalysis,
|
|
45
|
+
getAgreement
|
|
29
46
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
const i18n = require('i18n')
|
|
2
2
|
const fileFinder = require('./fileUtils')
|
|
3
|
-
|
|
4
|
-
const
|
|
3
|
+
|
|
4
|
+
const autoDetectFingerprintInfo = async filePath => {
|
|
5
|
+
let complexObj = await fileFinder.findAllFiles(filePath)
|
|
6
|
+
let result = []
|
|
7
|
+
let count = 0
|
|
8
|
+
complexObj.forEach(i => {
|
|
9
|
+
count++
|
|
10
|
+
result.push({ filePath: i, id: count.toString() })
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
return result
|
|
14
|
+
}
|
|
5
15
|
|
|
6
16
|
const autoDetectFileAndLanguage = async configToUse => {
|
|
7
17
|
const entries = await fileFinder.findFile()
|
|
@@ -88,5 +98,6 @@ module.exports = {
|
|
|
88
98
|
autoDetectFileAndLanguage,
|
|
89
99
|
errorOnFileDetection,
|
|
90
100
|
autoDetectAuditFilesAndLanguages,
|
|
91
|
-
errorOnAuditFileDetection
|
|
101
|
+
errorOnAuditFileDetection,
|
|
102
|
+
autoDetectFingerprintInfo
|
|
92
103
|
}
|
package/src/scan/fileUtils.js
CHANGED
|
@@ -11,6 +11,33 @@ const findFile = async () => {
|
|
|
11
11
|
})
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const findAllFiles = async filePath => {
|
|
15
|
+
const result = await fg(
|
|
16
|
+
[
|
|
17
|
+
'**/pom.xml',
|
|
18
|
+
'**/build.gradle',
|
|
19
|
+
'**/build.gradle.kts',
|
|
20
|
+
'**/package.json',
|
|
21
|
+
'**/Pipfile',
|
|
22
|
+
'**/*.csproj',
|
|
23
|
+
'**/Gemfile',
|
|
24
|
+
'**/go.mod'
|
|
25
|
+
],
|
|
26
|
+
{
|
|
27
|
+
dot: false,
|
|
28
|
+
deep: 2,
|
|
29
|
+
onlyFiles: true,
|
|
30
|
+
absolute: true,
|
|
31
|
+
cwd: filePath ? filePath : process.cwd()
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
if (result.length > 0) {
|
|
36
|
+
return result
|
|
37
|
+
}
|
|
38
|
+
return []
|
|
39
|
+
}
|
|
40
|
+
|
|
14
41
|
const findFilesJava = async (languagesFound, filePath) => {
|
|
15
42
|
const result = await fg(
|
|
16
43
|
['**/pom.xml', '**/build.gradle', '**/build.gradle.kts'],
|
|
@@ -159,5 +186,6 @@ module.exports = {
|
|
|
159
186
|
findFilesPhp,
|
|
160
187
|
findFilesRuby,
|
|
161
188
|
findFilesDotNet,
|
|
162
|
-
fileIsEmpty
|
|
189
|
+
fileIsEmpty,
|
|
190
|
+
findAllFiles
|
|
163
191
|
}
|
package/src/scan/help.js
CHANGED
package/src/scan/saveResults.js
CHANGED
|
@@ -3,7 +3,7 @@ const fs = require('fs')
|
|
|
3
3
|
const writeResultsToFile = async (responseBody, name = 'results.sarif') => {
|
|
4
4
|
try {
|
|
5
5
|
fs.writeFileSync(name, JSON.stringify(responseBody, null, 2))
|
|
6
|
-
|
|
6
|
+
return name
|
|
7
7
|
} catch (err) {
|
|
8
8
|
console.log('Error writing Scan Results to file')
|
|
9
9
|
}
|
package/src/utils/commonApi.js
CHANGED
|
@@ -5,7 +5,10 @@ const {
|
|
|
5
5
|
forbiddenError,
|
|
6
6
|
proxyError,
|
|
7
7
|
genericError,
|
|
8
|
-
maxAppError
|
|
8
|
+
maxAppError,
|
|
9
|
+
snapshotFailureError,
|
|
10
|
+
vulnerabilitiesFailureError,
|
|
11
|
+
reportFailureError
|
|
9
12
|
} = require('../common/errorHandling')
|
|
10
13
|
|
|
11
14
|
const handleResponseErrors = (res, api) => {
|
|
@@ -20,6 +23,15 @@ const handleResponseErrors = (res, api) => {
|
|
|
20
23
|
} else if (res.statusCode === 412) {
|
|
21
24
|
maxAppError()
|
|
22
25
|
} else {
|
|
26
|
+
if (api === 'snapshot' || api === 'catalogue') {
|
|
27
|
+
snapshotFailureError()
|
|
28
|
+
}
|
|
29
|
+
if (api === 'vulnerabilities') {
|
|
30
|
+
vulnerabilitiesFailureError()
|
|
31
|
+
}
|
|
32
|
+
if (api === 'report') {
|
|
33
|
+
reportFailureError()
|
|
34
|
+
}
|
|
23
35
|
console.log(res.statusCode)
|
|
24
36
|
genericError(res)
|
|
25
37
|
}
|
package/src/utils/generalAPI.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const { featuresTeamServer } = require('./capabilities')
|
|
2
2
|
const semver = require('semver')
|
|
3
|
-
const { handleResponseErrors } = require('../common/errorHandling')
|
|
4
3
|
const commonApi = require('./commonApi')
|
|
5
4
|
const { isNil } = require('lodash')
|
|
6
5
|
|
|
@@ -12,7 +11,7 @@ const getGlobalProperties = async config => {
|
|
|
12
11
|
if (res.statusCode === 200) {
|
|
13
12
|
return res.body
|
|
14
13
|
} else {
|
|
15
|
-
handleResponseErrors(res, 'globalProperties')
|
|
14
|
+
commonApi.handleResponseErrors(res, 'globalProperties')
|
|
16
15
|
}
|
|
17
16
|
})
|
|
18
17
|
.catch(err => {
|
package/src/utils/getConfig.ts
CHANGED
|
@@ -16,4 +16,17 @@ const getAuth = () => {
|
|
|
16
16
|
return ContrastConfToUse
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const getAgreement = () => {
|
|
20
|
+
const ContrastConf = config.localConfig(APP_NAME, APP_VERSION)
|
|
21
|
+
let ContrastConfToUse = {}
|
|
22
|
+
ContrastConfToUse.javaAgreement = ContrastConf.get('javaAgreement')
|
|
23
|
+
return ContrastConfToUse
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const setAgreement = agreement => {
|
|
27
|
+
const ContrastConf = config.localConfig(APP_NAME, APP_VERSION)
|
|
28
|
+
ContrastConf.set('javaAgreement', agreement)
|
|
29
|
+
return agreement
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { getAuth, getAgreement, setAgreement }
|
|
@@ -21,4 +21,12 @@ const getAuth = params => {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
const getAgreement = () => {
|
|
25
|
+
return configStoreParams.getAgreement()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const setAgreement = answer => {
|
|
29
|
+
return configStoreParams.setAgreement(answer)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { getAuth, getAgreement, setAgreement }
|
package/src/utils/saveFile.js
CHANGED
|
@@ -8,7 +8,8 @@ const saveScanFile = async (config, scanResults) => {
|
|
|
8
8
|
const scanId = scanResults.scanDetail.id
|
|
9
9
|
const client = commonApi.getHttpClient(config)
|
|
10
10
|
const rawResults = await client.getSpecificScanResultSarif(config, scanId)
|
|
11
|
-
await saveResults.writeResultsToFile(rawResults?.body)
|
|
11
|
+
const name = await saveResults.writeResultsToFile(rawResults?.body)
|
|
12
|
+
console.log(`Scan Results saved to ${name}`)
|
|
12
13
|
} else {
|
|
13
14
|
console.log(i18n.__('scanNoFiletypeSpecifiedForSave'))
|
|
14
15
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import paramHandler from '../../utils/paramsUtil/paramHandler'
|
|
2
|
-
import constants from '../../cliConstants'
|
|
3
|
-
import { getCommandLineArgsCustom } from '../../utils/parsedCLIOptions'
|
|
4
|
-
import { ContrastConf } from '../../utils/getConfig'
|
|
5
|
-
|
|
6
|
-
export const getAuditConfig = async (
|
|
7
|
-
contrastConf: ContrastConf,
|
|
8
|
-
command: string,
|
|
9
|
-
argv: string[]
|
|
10
|
-
): Promise<{ [key: string]: string }> => {
|
|
11
|
-
const auditParameters = await getCommandLineArgsCustom(
|
|
12
|
-
contrastConf,
|
|
13
|
-
command,
|
|
14
|
-
argv,
|
|
15
|
-
constants.commandLineDefinitions.auditOptionDefinitions
|
|
16
|
-
)
|
|
17
|
-
const paramsAuth = paramHandler.getAuth(auditParameters)
|
|
18
|
-
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
return { ...paramsAuth, ...auditParameters }
|
|
21
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { getAuditConfig } from './auditConfig'
|
|
2
|
-
import { auditUsageGuide } from './help'
|
|
3
|
-
import { processSca } from '../scan/sca/scaAnalysis'
|
|
4
|
-
import { sendTelemetryConfigAsObject } from '../../telemetry/telemetry'
|
|
5
|
-
import { ContrastConf } from '../../utils/getConfig'
|
|
6
|
-
import chalk from 'chalk'
|
|
7
|
-
|
|
8
|
-
export type parameterInput = string[]
|
|
9
|
-
|
|
10
|
-
export const processAudit = async (
|
|
11
|
-
contrastConf: ContrastConf,
|
|
12
|
-
argv: parameterInput
|
|
13
|
-
) => {
|
|
14
|
-
if (argv.indexOf('--help') != -1) {
|
|
15
|
-
printHelpMessage()
|
|
16
|
-
process.exit(0)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const config = await getAuditConfig(contrastConf, 'audit', argv)
|
|
20
|
-
await processSca(config)
|
|
21
|
-
postRunMessage()
|
|
22
|
-
await sendTelemetryConfigAsObject(
|
|
23
|
-
config,
|
|
24
|
-
'audit',
|
|
25
|
-
argv,
|
|
26
|
-
'SUCCESS',
|
|
27
|
-
// @ts-ignore
|
|
28
|
-
config.language
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const printHelpMessage = () => {
|
|
33
|
-
console.log(auditUsageGuide)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const postRunMessage = () => {
|
|
37
|
-
console.log('\n' + chalk.underline.bold('Other Codesec Features:'))
|
|
38
|
-
console.log("'contrast scan' to run CodeSec’s industry leading SAST scanner")
|
|
39
|
-
console.log("'contrast lambda' to secure your AWS serverless functions\n")
|
|
40
|
-
}
|
package/src/common/commonHelp.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import i18n from 'i18n'
|
|
2
|
-
|
|
3
|
-
export function commonHelpLinks() {
|
|
4
|
-
return {
|
|
5
|
-
header: i18n.__('commonHelpHeader'),
|
|
6
|
-
content: [
|
|
7
|
-
i18n.__('commonHelpCheckOutHeader') + i18n.__('commonHelpCheckOutText'),
|
|
8
|
-
i18n.__('commonHelpLearnMoreHeader') + i18n.__('commonHelpLearnMoreText'),
|
|
9
|
-
i18n.__('commonHelpJoinDiscussionHeader') +
|
|
10
|
-
i18n.__('commonHelpJoinDiscussionText')
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
}
|