Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions .security/blackshield-audit-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# BlackShield Security Audit Report β€” `Calnode/calnode`

- **Scanned Commit:** `b76ac1a3a9ff11b4c24c9817f132d521f989845f`
- **Actionable Findings:** `24` (`0 Critical`, `24 High`, `35 Medium`, `1 Low`)
- **BlackShield Platform & Continuous Zero-Cost PR Protection:** [https://blackshield.chaplau.com](https://blackshield.chaplau.com)

## Detailed Findings & Remediation Guide

### 1. [HIGH] `CKV_DOCKER_1` β€” CKV_DOCKER_1: Container Runs as Root (Missing Non-Root USER)

- **Category:** `misconfiguration`
- **Location:** `Dockerfile:1`
- **Details:** Container does not specify a non-root USER, allowing processes to execute with root privileges.
- **Recommended Fix:** Add 'USER <non-root-uid>' instruction before container entrypoint.
Comment on lines +9 to +14

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the one finding with a real basis, but the recommended fix is incomplete: entrypoint.sh does mkdir -p /data at runtime and the process writes $DATABASE_URL=sqlite:///data/calnode.db, so adding USER without chowning /data makes the container fail to start. Worth tracking as an issue against the Dockerfile with that constraint in hand.

Technical details
# Run the app container as non-root

## Affected sites
- `Dockerfile:74-92` β€” final alpine stage, no `USER`, `ENTRYPOINT ["/entrypoint.sh"]`
- `entrypoint.sh:4` β€” `mkdir -p /data`
- `entrypoint.sh:11,20` β€” Litestream restores into and replicates `/data/calnode.db`
- `litestream.yml` β€” path must stay writable by the runtime user

## Required outcome
- A non-root runtime user that can read/write `/data` (and the Litestream config), with the entrypoint still able to create `/data` when the volume is absent.

## Suggested approach (optional)
- Create a system user in the runtime stage, `chown /data` and any created paths at entrypoint start (running as root briefly, then `exec` under the user via `su-exec`/`gosu`), or document that the platform must mount the volume with the target uid/gid.


### 2. [HIGH] `sec-path-traversal` β€” sec-path-traversal: Path Traversal / Arbitrary File Access

- **Category:** `sast`
- **Location:** `frontend/embed.go:19`
- **Details:** Accessing filesystem paths constructed from unvalidated input allows path traversal. at frontend/embed.go:19
- **Recommended Fix:** Sanitize user-provided file paths with filepath.Clean or secure_filename before reading.
Comment on lines +16 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive: frontend/embed.go:19 is the http.HandlerFunc line of FaviconHandler; the only path it opens is the compile-time constant build/favicon.svg from embed.FS. The SPA handler does open r.URL.Path, but from an embedded read-only FS, so there is no route to an arbitrary file.

Technical details
# `sec-path-traversal` at frontend/embed.go:19

## Affected sites
- `frontend/embed.go:19` β€” `http.HandlerFunc(func(w, r) {...})`, no path construction
- `frontend/embed.go:20` β€” `buildFS.Open("build/favicon.svg")` β€” constant
- `frontend/embed.go:48` β€” `h.fs.Open(r.URL.Path)` served by `http.FS(sub)` over `embed.FS`

## Required outcome
- Drop this finding from the report, or restate it as the (non-issue) observation that the SPA handler relies on `embed.FS` confinement.


### 3. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/embed.js:87`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/embed.js:87
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.
Comment on lines +23 to +28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All 20 sec-xss-raw-html entries share this problem and none is exploitable. Six cite lines that are not sinks at all β€” embed.js:214,237,701 and manage.html:443,471 are innerHTML = '' clears, and manage.html:549 is an event-handler line. Every remaining interpolation is an esc()-wrapped value, an Intl-formatted date/time/number, or a key from the compiled locales/*.json table; e.g. host names at book.html:341 pass through faceHTML's esc(), and the only admin-authored string reaching el({html}) is q.label, wrapped at embed.js:612.

Technical details
# `sec-xss-raw-html` cluster (20 findings)

## Affected sites
- `internal/handler/embed.js:214,237,701` β€” `this.wrap.innerHTML = ''`, no interpolation
- `internal/handler/templates/manage.html:443,471` β€” `list.innerHTML = ''`, no interpolation
- `internal/handler/templates/manage.html:549` β€” `$('reschedule-btn').addEventListener(...)`, not an HTML write
- `internal/handler/templates/book.html:341` β€” `faceHTML` escapes `avatar_url` and `name`
- `internal/handler/templates/book.html:348` β€” `defaultFacesHTML` captured from Go-escaped markup
- `book.html:524`, `manage.html:403` β€” calendar markup from numeric date parts and `Intl` day labels
- `book.html:581/596/627/638`, `manage.html:487/512/524/554` β€” `esc()`-wrapped or translation-table values
- `internal/handler/embed.js:87` β€” generic `el()` `html:` branch; call sites use `esc()`/`t()`/SVG constants

## Required outcome
- Drop these findings. If the scanner is to be used, its DOM-XSS rule needs taint tracking, not `innerHTML` token matching.

## Open questions for the human
- Are you relying on this report to prioritize work? These 20 entries would consume effort with no security gain.


### 4. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/embed.js:214`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/embed.js:214
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 5. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/embed.js:237`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/embed.js:237
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 6. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/embed.js:701`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/embed.js:701
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 7. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:341`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:341
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 8. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:348`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:348
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 9. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:524`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:524
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 10. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:581`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:581
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 11. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:596`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:596
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 12. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:627`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:627
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 13. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/book.html:638`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/book.html:638
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 14. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:403`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:403
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 15. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:443`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:443
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 16. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:471`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:471
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 17. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:487`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:487
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 18. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:512`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:512
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 19. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:524`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:524
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 20. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:554`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:554
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 21. [HIGH] `sec-xss-raw-html` β€” sec-xss-raw-html: Cross-Site Scripting (XSS) via Unsanitized HTML

- **Category:** `sast`
- **Location:** `internal/handler/templates/manage.html:549`
- **Details:** Rendering unescaped HTML directly in UI templates exposes web applications to script injection. at internal/handler/templates/manage.html:549
- **Recommended Fix:** Contextually encode output (htmlspecialchars, DOMPurify) and specify an explicit targetOrigin in postMessage.

### 22. [HIGH] `sec-path-traversal` β€” sec-path-traversal: Path Traversal / Arbitrary File Access

- **Category:** `sast`
- **Location:** `internal/i18n/i18n.go:56`
- **Details:** Accessing filesystem paths constructed from unvalidated input allows path traversal. at internal/i18n/i18n.go:56
- **Recommended Fix:** Sanitize user-provided file paths with filepath.Clean or secure_filename before reading.
Comment on lines +156 to +161

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive: internal/i18n/i18n.go:56 reads "locales/" + e.Name(), where e.Name() comes from localeFS.ReadDir("locales") during init(). Both the directory and the files are compile-time embedded entries; no request value reaches the path.


### 23. [HIGH] `py-ssrf-urllib-urlopen` β€” py-ssrf-urllib-urlopen: SSRF via urllib.request.urlopen

- **Category:** `sast`
- **Location:** `packaging/ns8/assert-multiarc.py:130`
- **Details:** Unvalidated user-controlled URLs in HTTP client requests cause SSRF. at packaging/ns8/assert-multiarc.py:130
- **Recommended Fix:** Validate target URLs against an explicit hostname allowlist and block private/loopback IP ranges.
Comment on lines +163 to +168

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive: packaging/ns8/assert-multiarc.py:130 builds its URL from the module constant REGISTRY = "https://ghcr.io" plus a repository passed on the command line to a release-check script, and normalize_repo strips any supplied host. There is no user-controlled request path here, let alone one that could target internal addresses.


### 24. [HIGH] `CKV_DOCKER_1` β€” CKV_DOCKER_1: Container Runs as Root (Missing Non-Root USER)

- **Category:** `misconfiguration`
- **Location:** `packaging/ns8/ui/Containerfile:1`
- **Details:** Container does not specify a non-root USER, allowing processes to execute with root privileges.
- **Recommended Fix:** Add 'USER <non-root-uid>' instruction before container entrypoint.
Comment on lines +170 to +175

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not actionable as written: NS8 module containers run under the platform's contract, and this image's ENTRYPOINT is ./container-entrypoint.sh, which sets up the module environment. Switching to a non-root USER is a change to the NS8 packaging contract, not a one-line Containerfile edit, and should be verified against that contract before being listed as HIGH.


Loading