@eurekadevsecops/radar 1.8.2 → 1.8.3
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/package.json +2 -2
- package/src/commands/scan.js +27 -6
- package/src/util/git/index.js +16 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eurekadevsecops/radar",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "Radar is an open-source orchestrator of security scanners.",
|
|
5
5
|
"homepage": "https://www.eurekadevsecops.com/radar",
|
|
6
6
|
"keywords": [
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"url": "https://github.com/EurekaDevSecOps/radarctl.git"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@persistr/clif": "^1.11.
|
|
30
|
+
"@persistr/clif": "^1.11.2",
|
|
31
31
|
"@persistr/clif-plugin-settings": "^2.3.1",
|
|
32
32
|
"hosted-git-info": "^9.0.0",
|
|
33
33
|
"humanize-duration": "^3.33.0",
|
package/src/commands/scan.js
CHANGED
|
@@ -17,6 +17,7 @@ module.exports = {
|
|
|
17
17
|
},
|
|
18
18
|
options: [
|
|
19
19
|
{ name: 'CATEGORIES', short: 'c', long: 'categories', type: 'string', description: 'list of scanner categories' },
|
|
20
|
+
{ name: 'DEBUG', short: 'd', long: 'debug', type: 'boolean', description: 'log detailed debug info to stdout' },
|
|
20
21
|
{ name: 'ESCALATE', short: 'e', long: 'escalate', type: 'string', description: 'severities to treat as high/error' },
|
|
21
22
|
{ name: 'FORMAT', short: 'f', long: 'format', type: 'string', description: 'severity format' },
|
|
22
23
|
{ name: 'OUTPUT', short: 'o', long: 'output', type: 'string', description: 'output SARIF file' },
|
|
@@ -75,6 +76,8 @@ module.exports = {
|
|
|
75
76
|
examples: [
|
|
76
77
|
'$ radar scan ' + '(scan current working directory)'.grey,
|
|
77
78
|
'$ radar scan . ' + '(scan current working directory)'.grey,
|
|
79
|
+
'$ radar scan -d' + '(turn debug mode on)'.grey,
|
|
80
|
+
'$ radar scan --debug' + '(turn debug mode on)'.grey,
|
|
78
81
|
'$ radar scan /my/repo/dir ' + '(scan target directory)'.grey,
|
|
79
82
|
'$ radar scan --output=scan.sarif ' + '(save findings in a file)'.grey,
|
|
80
83
|
'$ radar scan -o scan.sarif /my/repo/dir ' + '(short versions of options)'.grey,
|
|
@@ -87,9 +90,12 @@ module.exports = {
|
|
|
87
90
|
'$ radar scan -e moderate,low ' + '(treat lower severities as high)'.grey,
|
|
88
91
|
'$ radar scan -f sarif -e warning,note ' + '(treat lower severities as errors)'.grey
|
|
89
92
|
],
|
|
90
|
-
run: async (toolbox, args) => {
|
|
93
|
+
run: async (toolbox, args, globals) => {
|
|
91
94
|
const { log, scanners: availableScanners, categories: availableCategories, telemetry, git } = toolbox
|
|
92
95
|
|
|
96
|
+
// Enable debug mode, if needed.
|
|
97
|
+
if (args.DEBUG) globals.debug = true
|
|
98
|
+
|
|
93
99
|
// Set defaults for args and options.
|
|
94
100
|
args.TARGET ??= process.cwd()
|
|
95
101
|
args.FORMAT ??= 'security'
|
|
@@ -150,14 +156,24 @@ module.exports = {
|
|
|
150
156
|
}
|
|
151
157
|
catch (error) {
|
|
152
158
|
log(`WARNING: Telemetry will be skipped for this scan run: ${error.message}\n`)
|
|
159
|
+
if (args.DEBUG) {
|
|
160
|
+
log(error)
|
|
161
|
+
if (error?.cause?.code === 'ECONNREFUSED') {
|
|
162
|
+
log(error.cause.errors)
|
|
163
|
+
log()
|
|
164
|
+
}
|
|
165
|
+
}
|
|
153
166
|
}
|
|
154
167
|
}
|
|
155
168
|
|
|
156
169
|
// Send telemetry: git metadata.
|
|
157
170
|
const metadata = git.metadata(target)
|
|
171
|
+
if (metadata.type === 'error') throw new Error(`${metadata.error.code}: ${metadata.error.details}`)
|
|
158
172
|
if (telemetry.enabled && scanID) {
|
|
159
|
-
await telemetry.send(`scans/:scanID/metadata`, { scanID }, { metadata })
|
|
160
|
-
|
|
173
|
+
let res = await telemetry.send(`scans/:scanID/metadata`, { scanID }, { metadata })
|
|
174
|
+
if (!res.ok) log(`WARNING: Scan metadata (stage 1) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
175
|
+
res = await telemetry.sendSensitive(`scans/:scanID/metadata`, { scanID }, { metadata })
|
|
176
|
+
if (!res.ok) log(`WARNING: Scan metadata (stage 2) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
161
177
|
}
|
|
162
178
|
|
|
163
179
|
// Run scanners.
|
|
@@ -170,7 +186,10 @@ module.exports = {
|
|
|
170
186
|
catch (error) {
|
|
171
187
|
log(`\n${error}`)
|
|
172
188
|
if (!args.QUIET) log('Scan NOT completed!')
|
|
173
|
-
if (telemetry.enabled)
|
|
189
|
+
if (telemetry.enabled) {
|
|
190
|
+
const res = await telemetry.send(`scans/:scanID/failed`, { scanID })
|
|
191
|
+
if (!res.ok) log(`WARNING: Scan status (not completed) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
192
|
+
}
|
|
174
193
|
fs.rmSync(tmpdir, { recursive: true, force: true }) // Clean up.
|
|
175
194
|
return 0x10 // exit code
|
|
176
195
|
}
|
|
@@ -184,7 +203,8 @@ module.exports = {
|
|
|
184
203
|
|
|
185
204
|
// Send telemetry: scan results.
|
|
186
205
|
if (telemetry.enabled && scanID) {
|
|
187
|
-
await telemetry.sendSensitive(`scans/:scanID/results`, { scanID }, { findings: results.sarif, log: results.log })
|
|
206
|
+
const res = await telemetry.sendSensitive(`scans/:scanID/results`, { scanID }, { findings: results.sarif, log: results.log })
|
|
207
|
+
if (!res.ok) log(`WARNING: Scan results telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
188
208
|
}
|
|
189
209
|
|
|
190
210
|
// Analyze scan results: group findings by severity level.
|
|
@@ -199,7 +219,8 @@ module.exports = {
|
|
|
199
219
|
|
|
200
220
|
// Send telemetry: scan summary.
|
|
201
221
|
if (telemetry.enabled && scanID) {
|
|
202
|
-
await telemetry.send(`scans/:scanID/completed`, { scanID }, summary)
|
|
222
|
+
const res = await telemetry.send(`scans/:scanID/completed`, { scanID }, summary)
|
|
223
|
+
if (!res.ok) log(`WARNING: Scan status (completed) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
203
224
|
}
|
|
204
225
|
|
|
205
226
|
// Display summarized findings.
|
package/src/util/git/index.js
CHANGED
|
@@ -49,7 +49,7 @@ git rev-list --abbrev=4 --abbrev-commit --all | \
|
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
51
|
// Return the repo metadata.
|
|
52
|
-
|
|
52
|
+
const metadata = {
|
|
53
53
|
type: 'git',
|
|
54
54
|
repo: {
|
|
55
55
|
url: {
|
|
@@ -73,6 +73,21 @@ git rev-list --abbrev=4 --abbrev-commit --all | \
|
|
|
73
73
|
tags
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
// Validate repo metadata.
|
|
78
|
+
if (!metadata.repo.url.origin) throw new Error('remote.origin.url not present')
|
|
79
|
+
if (!metadata.repo.url.https) throw new Error('remote.origin.url (https) not present')
|
|
80
|
+
if (!metadata.repo.source.type) throw new Error('unable to determine repository type')
|
|
81
|
+
if (!metadata.repo.source.domain) throw new Error('unable to determine repository domain')
|
|
82
|
+
if (!metadata.repo.owner) throw new Error('unknown repo owner')
|
|
83
|
+
if (!metadata.repo.name) throw new Error('unknown repo name')
|
|
84
|
+
if (!metadata.repo.abbrevs) throw new Error('unable to determine number of significant digits for commit IDs')
|
|
85
|
+
if (!metadata.repo.contributors) throw new Error('no repository contributors present')
|
|
86
|
+
if (!metadata.commit.id) throw new Error('commit ID not present')
|
|
87
|
+
if (!metadata.commit.time) throw new Error('commit time not present')
|
|
88
|
+
if (!metadata.commit.branch) throw new Error('branch not present')
|
|
89
|
+
|
|
90
|
+
return metadata
|
|
76
91
|
} catch (error) {
|
|
77
92
|
return {
|
|
78
93
|
type: 'error',
|