@eurekadevsecops/radar 1.5.1 → 1.6.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eurekadevsecops/radar",
3
- "version": "1.5.1",
3
+ "version": "1.6.1",
4
4
  "description": "Radar is an open-source orchestrator of security scanners.",
5
5
  "homepage": "https://www.eurekadevsecops.com/radar",
6
6
  "keywords": [
@@ -0,0 +1,5 @@
1
+ name = "depscan"
2
+ title = "OWASP dep-scan"
3
+ description = "Next-generation security and risk audit tool."
4
+ categories = [ "SCA" ]
5
+ cmd = "${assets}/run.sh ${target} ${assets} ${output}"
@@ -0,0 +1,5 @@
1
+ name = "gitleaks"
2
+ title = "Gitleaks"
3
+ description = "Detect secrets like passwords, API keys, and tokens in source code."
4
+ categories = [ "SAST" ]
5
+ cmd = "${assets}/run.sh ${target} ${assets} ${output}"
@@ -0,0 +1,5 @@
1
+ name = "grype"
2
+ title = "Grype"
3
+ description = "A vulnerability scanner for container images and filesystems."
4
+ categories = [ "SCA" ]
5
+ cmd = "${assets}/run.sh ${target} ${assets} ${output}"
@@ -0,0 +1,7 @@
1
+ # Parameters:
2
+ # $1 - Path to the source code folder that should be scanned
3
+ # $2 - Path to the assets folder
4
+ # $3 - Path to the output folder where scan results should be stored
5
+
6
+ set -e
7
+ docker run --rm -v $1:/app -v $2:/input -v $3:/output ghcr.io/eurekadevsecops/radar-grype 2>&1
@@ -0,0 +1,5 @@
1
+ name = "opengrep"
2
+ title = "Opengrep"
3
+ description = "Ultra-fast static analysis tool."
4
+ categories = [ "SAST" ]
5
+ cmd = "${assets}/run.sh ${target} ${assets} ${output}"
@@ -2,8 +2,46 @@ const fs = require('node:fs')
2
2
  const path = require('node:path')
3
3
  const TOML = require('smol-toml')
4
4
 
5
- const data = fs.readFileSync(path.join(__dirname, '..', '..', 'scanners', 'scanners.toml'), 'utf8')
6
- const config = TOML.parse(data)
5
+ function enumerate(dir) {
6
+ const files = []
7
+ const entries = fs.readdirSync(dir, { withFileTypes: true })
8
+ for (const entry of entries) {
9
+ if (entry.isDirectory()) {
10
+ const candidate = path.join(dir, entry.name, 'about.toml')
11
+ try {
12
+ const stat = fs.statSync(candidate)
13
+ if (stat.isFile()) {
14
+ files.push(candidate)
15
+ }
16
+ } catch {
17
+ // no about.toml in this subfolder — ignore
18
+ }
19
+ }
20
+ }
21
+ return files
22
+ }
23
+
24
+ function parseTOML(filePath) {
25
+ const text = fs.readFileSync(filePath, "utf8")
26
+ try {
27
+ return TOML.parse(text)
28
+ } catch (error) {
29
+ const rel = path.relative(process.cwd(), filePath)
30
+ throw new Error(`Failed to parse TOML at ${rel}: ${error.message}`)
31
+ }
32
+ }
33
+
34
+ function readConfig(dir) {
35
+ const scanners = []
36
+ const files = enumerate(dir)
37
+ for (const file of files) {
38
+ const scanner = parseTOML(file)
39
+ scanners.push(scanner)
40
+ }
41
+ return { scanners }
42
+ }
43
+
44
+ const config = readConfig(path.join(__dirname, '..', '..', 'scanners'))
7
45
  const categories = Array.from(new Set(config.scanners.flatMap(scanner => scanner.categories)))
8
46
 
9
47
  module.exports = {
@@ -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).aud
12
+ this.#EWA_URL = this.#claims(this.#EUREKA_AGENT_TOKEN)?.aud?.replace(/\/$/, '')
13
13
  }
14
14
 
