@eurekadevsecops/radar 1.9.5 → 1.9.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/.config/commitlint/config.mjs +173 -0
- package/.config/commitlint/cz.config.mjs +3 -0
- package/.config/release-please/config.json +51 -0
- package/.config/release-please/manifest.json +3 -0
- package/.github/workflows/commitlint.yaml +35 -0
- package/.github/workflows/radar.yaml +9 -38
- package/.github/workflows/release-please.yaml +21 -0
- package/.husky/commit-msg +1 -0
- package/CHANGELOG.md +46 -0
- package/LICENSE +0 -55
- package/README.md +3 -5
- package/ewa-bitbucket.sarif +61 -0
- package/ewa.sarif +274 -0
- package/package.json +18 -1
- package/src/commands/scan.js +18 -15
- package/src/telemetry/README.md +9 -3
- package/src/telemetry/index.js +13 -9
- package/out.json +0 -6584
- package/out.log +0 -6584
package/ewa.sarif
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.1.0",
|
|
3
|
+
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
|
|
4
|
+
"runs": [
|
|
5
|
+
{
|
|
6
|
+
"tool": {
|
|
7
|
+
"driver": {
|
|
8
|
+
"name": "gitleaks",
|
|
9
|
+
"semanticVersion": "v8.0.0",
|
|
10
|
+
"informationUri": "https://github.com/gitleaks/gitleaks",
|
|
11
|
+
"properties": {
|
|
12
|
+
"officialName": "gitleaks"
|
|
13
|
+
},
|
|
14
|
+
"rules": [
|
|
15
|
+
{
|
|
16
|
+
"id": "bitbucket-client-id",
|
|
17
|
+
"shortDescription": {
|
|
18
|
+
"text": "Discovered a potential Bitbucket Client ID, risking unauthorized repository access and potential codebase exposure."
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "generic-api-key",
|
|
23
|
+
"shortDescription": {
|
|
24
|
+
"text": "Detected a Generic API Key, potentially exposing access to various services and sensitive operations."
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "gitlab-oauth-app-secret",
|
|
29
|
+
"shortDescription": {
|
|
30
|
+
"text": "Identified a GitLab OIDC Application Secret, risking access to apps using GitLab as authentication provider."
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "private-key",
|
|
35
|
+
"shortDescription": {
|
|
36
|
+
"text": "Identified a Private Key, which may compromise cryptographic security and sensitive data encryption."
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "stripe-access-token",
|
|
41
|
+
"shortDescription": {
|
|
42
|
+
"text": "Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"results": [
|
|
49
|
+
{
|
|
50
|
+
"message": {
|
|
51
|
+
"text": "generic-api-key has detected secret for file apps/backend/.env.local."
|
|
52
|
+
},
|
|
53
|
+
"ruleId": "generic-api-key",
|
|
54
|
+
"locations": [
|
|
55
|
+
{
|
|
56
|
+
"physicalLocation": {
|
|
57
|
+
"artifactLocation": {
|
|
58
|
+
"uri": "apps/backend/.env.local"
|
|
59
|
+
},
|
|
60
|
+
"region": {
|
|
61
|
+
"startLine": 121,
|
|
62
|
+
"startColumn": 2,
|
|
63
|
+
"endLine": 121,
|
|
64
|
+
"endColumn": 62,
|
|
65
|
+
"snippet": {
|
|
66
|
+
"text": "0231e56436d8862a967f583939d1d91e955c2bd3"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"properties": {
|
|
73
|
+
"tags": []
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"message": {
|
|
78
|
+
"text": "generic-api-key has detected secret for file apps/backend/.env.local."
|
|
79
|
+
},
|
|
80
|
+
"ruleId": "generic-api-key",
|
|
81
|
+
"locations": [
|
|
82
|
+
{
|
|
83
|
+
"physicalLocation": {
|
|
84
|
+
"artifactLocation": {
|
|
85
|
+
"uri": "apps/backend/.env.local"
|
|
86
|
+
},
|
|
87
|
+
"region": {
|
|
88
|
+
"startLine": 132,
|
|
89
|
+
"startColumn": 2,
|
|
90
|
+
"endLine": 132,
|
|
91
|
+
"endColumn": 57,
|
|
92
|
+
"snippet": {
|
|
93
|
+
"text": "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"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"properties": {
|
|
100
|
+
"tags": []
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"message": {
|
|
105
|
+
"text": "generic-api-key has detected secret for file apps/backend/.env.local."
|
|
106
|
+
},
|
|
107
|
+
"ruleId": "generic-api-key",
|
|
108
|
+
"locations": [
|
|
109
|
+
{
|
|
110
|
+
"physicalLocation": {
|
|
111
|
+
"artifactLocation": {
|
|
112
|
+
"uri": "apps/backend/.env.local"
|
|
113
|
+
},
|
|
114
|
+
"region": {
|
|
115
|
+
"startLine": 146,
|
|
116
|
+
"startColumn": 2,
|
|
117
|
+
"endLine": 146,
|
|
118
|
+
"endColumn": 54,
|
|
119
|
+
"snippet": {
|
|
120
|
+
"text": "00e3e61c-50ed-44f2-8901-ba56c166b4e5"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"properties": {
|
|
127
|
+
"tags": []
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"message": {
|
|
132
|
+
"text": "generic-api-key has detected secret for file apps/backend/.env.local."
|
|
133
|
+
},
|
|
134
|
+
"ruleId": "generic-api-key",
|
|
135
|
+
"locations": [
|
|
136
|
+
{
|
|
137
|
+
"physicalLocation": {
|
|
138
|
+
"artifactLocation": {
|
|
139
|
+
"uri": "apps/backend/.env.local"
|
|
140
|
+
},
|
|
141
|
+
"region": {
|
|
142
|
+
"startLine": 155,
|
|
143
|
+
"startColumn": 2,
|
|
144
|
+
"endLine": 155,
|
|
145
|
+
"endColumn": 58,
|
|
146
|
+
"snippet": {
|
|
147
|
+
"text": "whsec_X92mgLcj9LACgQCfxlEazUtZ5Qb1MSN6"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"properties": {
|
|
154
|
+
"tags": []
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"message": {
|
|
159
|
+
"text": "gitlab-oauth-app-secret has detected secret for file apps/backend/.env.local."
|
|
160
|
+
},
|
|
161
|
+
"ruleId": "gitlab-oauth-app-secret",
|
|
162
|
+
"locations": [
|
|
163
|
+
{
|
|
164
|
+
"physicalLocation": {
|
|
165
|
+
"artifactLocation": {
|
|
166
|
+
"uri": "apps/backend/.env.local"
|
|
167
|
+
},
|
|
168
|
+
"region": {
|
|
169
|
+
"startLine": 126,
|
|
170
|
+
"startColumn": 23,
|
|
171
|
+
"endLine": 126,
|
|
172
|
+
"endColumn": 92,
|
|
173
|
+
"snippet": {
|
|
174
|
+
"text": "gloas-776889e1488d83b207ac8a3e3230b71ee8f91ef6cfd6007aa4f5accb579eacd5"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
"properties": {
|
|
181
|
+
"tags": []
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"message": {
|
|
186
|
+
"text": "private-key has detected secret for file apps/backend/.env.local."
|
|
187
|
+
},
|
|
188
|
+
"ruleId": "private-key",
|
|
189
|
+
"locations": [
|
|
190
|
+
{
|
|
191
|
+
"physicalLocation": {
|
|
192
|
+
"artifactLocation": {
|
|
193
|
+
"uri": "apps/backend/.env.local"
|
|
194
|
+
},
|
|
195
|
+
"region": {
|
|
196
|
+
"startLine": 81,
|
|
197
|
+
"startColumn": 26,
|
|
198
|
+
"endLine": 107,
|
|
199
|
+
"endColumn": 30,
|
|
200
|
+
"snippet": {
|
|
201
|
+
"text": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAs1jrtHlMuqGnpah5PdGJ1Tzeoth+dWJ4hP1Nr8a50z0JCBHT\n7NZ0XW/DmNroKXqxmVW7U1iKw0g96+5xRuJiFDLs+qeJGXiog7gOETKI3gHum2h2\nj/VcGzMRfe7gH4le+69SFnCK9+9nB5H4oVXQ5JimUA74pmRxKWBY9+96BsMUVBp+\n2PYFtOsNHplx+UlzAQ3KnbDlE73aAZpPGW1GKrw8ZkrN22srDokp2ZbjWqbp54mc\nht0/7g2h+6naJonhNOKmadHOb9T2OcwKgmNrNINQq0R7X4fb7Wcs6Ecru8H+8H2h\nInViwTuI17gdrI8iBeNCNayKigdTu5BTFJurJwIDAQABAoIBAFMx330De81jacJV\nyZAcoGSTbO97oAXR3PhMDHqKo+7SdFsS8gz+WlJxovlIKsP7D2GCvHfoLc5yt463\nOELahwa5rOaFSvrO1tTrT1M47vaVTNs4dS9IcSaI5QdXBQ58CdyUsm6IXF6w5klD\ntGMazOEN0rB2kW+WTkwUTpEMvL1ff8BZEvYygv9a8hgPLfxyu4Lvkan7059UG766\nOW5eLQ8eaf+jjWw3YRsty8YK+w3kGOErIHZ7qw+JiQ6nbSxUKbqAGJCXwsvvLiKs\nNfhxeksHqod4CQMIrFDCwYw5pEW9Ji3AWj1XS8h0THYM6z5XPijHsvRVSLC1Fl45\nWFHC6cECgYEA5mFN+XixFLqXGb0N4jtZVC/WUJs+ER9sasMJrwd7moWAyZvjMdkA\nDKq2TeiuNRGcjP9VWM9EWDqNiyQEBxUcwwT3RD5KRykNkLYz51nJZcRmijQUb7ss\nmtLd+tGTaFDfMU3dRihzwYmfYiKJpqwa8mgeTZEXEEU8lEEh7JfrO8cCgYEAx0rD\niI6Lv/7MwoG+cH7eZR3ezyfiGFAbWOfMKtBxLsVyNSzl3JCnyaWf2tsrJSmYlVUa\nANNo9gXvSfrrFjnPOC9ZLEnB2xl1XoJagBFj5Qwf3Giy/i9eiRSu0SyT6WrSzfKa\nOaIFhwwsx1s6Qoeck4UqQFqUgk+FnN3BuCaeVaECgYB0AsfrOnWhxJxWX7dgFxbS\nqAw6JxLIOJS15mU3+IKru1KxM4jjDy1RM539+Y/QNYAqGGH4CNeXvlSMnqRQlLcZ\nFaUWfm+VCf1ExBu7AqHCV3ZzXep0oULC7DDQHz0lqKPcBiPJMpGoAg96sX2zqrMf\nIoMv+EIu9U6eMXZN1+qi/QKBgB0Mv93a8XIGITDFGs5pH9/bb8wAg0uJ+cKG31Lq\nWWU48MHhjowNJfgVxWxwgCSFoLE723N9XZJnIQ9GnRf7S0JkXHpBMhnO5zXkiG6c\nmlQb5VUKifTVUNFoi2cAOXtPz/SnRWXbQTUDSE+y85YZEHDMe3EwAu/PyakpBgDi\n2DehAoGBAKJtxule5t0JQpFzYtk7Ojxv8ppellrqevoX/z+xNG58AT97/JtQAD0D\nTwz1fuptQFe1Mq+cA561hZaTH9MqhTOCVxdP7tMGnGmIT+MXU24o4EhGN0EFtsvR\npKxf8/C9KgyrbfXXzb/LMQIZko0cAFI47EMo/Ad8wgyPDsTnTcJZ\n-----END RSA PRIVATE KEY-----"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
"properties": {
|
|
208
|
+
"tags": []
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"message": {
|
|
213
|
+
"text": "bitbucket-client-id has detected secret for file apps/backend/.env.local."
|
|
214
|
+
},
|
|
215
|
+
"ruleId": "bitbucket-client-id",
|
|
216
|
+
"locations": [
|
|
217
|
+
{
|
|
218
|
+
"physicalLocation": {
|
|
219
|
+
"artifactLocation": {
|
|
220
|
+
"uri": "apps/backend/.env.local"
|
|
221
|
+
},
|
|
222
|
+
"region": {
|
|
223
|
+
"startLine": 116,
|
|
224
|
+
"startColumn": 2,
|
|
225
|
+
"endLine": 116,
|
|
226
|
+
"endColumn": 57,
|
|
227
|
+
"snippet": {
|
|
228
|
+
"text": "KbPZjucUXpxhqmKjP6wbtS5BfEERxdnb"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
"properties": {
|
|
235
|
+
"tags": []
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"message": {
|
|
240
|
+
"text": "stripe-access-token has detected secret for file apps/backend/.env.local."
|
|
241
|
+
},
|
|
242
|
+
"ruleId": "stripe-access-token",
|
|
243
|
+
"locations": [
|
|
244
|
+
{
|
|
245
|
+
"physicalLocation": {
|
|
246
|
+
"artifactLocation": {
|
|
247
|
+
"uri": "apps/backend/.env.local"
|
|
248
|
+
},
|
|
249
|
+
"region": {
|
|
250
|
+
"startLine": 154,
|
|
251
|
+
"startColumn": 24,
|
|
252
|
+
"endLine": 154,
|
|
253
|
+
"endColumn": 130,
|
|
254
|
+
"snippet": {
|
|
255
|
+
"text": "sk_test_51RYvkf2YG6fO9qlhtYIIbnGSXSr6xpzqdqryyPk58EVMgZMjIviKEXde8r55HE4vbVgzKwNb7owr74qRMEHUKakC007aUEcU3n"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
"properties": {
|
|
262
|
+
"tags": []
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
"properties": {
|
|
267
|
+
"repository": {
|
|
268
|
+
"type": "git",
|
|
269
|
+
"url": "https://github.com/EurekaDevSecOps/app.git"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
]
|
|
274
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eurekadevsecops/radar",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.7",
|
|
4
4
|
"description": "Radar is an open-source orchestrator of security scanners.",
|
|
5
5
|
"homepage": "https://www.eurekadevsecops.com/radar",
|
|
6
6
|
"keywords": [
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
"radar": "cli.js"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
+
"commit": "npx cz",
|
|
24
|
+
"prepare": "husky || true",
|
|
23
25
|
"test": "standard"
|
|
24
26
|
},
|
|
25
27
|
"repository": {
|
|
@@ -37,6 +39,21 @@
|
|
|
37
39
|
"tiny-spinner": "^2.0.5"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
42
|
+
"@commitlint/cli": "^20.1.0",
|
|
43
|
+
"@commitlint/config-conventional": "^20.0.0",
|
|
44
|
+
"@commitlint/cz-commitlint": "^20.1.0",
|
|
45
|
+
"commitizen": "^4.3.1",
|
|
46
|
+
"commitlint-plugin-selective-scope": "^1.0.1",
|
|
47
|
+
"conventional-changelog-atom": "^5.0.0",
|
|
48
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
49
|
+
"cz-git": "^1.12.0",
|
|
50
|
+
"husky": "^9.1.7",
|
|
40
51
|
"standard": "*"
|
|
52
|
+
},
|
|
53
|
+
"config": {
|
|
54
|
+
"commitizen": {
|
|
55
|
+
"path": "cz-git",
|
|
56
|
+
"czConfig": ".config/commitlint/cz.config.mjs"
|
|
57
|
+
}
|
|
41
58
|
}
|
|
42
59
|
}
|
package/src/commands/scan.js
CHANGED
|
@@ -4,6 +4,8 @@ const path = require('node:path')
|
|
|
4
4
|
const os = require('node:os')
|
|
5
5
|
const SARIF = require('../util/sarif')
|
|
6
6
|
const runner = require('../util/runner')
|
|
7
|
+
const { DateTime } = require('luxon')
|
|
8
|
+
|
|
7
9
|
module.exports = {
|
|
8
10
|
summary: 'scan for vulnerabilities',
|
|
9
11
|
args: {
|
|
@@ -63,12 +65,11 @@ module.exports = {
|
|
|
63
65
|
|
|
64
66
|
Runs entirely on your machine — by default, Radar CLI doesn’t upload any findings.
|
|
65
67
|
Your vulnerabilities stay local and private. To upload results to Eureka ASPM,
|
|
66
|
-
provide your API credentials
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
set, you can pass the LOCAL option on the command line.
|
|
68
|
+
provide your API credentials through the 'EUREKA_AGENT_TOKEN' environment variable.
|
|
69
|
+
When set, Radar CLI automatically uploads results after each scan — letting you view
|
|
70
|
+
your full scan history and all findings in the Eureka ASPM Dashboard. To prevent
|
|
71
|
+
Radar CLI from uploading scan findings even when you have 'EUREKA_AGENT_TOKEN' set,
|
|
72
|
+
you can pass the LOCAL option on the command line.
|
|
72
73
|
|
|
73
74
|
Exit codes:
|
|
74
75
|
0 - Clean and successful scan. No errors, warnings, or notes.
|
|
@@ -159,12 +160,18 @@ module.exports = {
|
|
|
159
160
|
log(`INFO: Running a local scan.\n`)
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
// Get target git metadata.
|
|
164
|
+
const metadata = git.metadata(target)
|
|
165
|
+
if (metadata.type === 'error') throw new Error(`${metadata.error.code}: ${metadata.error.details}`)
|
|
166
|
+
|
|
162
167
|
// Send telemetry: scan started.
|
|
163
168
|
let scanID = undefined
|
|
169
|
+
const timestamp = DateTime.now().toISO()
|
|
170
|
+
|
|
164
171
|
if (telemetry.enabled && !args.LOCAL) {
|
|
165
172
|
// TODO: Should pass scanID to the server; not read it from the server.
|
|
166
173
|
try {
|
|
167
|
-
const res = await telemetry.send(`scans/started`, {}, { scanners: scanners.map((s) => s.name) })
|
|
174
|
+
const res = await telemetry.send(`scans/started`, {}, { scanners: scanners.map((s) => s.name), metadata, timestamp })
|
|
168
175
|
if (!res.ok) throw new Error(`[${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
169
176
|
const data = await res.json()
|
|
170
177
|
scanID = data.scan_id
|
|
@@ -181,14 +188,10 @@ module.exports = {
|
|
|
181
188
|
}
|
|
182
189
|
}
|
|
183
190
|
|
|
184
|
-
// Send telemetry:
|
|
185
|
-
const metadata = git.metadata(target)
|
|
186
|
-
if (metadata.type === 'error') throw new Error(`${metadata.error.code}: ${metadata.error.details}`)
|
|
191
|
+
// Send telemetry: scan started (stage 2).
|
|
187
192
|
if (telemetry.enabled && scanID && !args.LOCAL) {
|
|
188
|
-
|
|
189
|
-
if (!res.ok) log(`WARNING: Scan
|
|
190
|
-
res = await telemetry.sendSensitive(`scans/:scanID/metadata`, { scanID }, { metadata })
|
|
191
|
-
if (!res.ok) log(`WARNING: Scan metadata (stage 2) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
193
|
+
const res = await telemetry.sendSensitive(`scans/:scanID/started`, { scanID }, { metadata, timestamp })
|
|
194
|
+
if (!res.ok) log(`WARNING: Scan started (stage 2) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
// Run scanners.
|
|
@@ -234,7 +237,7 @@ module.exports = {
|
|
|
234
237
|
|
|
235
238
|
// Send telemetry: scan summary.
|
|
236
239
|
if (telemetry.enabled && scanID && !args.LOCAL) {
|
|
237
|
-
const res = await telemetry.send(`scans/:scanID/completed`, { scanID }, summary)
|
|
240
|
+
const res = await telemetry.send(`scans/:scanID/completed`, { scanID }, { summary })
|
|
238
241
|
if (!res.ok) log(`WARNING: Scan status (completed) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
|
|
239
242
|
}
|
|
240
243
|
|
package/src/telemetry/README.md
CHANGED
|
@@ -11,15 +11,21 @@ const telemetry = require('./telemetry')
|
|
|
11
11
|
|
|
12
12
|
All available telemetry events:
|
|
13
13
|
```js
|
|
14
|
-
telemetry.send(`scans
|
|
14
|
+
telemetry.send(`scans/started`, {}, { scanners, metadata, timestamp })
|
|
15
|
+
telemetry.sendSensitive(`scans/:scanID/started`, { scanID }, { scanners, metadata, timestamp })
|
|
15
16
|
telemetry.send(`scans/:scanID/completed`, { scanID }, { status, findings, log })
|
|
16
17
|
telemetry.sendSensitive(`scans/:scanID/log`, { scanID }, log)
|
|
17
18
|
telemetry.sendSensitive(`scans/:scanID/findings`, { scanID }, sarif)
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
To send a telemetry event indicating that a scan has started:
|
|
21
|
+
To send a telemetry event indicating that a scan has started (stage 1):
|
|
21
22
|
```js
|
|
22
|
-
telemetry.send(`scans
|
|
23
|
+
telemetry.send(`scans/started`, {}, { scanners, metadata })
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
To send a telemetry event indicating that a scan has started (stage 2):
|
|
27
|
+
```js
|
|
28
|
+
telemetry.sendSensitive(`scans/:scanID/started`, { scanID }, { metadata })
|
|
23
29
|
```
|
|
24
30
|
|
|
25
31
|
To send a telemetry event indicating that a scan has completed:
|
package/src/telemetry/index.js
CHANGED
|
@@ -9,7 +9,7 @@ class Telemetry {
|
|
|
9
9
|
|
|
10
10
|
constructor() {
|
|
11
11
|
this.enabled = !!this.#EUREKA_AGENT_TOKEN
|
|
12
|
-
this.#EWA_URL = this.#claims(this.#EUREKA_AGENT_TOKEN)
|
|
12
|
+
this.#EWA_URL = this.#claims(this.#EUREKA_AGENT_TOKEN).aud?.replace(/\/$/, '')
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async send(path, params, body, token) {
|
|
@@ -71,7 +71,8 @@ class Telemetry {
|
|
|
71
71
|
'Content-Type': 'application/json',
|
|
72
72
|
'User-Agent': this.#USER_AGENT,
|
|
73
73
|
'Accept': 'application/json'
|
|
74
|
-
}
|
|
74
|
+
},
|
|
75
|
+
body: JSON.stringify({ profileId: process.env.EUREKA_PROFILE })
|
|
75
76
|
})
|
|
76
77
|
if (!response.ok) throw new Error(`Internal Error: Failed to get VDBE auth token from EWA: ${response.statusText}: ${await response.text()}`)
|
|
77
78
|
const data = await response.json()
|
|
@@ -82,9 +83,9 @@ class Telemetry {
|
|
|
82
83
|
const claims = this.#claims(token ?? this.#EUREKA_AGENT_TOKEN)
|
|
83
84
|
const aud = claims.aud.replace(/\/$/, '')
|
|
84
85
|
if (path === `scans/started`) return `${aud}/scans/started`
|
|
86
|
+
if (path === `scans/:scanID/started`) return `${aud}/scans/${params.scanID}/started`
|
|
85
87
|
if (path === `scans/:scanID/completed`) return `${aud}/scans/${params.scanID}/completed`
|
|
86
88
|
if (path === `scans/:scanID/failed`) return `${aud}/scans/${params.scanID}/completed`
|
|
87
|
-
if (path === `scans/:scanID/metadata`) return `${aud}/scans/${params.scanID}/metadata`
|
|
88
89
|
if (path === `scans/:scanID/results`) return `${aud}/scans/${params.scanID}/results`
|
|
89
90
|
throw new Error(`Internal Error: Unknown telemetry event: POST ${path}`)
|
|
90
91
|
}
|
|
@@ -92,7 +93,11 @@ class Telemetry {
|
|
|
92
93
|
#toReceiveURL(path, params, token) {
|
|
93
94
|
const claims = this.#claims(token ?? this.#EUREKA_AGENT_TOKEN)
|
|
94
95
|
const aud = claims.aud.replace(/\/$/, '')
|
|
95
|
-
if (path === `scans/:scanID/summary`)
|
|
96
|
+
if (path === `scans/:scanID/summary`) {
|
|
97
|
+
const profileId = process.env.EUREKA_PROFILE
|
|
98
|
+
const base = `${aud}/scans/${params.scanID}/summary`
|
|
99
|
+
return profileId ? `${base}?profileId=${profileId}` : base
|
|
100
|
+
}
|
|
96
101
|
throw new Error(`Internal Error: Unknown telemetry event: GET ${path}`)
|
|
97
102
|
}
|
|
98
103
|
|
|
@@ -102,11 +107,11 @@ class Telemetry {
|
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
#toBody(path, body) {
|
|
105
|
-
if (path === `scans/started`) body = { ...body,
|
|
106
|
-
if (path === `scans/:scanID/
|
|
110
|
+
if (path === `scans/started`) body = { ...body, profileId: process.env.EUREKA_PROFILE }
|
|
111
|
+
if (path === `scans/:scanID/started`) body = { ...body, profileId: process.env.EUREKA_PROFILE }
|
|
112
|
+
if (path === `scans/:scanID/completed`) body = { ...this.#toFindings(body.summary), timestamp: DateTime.now().toISO(), status: 'success', log: { sizeBytes: 0, warnings: 0, errors: 0, link: 'none' }, profileId: process.env.EUREKA_PROFILE, params: { id: '' }}
|
|
107
113
|
if (path === `scans/:scanID/failed`) body = { ...body, timestamp: DateTime.now().toISO(), status: 'failure', findings: { total: 0, critical: 0, high: 0, med: 0, low: 0 }, log: { sizeBytes: 0, warnings: 0, errors: 0, link: 'none' }, params: { id: '' }}
|
|
108
|
-
if (path === `scans/:scanID/
|
|
109
|
-
if (path === `scans/:scanID/results`) body = { findings: body.findings /* SARIF */, profileId: process.env.EUREKA_PROFILE, log: Buffer.from(body.log, 'utf8').toString('base64') }
|
|
114
|
+
if (path === `scans/:scanID/results`) body = { findings: body.findings /* SARIF */, log: Buffer.from(body.log, 'utf8').toString('base64'), profileId: process.env.EUREKA_PROFILE }
|
|
110
115
|
return JSON.stringify(body)
|
|
111
116
|
}
|
|
112
117
|
|
|
@@ -121,7 +126,6 @@ class Telemetry {
|
|
|
121
126
|
}
|
|
122
127
|
}
|
|
123
128
|
}
|
|
124
|
-
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
module.exports = {
|