@contrast/contrast 1.0.10 → 1.0.11
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/README.md +1 -1
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +39 -28
- package/dist/audit/languageAnalysisEngine/report/models/reportGuidanceModel.js +6 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +1 -2
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +1 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +11 -7
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +1 -2
- package/dist/commands/audit/auditConfig.js +3 -3
- package/dist/commands/audit/processAudit.js +4 -2
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/config/config.js +2 -2
- package/dist/commands/scan/processScan.js +11 -4
- package/dist/commands/scan/sca/scaAnalysis.js +10 -3
- package/dist/common/HTTPClient.js +9 -0
- package/dist/common/fail.js +66 -0
- package/dist/common/versionChecker.js +1 -1
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +6 -3
- package/dist/constants.js +39 -1
- package/dist/index.js +5 -2
- package/dist/scaAnalysis/common/scaParserForGoAndJava.js +32 -0
- package/dist/scaAnalysis/common/treeUpload.js +20 -5
- package/dist/scaAnalysis/dotnet/analysis.js +15 -3
- package/dist/scaAnalysis/go/goAnalysis.js +8 -2
- package/dist/scaAnalysis/java/analysis.js +10 -6
- package/dist/scaAnalysis/java/index.js +7 -1
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +19 -3
- package/dist/scaAnalysis/python/analysis.js +43 -5
- package/dist/scaAnalysis/python/index.js +7 -2
- package/dist/scaAnalysis/ruby/analysis.js +14 -4
- package/dist/scan/formatScanOutput.js +6 -5
- package/dist/scan/populateProjectIdAndProjectName.js +5 -0
- package/dist/scan/scan.js +4 -0
- package/dist/scan/scanConfig.js +3 -3
- package/dist/scan/scanResults.js +39 -3
- package/dist/telemetry/telemetry.js +137 -0
- package/dist/utils/getConfig.js +2 -2
- package/dist/utils/parsedCLIOptions.js +3 -1
- package/dist/utils/requestUtils.js +7 -1
- package/package.json +1 -1
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +57 -39
- package/src/audit/languageAnalysisEngine/report/models/reportGuidanceModel.ts +5 -0
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +1 -7
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +2 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +15 -8
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +2 -2
- package/src/commands/audit/auditConfig.ts +10 -3
- package/src/commands/audit/processAudit.ts +16 -2
- package/src/commands/auth/auth.js +3 -1
- package/src/commands/config/config.js +4 -2
- package/src/commands/scan/processScan.js +18 -4
- package/src/commands/scan/sca/scaAnalysis.js +11 -3
- package/src/common/HTTPClient.js +14 -0
- package/src/common/fail.js +75 -0
- package/src/common/versionChecker.ts +1 -1
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +8 -4
- package/src/constants.js +43 -1
- package/src/index.ts +17 -2
- package/src/scaAnalysis/common/scaParserForGoAndJava.js +41 -0
- package/src/scaAnalysis/common/treeUpload.js +21 -6
- package/src/scaAnalysis/dotnet/analysis.js +21 -3
- package/src/scaAnalysis/go/goAnalysis.js +9 -2
- package/src/scaAnalysis/java/analysis.js +11 -6
- package/src/scaAnalysis/java/index.js +9 -1
- package/src/scaAnalysis/java/javaBuildDepsParser.js +25 -6
- package/src/scaAnalysis/python/analysis.js +49 -5
- package/src/scaAnalysis/python/index.js +7 -2
- package/src/scaAnalysis/ruby/analysis.js +16 -4
- package/src/scan/formatScanOutput.ts +7 -5
- package/src/scan/populateProjectIdAndProjectName.js +5 -1
- package/src/scan/scan.ts +4 -0
- package/src/scan/scanConfig.js +5 -3
- package/src/scan/scanResults.js +46 -3
- package/src/telemetry/telemetry.ts +154 -0
- package/src/utils/getConfig.ts +4 -6
- package/src/utils/parsedCLIOptions.js +14 -1
- package/src/utils/requestUtils.js +8 -1
package/src/constants.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const commandLineUsage = require('command-line-usage')
|
|
2
2
|
const i18n = require('i18n')
|
|
3
3
|
const { en_locales } = require('./constants/locales.js')
|
|
4
|
+
const { parseSeverity } = require('./common/fail')
|
|
4
5
|
|
|
5
6
|
i18n.configure({
|
|
6
7
|
staticCatalog: {
|
|
@@ -106,6 +107,24 @@ const scanOptionDefinitions = [
|
|
|
106
107
|
'}: ' +
|
|
107
108
|
i18n.__('constantsProxyServer')
|
|
108
109
|
},
|
|
110
|
+
{
|
|
111
|
+
name: 'fail',
|
|
112
|
+
type: Boolean,
|
|
113
|
+
description:
|
|
114
|
+
'{bold ' +
|
|
115
|
+
i18n.__('constantsOptional') +
|
|
116
|
+
'}: ' +
|
|
117
|
+
i18n.__('failOptionErrorMessage')
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'severity',
|
|
121
|
+
type: severity => parseSeverity(severity),
|
|
122
|
+
description:
|
|
123
|
+
'{bold ' +
|
|
124
|
+
i18n.__('constantsOptional') +
|
|
125
|
+
'}: ' +
|
|
126
|
+
i18n.__('constantsSeverity')
|
|
127
|
+
},
|
|
109
128
|
{
|
|
110
129
|
name: 'ff',
|
|
111
130
|
type: Boolean,
|
|
@@ -220,6 +239,24 @@ const auditOptionDefinitions = [
|
|
|
220
239
|
'}: ' +
|
|
221
240
|
i18n.__('constantsFilePath')
|
|
222
241
|
},
|
|
242
|
+
{
|
|
243
|
+
name: 'fail',
|
|
244
|
+
type: Boolean,
|
|
245
|
+
description:
|
|
246
|
+
'{bold ' +
|
|
247
|
+
i18n.__('constantsOptional') +
|
|
248
|
+
'}: ' +
|
|
249
|
+
i18n.__('failOptionErrorMessage')
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: 'severity',
|
|
253
|
+
type: severity => parseSeverity(severity),
|
|
254
|
+
description:
|
|
255
|
+
'{bold ' +
|
|
256
|
+
i18n.__('constantsOptional') +
|
|
257
|
+
'}: ' +
|
|
258
|
+
i18n.__('constantsSeverity')
|
|
259
|
+
},
|
|
223
260
|
{
|
|
224
261
|
name: 'app-groups',
|
|
225
262
|
description:
|
|
@@ -257,6 +294,7 @@ const auditOptionDefinitions = [
|
|
|
257
294
|
{
|
|
258
295
|
name: 'ignore-dev',
|
|
259
296
|
type: Boolean,
|
|
297
|
+
alias: 'i',
|
|
260
298
|
description:
|
|
261
299
|
'{bold ' +
|
|
262
300
|
i18n.__('constantsOptional') +
|
|
@@ -293,7 +331,6 @@ const auditOptionDefinitions = [
|
|
|
293
331
|
},
|
|
294
332
|
{
|
|
295
333
|
name: 'host',
|
|
296
|
-
alias: 'h',
|
|
297
334
|
description:
|
|
298
335
|
'{bold ' +
|
|
299
336
|
i18n.__('constantsRequired') +
|
|
@@ -341,6 +378,11 @@ const auditOptionDefinitions = [
|
|
|
341
378
|
i18n.__('constantsOptional') +
|
|
342
379
|
'}: ' +
|
|
343
380
|
i18n.__('scanOptionsTimeoutSummary')
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: 'help',
|
|
384
|
+
alias: 'h',
|
|
385
|
+
type: Boolean
|
|
344
386
|
}
|
|
345
387
|
]
|
|
346
388
|
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
isCorrectNodeVersion
|
|
15
15
|
} from './common/versionChecker'
|
|
16
16
|
import { findCommandOnError } from './common/errorHandling'
|
|
17
|
+
import { sendTelemetryConfigAsConfObj } from './telemetry/telemetry'
|
|
17
18
|
|
|
18
19
|
const {
|
|
19
20
|
commandLineDefinitions: { mainUsageGuide, mainDefinition }
|
|
@@ -75,11 +76,11 @@ const start = async () => {
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
if (command === 'scan') {
|
|
78
|
-
return await processScan(argvMain)
|
|
79
|
+
return await processScan(config, argvMain)
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
if (command === 'audit') {
|
|
82
|
-
return await processAudit(argvMain)
|
|
83
|
+
return await processAudit(config, argvMain)
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
if (
|
|
@@ -98,10 +99,24 @@ const start = async () => {
|
|
|
98
99
|
: console.log(
|
|
99
100
|
`Unknown Command: ${command} \nUse --help for the full list`
|
|
100
101
|
)
|
|
102
|
+
await sendTelemetryConfigAsConfObj(
|
|
103
|
+
config,
|
|
104
|
+
command,
|
|
105
|
+
argvMain,
|
|
106
|
+
'FAILURE',
|
|
107
|
+
'undefined'
|
|
108
|
+
)
|
|
101
109
|
} else {
|
|
102
110
|
console.log(
|
|
103
111
|
`Unknown Command: ${command} \nUse --help for the full list`
|
|
104
112
|
)
|
|
113
|
+
await sendTelemetryConfigAsConfObj(
|
|
114
|
+
config,
|
|
115
|
+
command,
|
|
116
|
+
argvMain,
|
|
117
|
+
'FAILURE',
|
|
118
|
+
'undefined'
|
|
119
|
+
)
|
|
105
120
|
}
|
|
106
121
|
process.exit(9)
|
|
107
122
|
} else {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const parseDependenciesForSCAServices = dependencyTreeObject => {
|
|
2
|
+
let parsedDependencyTree = {}
|
|
3
|
+
let subDeps
|
|
4
|
+
|
|
5
|
+
for (let tree in dependencyTreeObject) {
|
|
6
|
+
let unParsedDependencyTree = dependencyTreeObject[tree]
|
|
7
|
+
for (let dependency in unParsedDependencyTree) {
|
|
8
|
+
subDeps = parseSubDependencies(unParsedDependencyTree[dependency].edges)
|
|
9
|
+
|
|
10
|
+
let parsedDependency = {
|
|
11
|
+
name: unParsedDependencyTree[dependency].artifactID,
|
|
12
|
+
group: unParsedDependencyTree[dependency].group,
|
|
13
|
+
version: unParsedDependencyTree[dependency].version,
|
|
14
|
+
directDependency: unParsedDependencyTree[dependency].type === 'direct',
|
|
15
|
+
isProduction: true,
|
|
16
|
+
dependencies: subDeps
|
|
17
|
+
}
|
|
18
|
+
parsedDependencyTree[dependency] = parsedDependency
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return parsedDependencyTree
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const parseSubDependencies = dependencies => {
|
|
25
|
+
// converting:
|
|
26
|
+
// dependencies: {
|
|
27
|
+
// 'gopkg.in/check.v1@v0.0.0-2': 'gopkg.in/check.v1@v0.0.0-2'
|
|
28
|
+
// }
|
|
29
|
+
// to:
|
|
30
|
+
// dependencies: [ 'gopkg.in/check.v1@v0.0.0-2' ]
|
|
31
|
+
let subDeps = []
|
|
32
|
+
for (let x in dependencies) {
|
|
33
|
+
subDeps.push(dependencies[x])
|
|
34
|
+
}
|
|
35
|
+
return subDeps
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
parseDependenciesForSCAServices,
|
|
40
|
+
parseSubDependencies
|
|
41
|
+
}
|
|
@@ -2,12 +2,14 @@ const commonApi = require('../../utils/commonApi')
|
|
|
2
2
|
const { APP_VERSION } = require('../../constants/constants')
|
|
3
3
|
|
|
4
4
|
const commonSendSnapShot = async (analysis, config) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
let requestBody = {}
|
|
6
|
+
config.experimental === true
|
|
7
|
+
? (requestBody = sendToSCAServices(config, analysis))
|
|
8
|
+
: (requestBody = {
|
|
9
|
+
appID: config.applicationId,
|
|
10
|
+
cliVersion: APP_VERSION,
|
|
11
|
+
snapshot: analysis
|
|
12
|
+
})
|
|
11
13
|
const client = commonApi.getHttpClient(config)
|
|
12
14
|
return client
|
|
13
15
|
.sendSnapshot(requestBody, config)
|
|
@@ -23,6 +25,19 @@ const commonSendSnapShot = async (analysis, config) => {
|
|
|
23
25
|
})
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
const sendToSCAServices = (config, analysis) => {
|
|
29
|
+
return {
|
|
30
|
+
applicationId: config.applicationId,
|
|
31
|
+
dependencyTree: analysis,
|
|
32
|
+
organizationId: config.organizationId,
|
|
33
|
+
language: config.language,
|
|
34
|
+
tool: {
|
|
35
|
+
name: 'Contrast Codesec',
|
|
36
|
+
version: APP_VERSION
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
26
41
|
module.exports = {
|
|
27
42
|
commonSendSnapShot
|
|
28
43
|
}
|
|
@@ -40,9 +40,26 @@ const readAndParseLockFile = lockFilePath => {
|
|
|
40
40
|
return lockFile
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
const checkForCorrectFiles = languageFiles => {
|
|
44
|
+
if (!languageFiles.includes('packages.lock.json')) {
|
|
45
|
+
throw new Error(i18n.__('languageAnalysisHasNoLockFile', '.NET'))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!languageFiles.some(i => i.includes('.csproj'))) {
|
|
49
|
+
throw new Error(i18n.__('languageAnalysisProjectFileError', '.NET'))
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
const getDotNetDeps = (filePath, languageFiles) => {
|
|
44
|
-
|
|
45
|
-
const
|
|
54
|
+
checkForCorrectFiles(languageFiles)
|
|
55
|
+
const projectFileName = languageFiles.find(fileName =>
|
|
56
|
+
fileName.includes('.csproj')
|
|
57
|
+
)
|
|
58
|
+
const lockFileName = languageFiles.find(fileName =>
|
|
59
|
+
fileName.includes('.json')
|
|
60
|
+
)
|
|
61
|
+
const projectFile = readAndParseProjectFile(filePath + `/${projectFileName}`)
|
|
62
|
+
const lockFile = readAndParseLockFile(filePath + `/${lockFileName}`)
|
|
46
63
|
|
|
47
64
|
return { projectFile, lockFile }
|
|
48
65
|
}
|
|
@@ -50,5 +67,6 @@ const getDotNetDeps = (filePath, languageFiles) => {
|
|
|
50
67
|
module.exports = {
|
|
51
68
|
getDotNetDeps,
|
|
52
69
|
readAndParseProjectFile,
|
|
53
|
-
readAndParseLockFile
|
|
70
|
+
readAndParseLockFile,
|
|
71
|
+
checkForCorrectFiles
|
|
54
72
|
}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
const { createGoTSMessage } = require('../common/formatMessage')
|
|
2
|
+
const {
|
|
3
|
+
parseDependenciesForSCAServices
|
|
4
|
+
} = require('../common/scaParserForGoAndJava')
|
|
2
5
|
const goReadDepFile = require('./goReadDepFile')
|
|
3
6
|
const goParseDeps = require('./goParseDeps')
|
|
4
7
|
|
|
5
|
-
const goAnalysis =
|
|
8
|
+
const goAnalysis = config => {
|
|
6
9
|
try {
|
|
7
10
|
const rawGoDependencies = goReadDepFile.getGoDependencies(config)
|
|
8
11
|
const parsedGoDependencies =
|
|
9
12
|
goParseDeps.parseGoDependencies(rawGoDependencies)
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
if (config.experimental) {
|
|
15
|
+
return parseDependenciesForSCAServices(parsedGoDependencies)
|
|
16
|
+
} else {
|
|
17
|
+
return createGoTSMessage(parsedGoDependencies)
|
|
18
|
+
}
|
|
12
19
|
} catch (e) {
|
|
13
20
|
console.log(e.message.toString())
|
|
14
21
|
}
|
|
@@ -6,9 +6,13 @@ const fs = require('fs')
|
|
|
6
6
|
const MAVEN = 'maven'
|
|
7
7
|
const GRADLE = 'gradle'
|
|
8
8
|
|
|
9
|
-
const determineProjectTypeAndCwd = (files,
|
|
9
|
+
const determineProjectTypeAndCwd = (files, config) => {
|
|
10
10
|
const projectData = {}
|
|
11
11
|
|
|
12
|
+
if (files.length > 1) {
|
|
13
|
+
files = files.filter(i => config.fileName.includes(i))
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
if (files[0].includes('pom.xml')) {
|
|
13
17
|
projectData.projectType = MAVEN
|
|
14
18
|
} else if (files[0].includes('build.gradle')) {
|
|
@@ -16,9 +20,9 @@ const determineProjectTypeAndCwd = (files, file) => {
|
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
//clean up the path to be a folder not a file
|
|
19
|
-
projectData.cwd = file
|
|
20
|
-
? file.replace('pom.xml', '').replace('build.gradle', '')
|
|
21
|
-
: file
|
|
23
|
+
projectData.cwd = config.file
|
|
24
|
+
? config.file.replace('pom.xml', '').replace('build.gradle', '')
|
|
25
|
+
: config.file
|
|
22
26
|
|
|
23
27
|
return projectData
|
|
24
28
|
}
|
|
@@ -124,7 +128,7 @@ const getJavaBuildDeps = (config, files) => {
|
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
try {
|
|
127
|
-
const projectData = determineProjectTypeAndCwd(files, config
|
|
131
|
+
const projectData = determineProjectTypeAndCwd(files, config)
|
|
128
132
|
if (projectData.projectType === MAVEN) {
|
|
129
133
|
output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout)
|
|
130
134
|
} else if (projectData.projectType === GRADLE) {
|
|
@@ -138,5 +142,6 @@ const getJavaBuildDeps = (config, files) => {
|
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
module.exports = {
|
|
141
|
-
getJavaBuildDeps
|
|
145
|
+
getJavaBuildDeps,
|
|
146
|
+
determineProjectTypeAndCwd
|
|
142
147
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const analysis = require('./analysis')
|
|
2
2
|
const { parseBuildDeps } = require('./javaBuildDepsParser')
|
|
3
3
|
const { createJavaTSMessage } = require('../common/formatMessage')
|
|
4
|
+
const {
|
|
5
|
+
parseDependenciesForSCAServices
|
|
6
|
+
} = require('../common/scaParserForGoAndJava')
|
|
4
7
|
|
|
5
8
|
const javaAnalysis = (config, languageFiles) => {
|
|
6
9
|
languageFiles.JAVA.forEach(file => {
|
|
@@ -8,7 +11,12 @@ const javaAnalysis = (config, languageFiles) => {
|
|
|
8
11
|
})
|
|
9
12
|
|
|
10
13
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
11
|
-
|
|
14
|
+
|
|
15
|
+
if (config.experimental) {
|
|
16
|
+
return parseDependenciesForSCAServices(javaDeps)
|
|
17
|
+
} else {
|
|
18
|
+
return createJavaTSMessage(javaDeps)
|
|
19
|
+
}
|
|
12
20
|
}
|
|
13
21
|
|
|
14
22
|
const buildJavaTree = (config, files) => {
|
|
@@ -14,14 +14,14 @@ const parseBuildDeps = (config, input) => {
|
|
|
14
14
|
const preParser = shavedOutput => {
|
|
15
15
|
let obj = []
|
|
16
16
|
for (let dep in shavedOutput) {
|
|
17
|
+
shavedOutput[dep] = shaveDependencyType(shavedOutput[dep])
|
|
18
|
+
|
|
17
19
|
obj.push(
|
|
18
20
|
shavedOutput[dep]
|
|
19
21
|
.replace('+-', '+---')
|
|
20
22
|
.replace('[INFO]', '')
|
|
21
23
|
.replace('\\-', '\\---')
|
|
22
24
|
.replace(':jar:', ':')
|
|
23
|
-
.replace(':test', '')
|
|
24
|
-
.replace(':compile', '')
|
|
25
25
|
.replace(' +', '+')
|
|
26
26
|
.replace(' |', '|')
|
|
27
27
|
.replace(' \\', '\\')
|
|
@@ -56,11 +56,29 @@ const preParser = shavedOutput => {
|
|
|
56
56
|
return depTree
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
const shaveDependencyType = dep => {
|
|
60
|
+
if (dep.endsWith('\r')) {
|
|
61
|
+
dep = dep.slice(0, -1)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (dep.endsWith(':test')) {
|
|
65
|
+
dep = dep.slice(0, -5)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (dep.endsWith(':compile')) {
|
|
69
|
+
dep = dep.slice(0, -8)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (dep.endsWith(':provided')) {
|
|
73
|
+
dep = dep.slice(0, -9)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return dep
|
|
77
|
+
}
|
|
78
|
+
|
|
59
79
|
const shaveOutput = (gradleDependencyTreeOutput, projectType) => {
|
|
60
80
|
let shavedOutput = gradleDependencyTreeOutput.split('\n')
|
|
61
81
|
|
|
62
|
-
// console.log(projectType)
|
|
63
|
-
|
|
64
82
|
if (projectType === 'maven') {
|
|
65
83
|
shavedOutput = preParser(shavedOutput)
|
|
66
84
|
}
|
|
@@ -375,7 +393,6 @@ const validateIndentation = shavedOutput => {
|
|
|
375
393
|
|
|
376
394
|
const parseGradle = (gradleDependencyTreeOutput, config, projectType) => {
|
|
377
395
|
let shavedOutput = shaveOutput(gradleDependencyTreeOutput, projectType)
|
|
378
|
-
|
|
379
396
|
if (config.subProject) {
|
|
380
397
|
let subProject = parseSubProject(shavedOutput)
|
|
381
398
|
let validatedOutput = validateIndentation(subProject)
|
|
@@ -400,5 +417,7 @@ module.exports = {
|
|
|
400
417
|
computeRelationToLastElement,
|
|
401
418
|
addIndentation,
|
|
402
419
|
computeLevel,
|
|
403
|
-
computeIndentation
|
|
420
|
+
computeIndentation,
|
|
421
|
+
shaveDependencyType,
|
|
422
|
+
preParser
|
|
404
423
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const multiReplace = require('string-multiple-replace')
|
|
2
2
|
const fs = require('fs')
|
|
3
|
+
const i18n = require('i18n')
|
|
3
4
|
|
|
4
5
|
const readAndParseProjectFile = file => {
|
|
5
6
|
const filePath = filePathForWindows(file + '/Pipfile')
|
|
@@ -23,12 +24,52 @@ const readAndParseLockFile = file => {
|
|
|
23
24
|
return parsedPipLock
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const
|
|
27
|
+
const readLockFile = file => {
|
|
28
|
+
const filePath = filePathForWindows(file + '/Pipfile.lock')
|
|
29
|
+
const lockFile = fs.readFileSync(filePath, 'utf8')
|
|
30
|
+
let parsedPipLock = JSON.parse(lockFile)
|
|
31
|
+
return parsedPipLock['default']
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const scaPythonParser = pythonDependencies => {
|
|
35
|
+
let pythonParsedDeps = {}
|
|
36
|
+
for (let key in pythonDependencies) {
|
|
37
|
+
pythonParsedDeps[key] = {}
|
|
38
|
+
pythonParsedDeps[key].version = pythonDependencies[key].version.replace(
|
|
39
|
+
'==',
|
|
40
|
+
''
|
|
41
|
+
)
|
|
42
|
+
pythonParsedDeps[key].group = null
|
|
43
|
+
pythonParsedDeps[key].name = key
|
|
44
|
+
pythonParsedDeps[key].isProduction = true
|
|
45
|
+
pythonParsedDeps[key].dependencies = []
|
|
46
|
+
pythonParsedDeps[key].directDependency = true
|
|
47
|
+
}
|
|
48
|
+
return pythonParsedDeps
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const checkForCorrectFiles = languageFiles => {
|
|
52
|
+
if (!languageFiles.includes('Pipfile.lock')) {
|
|
53
|
+
throw new Error(i18n.__('languageAnalysisHasNoLockFile', 'python'))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!languageFiles.includes('Pipfile')) {
|
|
57
|
+
throw new Error(i18n.__('languageAnalysisProjectFileError', 'python'))
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const getPythonDeps = (config, languageFiles) => {
|
|
27
62
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
63
|
+
if (config.experimental) {
|
|
64
|
+
let pythonLockFileContents = readLockFile(config.file)
|
|
65
|
+
return scaPythonParser(pythonLockFileContents)
|
|
66
|
+
} else {
|
|
67
|
+
checkForCorrectFiles(languageFiles)
|
|
68
|
+
const parseProject = readAndParseProjectFile(config.file)
|
|
69
|
+
const parsePip = readAndParseLockFile(config.file)
|
|
30
70
|
|
|
31
|
-
|
|
71
|
+
return { pipfileLock: parsePip, pipfilDependanceies: parseProject }
|
|
72
|
+
}
|
|
32
73
|
} catch (err) {
|
|
33
74
|
console.log(err.message.toString())
|
|
34
75
|
process.exit(1)
|
|
@@ -44,6 +85,9 @@ const filePathForWindows = path => {
|
|
|
44
85
|
|
|
45
86
|
module.exports = {
|
|
46
87
|
getPythonDeps,
|
|
88
|
+
scaPythonParser,
|
|
89
|
+
readAndParseLockFile,
|
|
47
90
|
readAndParseProjectFile,
|
|
48
|
-
|
|
91
|
+
checkForCorrectFiles,
|
|
92
|
+
readLockFile
|
|
49
93
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
const { createPythonTSMessage } = require('../common/formatMessage')
|
|
2
|
-
const { getPythonDeps } = require('./analysis')
|
|
2
|
+
const { getPythonDeps, secondaryParser } = require('./analysis')
|
|
3
3
|
|
|
4
4
|
const pythonAnalysis = (config, languageFiles) => {
|
|
5
5
|
const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
if (config.experimental) {
|
|
8
|
+
return pythonDeps
|
|
9
|
+
} else {
|
|
10
|
+
return createPythonTSMessage(pythonDeps)
|
|
11
|
+
}
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
module.exports = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
|
+
const i18n = require('i18n')
|
|
2
3
|
|
|
3
4
|
const readAndParseGemfile = file => {
|
|
4
5
|
const gemFile = fs.readFileSync(file + '/Gemfile', 'utf8')
|
|
@@ -241,15 +242,25 @@ const buildSourceDependencyWithVersion = (
|
|
|
241
242
|
return dependencies
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
const getRubyDeps = config => {
|
|
245
|
+
const getRubyDeps = (config, languageFiles) => {
|
|
245
246
|
try {
|
|
247
|
+
checkForCorrectFiles(languageFiles)
|
|
246
248
|
const parsedGem = readAndParseGemfile(config.file)
|
|
247
249
|
const parsedLock = readAndParseGemLockFile(config.file)
|
|
248
250
|
|
|
249
251
|
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock }
|
|
250
252
|
} catch (err) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
+
throw err
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const checkForCorrectFiles = languageFiles => {
|
|
258
|
+
if (!languageFiles.includes('Gemfile.lock')) {
|
|
259
|
+
throw new Error(i18n.__('languageAnalysisHasNoLockFile', 'ruby'))
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!languageFiles.includes('Gemfile')) {
|
|
263
|
+
throw new Error(i18n.__('languageAnalysisProjectFileError', 'ruby'))
|
|
253
264
|
}
|
|
254
265
|
}
|
|
255
266
|
|
|
@@ -269,5 +280,6 @@ module.exports = {
|
|
|
269
280
|
getVersion,
|
|
270
281
|
getPatchLevel,
|
|
271
282
|
formatSourceArr,
|
|
272
|
-
getSourceArray
|
|
283
|
+
getSourceArray,
|
|
284
|
+
checkForCorrectFiles
|
|
273
285
|
}
|
|
@@ -62,12 +62,12 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
|
|
|
62
62
|
})
|
|
63
63
|
let learnRow: string[] = []
|
|
64
64
|
let adviceRow = []
|
|
65
|
+
const headerColour = chalk.hex(entry.colour)
|
|
65
66
|
const headerRow = [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
chalk.hex(entry.colour).bold(`[${entry.severity}] ${entry.ruleId}`) +
|
|
67
|
+
headerColour(`CONTRAST-${count.toString().padStart(3, '0')}`),
|
|
68
|
+
headerColour(`-`),
|
|
69
|
+
headerColour(`[${entry.severity}] `) +
|
|
70
|
+
headerColour.bold(`${entry.ruleId}`) +
|
|
71
71
|
entry.message
|
|
72
72
|
]
|
|
73
73
|
|
|
@@ -104,6 +104,8 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
|
|
|
104
104
|
})
|
|
105
105
|
}
|
|
106
106
|
printVulnInfo(projectOverview)
|
|
107
|
+
|
|
108
|
+
return projectOverview
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
function printVulnInfo(projectOverview: any) {
|
|
@@ -28,7 +28,11 @@ const createProjectId = async (config, client) => {
|
|
|
28
28
|
process.exit(1)
|
|
29
29
|
return
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
if (res.statusCode === 429) {
|
|
32
|
+
console.log(i18n.__('exceededFreeTier'))
|
|
33
|
+
process.exit(1)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
32
36
|
if (res.statusCode === 201) {
|
|
33
37
|
console.log(i18n.__('projectCreatedScan'))
|
|
34
38
|
if (config.verbose) {
|
package/src/scan/scan.ts
CHANGED
|
@@ -47,6 +47,10 @@ export const sendScan = async (config: any) => {
|
|
|
47
47
|
)
|
|
48
48
|
console.log(i18n.__('genericServiceError', res.statusCode))
|
|
49
49
|
}
|
|
50
|
+
if (res.statusCode === 429) {
|
|
51
|
+
console.log(i18n.__('exceededFreeTier'))
|
|
52
|
+
process.exit(1)
|
|
53
|
+
}
|
|
50
54
|
if (res.statusCode === 403) {
|
|
51
55
|
console.log(i18n.__('permissionsError'))
|
|
52
56
|
process.exit(1)
|
package/src/scan/scanConfig.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
const paramHandler = require('../utils/paramsUtil/paramHandler')
|
|
2
2
|
const constants = require('../../src/constants.js')
|
|
3
|
-
const parsedCLIOptions = require('../../src/utils/parsedCLIOptions')
|
|
4
3
|
const path = require('path')
|
|
5
4
|
const { supportedLanguagesScan } = require('../constants/constants')
|
|
6
5
|
const i18n = require('i18n')
|
|
7
6
|
const { scanUsageGuide } = require('./help')
|
|
7
|
+
const parsedCLIOptions = require('../utils/parsedCLIOptions')
|
|
8
8
|
|
|
9
|
-
const getScanConfig = argv => {
|
|
10
|
-
let scanParams = parsedCLIOptions.getCommandLineArgsCustom(
|
|
9
|
+
const getScanConfig = async (contrastConf, command, argv) => {
|
|
10
|
+
let scanParams = await parsedCLIOptions.getCommandLineArgsCustom(
|
|
11
|
+
contrastConf,
|
|
12
|
+
command,
|
|
11
13
|
argv,
|
|
12
14
|
constants.commandLineDefinitions.scanOptionDefinitions
|
|
13
15
|
)
|