15
15
  async send(path, params, body, token) {
@@ -80,17 +80,19 @@ class Telemetry {
80
80
 
81
81
  #toPostURL(path, params, token) {
82
82
  const claims = this.#claims(token ?? this.#EUREKA_AGENT_TOKEN)
83
- if (path === `scans/started`) return `${claims.aud}/scans/started`
84
- if (path === `scans/:scanID/completed`) return `${claims.aud}/scans/${params.scanID}/completed`
85
- if (path === `scans/:scanID/failed`) return `${claims.aud}/scans/${params.scanID}/completed`
86
- if (path === `scans/:scanID/metadata`) return `${claims.aud}/scans/${params.scanID}/metadata`
87
- if (path === `scans/:scanID/results`) return `${claims.aud}/scans/${params.scanID}/results`
83
+ const aud = claims.aud.replace(/\/$/, '')
84
+ if (path === `scans/started`) return `${aud}/scans/started`
85
+ if (path === `scans/:scanID/completed`) return `${aud}/scans/${params.scanID}/completed`
86
+ if (path === `scans/:scanID/failed`) return `${aud}/scans/${params.scanID}/completed`
87
+ if (path === `scans/:scanID/metadata`) return `${aud}/scans/${params.scanID}/metadata`
88
+ if (path === `scans/:scanID/results`) return `${aud}/scans/${params.scanID}/results`
88
89
  throw new Error(`Internal Error: Unknown telemetry event: POST ${path}`)
89
90
  }
90
91
 
91
92
  #toReceiveURL(path, params, token) {
92
93
  const claims = this.#claims(token ?? this.#EUREKA_AGENT_TOKEN)
93
- if (path === `scans/:scanID/summary`) return `${claims.aud}/scans/${params.scanID}/summary?profileId=${process.env.EUREKA_PROFILE}`
94
+ const aud = claims.aud.replace(/\/$/, '')
95
+ if (path === `scans/:scanID/summary`) return `${aud}/scans/${params.scanID}/summary?profileId=${process.env.EUREKA_PROFILE}`
94
96
  throw new Error(`Internal Error: Unknown telemetry event: GET ${path}`)
95
97
  }
96
98
 
@@ -20,14 +20,16 @@ module.exports = (sarif, dir) => {
20
20
  continue
21
21
  }
22
22
 
23
- for (const rule of run.tool.driver.rules) {
24
- if (rule.id === result.ruleId) {
25
- const level = rule?.defaultConfiguration?.level ?? 'error'
26
- if (level === 'error' || level === 'warning' || level === 'note') {
27
- finding.level = level
28
- summary[`${finding.level}s`].push(finding)
23
+ if (Array.isArray(run?.tool?.driver?.rules)) {
24
+ for (const rule of run.tool.driver.rules) {
25
+ if (rule.id === result.ruleId) {
26
+ const level = rule?.defaultConfiguration?.level ?? 'error'
27
+ if (level === 'error' || level === 'warning' || level === 'note') {
28
+ finding.level = level
29
+ summary[`${finding.level}s`].push(finding)
30
+ }
31
+ break
29
32
  }
30
- break
31
33
  }
32
34
  }
33
35
  }
@@ -8,12 +8,14 @@ module.exports = (sarif, escalations) => {
8
8
  continue
9
9
  }
10
10
 
11
- for (const rule of run.tool.driver.rules) {
12
- if (rule.id === result.ruleId) {
13
- if (escalations.includes(rule.defaultConfiguration?.level)) {
14
- rule.defaultConfiguration.level = 'error'
11
+ if (Array.isArray(run?.tool?.driver?.rules)) {
12
+ for (const rule of run.tool.driver.rules) {
13
+ if (rule.id === result.ruleId) {
14
+ if (escalations.includes(rule.defaultConfiguration?.level)) {
15
+ rule.defaultConfiguration.level = 'error'
16
+ }
17
+ break
15
18
  }
16
- break
17
19
  }
18
20
  }
19
21
  }
@@ -41,9 +41,11 @@ module.exports = async (outfile, files) => {
41
41
  rules.set(result.ruleId, true)
42
42
  }
43
43
 
44
- for (const rule of run.tool.driver.rules) {
45
- if (rules.has(rule.id)) {
46
- tool.driver.rules.push(rule)
44
+ if (Array.isArray(run?.tool?.driver?.rules)) {
45
+ for (const rule of run.tool.driver.rules) {
46
+ if (rules.has(rule.id)) {
47
+ tool.driver.rules.push(rule)
48
+ }
47
49
  }
48
50
  }
49
51
 
@@ -10,9 +10,14 @@ module.exports = (sarif, dir) => {
10
10
 
11
11
  // Make all physical locations for the result relative to the scan directory.
12
12
  for (const location of result.locations) {
13
- if (!location.physicalLocation?.artifactLocation?.uri?.startsWith('/app')) continue
14
- let file = path.relative('/app', location.physicalLocation.artifactLocation.uri)
15
- location.physicalLocation.artifactLocation.uri = file
13
+ if (location.physicalLocation?.artifactLocation?.uri?.startsWith('/app')) {
14
+ let file = path.relative('/app', location.physicalLocation.artifactLocation.uri)
15
+ location.physicalLocation.artifactLocation.uri = file
16
+ }
17
+ else if (location.physicalLocation?.artifactLocation?.uri?.startsWith('/')) {
18
+ let file = path.relative('/', location.physicalLocation.artifactLocation.uri)
19
+ location.physicalLocation.artifactLocation.uri = file
20
+ }
16
21
  }
17
22
 
18
23
  }
@@ -1 +0,0 @@
1
- {"id": "CVE-2022-33987", "package": "npm:got", "purl": "pkg:npm/got@9.6.0", "package_type": "npm", "package_usage": "optional", "version": "9.6.0", "fix_version": "11.8.5", "severity": "MEDIUM", "cvss_score": "5.3", "short_description": "# Got allows a redirect to a UNIX socket\nThe got package before 11.8.5 and 12.1.0 for Node.js allows a redirect to a UNIX socket.\nUpgrade to version 11.8.5 or later", "related_urls": [], "occurrence_count": 0, "reachable_flows": 0}
@@ -1,31 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="UTF-8">
5
- <style>
6
- .r1 {font-style: italic}
7
- .r2 {color: #800080; text-decoration-color: #800080; font-weight: bold}
8
- .r3 {color: #7c8082; text-decoration-color: #7c8082; font-style: italic}
9
- .r4 {color: #00875f; text-decoration-color: #00875f}
10
- .r6 {color: #ff753d; text-decoration-color: #ff753d; font-weight: bold}
11
- body {
12
- color: #000000;
13
- background-color: #ffffff;
14
- }
15
- </style>
16
- </head>
17
- <body>
18
- <pre style="font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><code style="font-family:inherit">
19
- <span class="r1"> Dependency Scan Results (UNIVERSAL) </span>
20
- ╔══════════════════════════════════════════════════════╤════════════════════════════════════════╤══════════════════════╤═════════════════╤═══════════╗
21
- ║<span class="r2"> Dependency Tree </span>│<span class="r2"> Insights </span>│<span class="r2"> Fix Version </span>│<span class="r2"> Severity </span>│<span class="r2"> Score </span>║
22
- ╟──────────────────────────────────────────────────────┼────────────────────────────────────────┼──────────────────────┼─────────────────┼───────────╢
23
- ║ <span class="r3">package-json@6.5.0 </span> │ <span class="r4">📓 Indirect dependency</span> │ 11.8.5 │ MEDIUM │ 5.3 ║
24
- ║ <span class="r5">└── </span><span class="r6">got@9.6.0 ⬅ CVE-2022-33987 </span> │ │ │ │ ║
25
- ╚══════════════════════════════════════════════════════╧════════════════════════════════════════╧══════════════════════╧═════════════════╧═══════════╝
26
- ╭─────────────────────────────────────────────────────────── Recommendation ───────────────────────────────────────────────────────────╮
27
- │ ✅ No package requires immediate attention since the major vulnerabilities are found only in dev packages and indirect dependencies. │
28
- ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
29
- </code></pre>
30
- </body>
31
- </html>
@@ -1,70 +0,0 @@
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": "owasp-depscan",
9
- "semanticVersion": "5.5.0",
10
- "informationUri": "https://github.com/owasp-dep-scan/dep-scan",
11
- "properties": {
12
- "protocol_version": "v1.0.0",
13
- "scanner_name": "owasp-depscan",
14
- "scanner_version": "5.5.0",
15
- "db": "https://github.com/AppThreat/vulnerability-db",
16
- "scan_mode": "source"
17
- },
18
- "rules": [
19
- {
20
- "id": "CVE-2022-33987/pkg:npm/got@9.6.0",
21
- "shortDescription": {
22
- "text": "Vulnerable pkg: npm/got@9.6.0\nCVE: CVE-2022-33987\nFix: Update to 11.8.5 or later\n\ndepscan:insights: Indirect dependency\ndepscan:prioritized: false\naffectedVersionRange: got@<11.8.5\n"
23
- },
24
- "fullDescription": {
25
- "text": "# Got allows a redirect to a UNIX socket\nThe got package before 11.8.5 and 12.1.0 for Node.js allows a redirect to a UNIX socket.\nUpgrade to version 11.8.5 or later"
26
- },
27
- "help": {
28
- "text": "Update to 11.8.5 or later"
29
- },
30
- "helpUri": "https://nvd.nist.gov/vuln/detail/CVE-2022-33987",
31
- "properties": {
32
- "tags": [
33
- "CVE-2022-33987"
34
- ]
35
- }
36
- }
37
-
38
- ]
39
- }
40
- },
41
- "results": [
42
- {
43
- "ruleId": "CVE-2022-33987/pkg:npm/got@9.6.0",
44
- "level": "warning",
45
- "message": {
46
- "text": "Vulnerability CVE-2022-33987 in pkg npm/got@9.6.0. Update to 11.8.5 or later"
47
- },
48
- "locations": [
49
- {
50
- "physicalLocation": {
51
- "artifactLocation": {
52
- "uri": "package-lock.json",
53
- "uriBaseId": "%SRCROOT%"
54
- },
55
- "region": {
56
- "startLine": 1
57
- }
58
- },
59
- "message": {
60
- "text": "Vulnerability CVE-2022-33987 in pkg npm/got@9.6.0. Update to 11.8.5 or later"
61
- }
62
- }
63
- ]
64
- }
65
-
66
-
67
- ]
68
- }
69
- ]
70
- }