# QA Security Audit Report — CWE-614 Remediation **Date:** 2026-03-21 **Scope:** `backend/internal/api/handlers/auth_handler.go` — removal of `secure = false` branch from `setSecureCookie` **Audited by:** QA Security Agent --- ## Scope Backend-only change. File audited: | File | Change Type | |------|-------------| | `backend/internal/api/handlers/auth_handler.go` | Modified — `secure = false` branch removed; `Secure` always `true` | | `backend/internal/api/handlers/auth_handler_test.go` | Modified — all `TestSetSecureCookie_*` assertions updated to `assert.True(t, cookie.Secure)` | --- ## 1. Test Results | Metric | Value | Gate | Status | |---|---|---|---| | Statement coverage | 88.0% | ≥ 87% | ✅ PASS | | Line coverage | 88.2% | ≥ 87% | ✅ PASS | | Test failures | 0 | 0 | ✅ PASS | All `TestSetSecureCookie_*` variants assert `cookie.Secure == true` unconditionally, correctly reflecting the remediated behaviour. --- ## 2. Lint Results **Tool:** `golangci-lint` (fast config — staticcheck, govet, errcheck, ineffassign, unused) **Result:** `0 issues` — ✅ PASS --- ## 3. Pre-commit Hooks **Tool:** Lefthook v2.1.4 | Hook | Result | |---|---| | check-yaml | ✅ PASS | | actionlint | ✅ PASS | | end-of-file-fixer | ✅ PASS | | trailing-whitespace | ✅ PASS | | dockerfile-check | ✅ PASS | | shellcheck | ✅ PASS | Go-specific hooks (`go-vet`, `golangci-lint-fast`) were skipped — no staged files. These were validated directly via `make lint-fast`. --- ## 4. Trivy Security Scan **Tool:** Trivy v0.52.2 ### New Vulnerabilities Introduced by This Change **None.** Zero HIGH or CRITICAL vulnerabilities attributable to the CWE-614 remediation. ### Pre-existing Baseline Finding (unrelated) | ID | Severity | Type | Description | |---|---|---|---| | DS002 | HIGH | Dockerfile misconfiguration | Container runs as root — pre-existing, not introduced by this change | --- ## 5. CWE-614 Verification ### Pattern Search: `secure = false` in handlers package ``` grep -rn "secure = false" /projects/Charon/backend/ ``` **Result:** 0 matches — ✅ CLEARED ### Pattern Search: Inline CodeQL suppression ``` grep -rn "codeql[go/cookie-secure-not-set]" /projects/Charon/backend/ ``` **Result:** 0 matches — ✅ CLEARED ### `setSecureCookie` Implementation The function unconditionally passes `true` as the `secure` argument to `c.SetCookie`: ```go c.SetCookie( name, // name value, // value maxAge, // maxAge in seconds "/", // path domain, // domain (empty = current host) true, // secure ← always true, no conditional branch true, // httpOnly ) ``` All test cases (`TestSetSecureCookie_HTTPS_Strict`, `_HTTP_Lax`, `_HTTP_Loopback_Insecure`, `_ForwardedHTTPS_*`, `_HTTP_PrivateIP_Insecure`, `_HTTP_10Network_Insecure`, `_HTTP_172Network_Insecure`) assert `cookie.Secure == true`. --- ## Summary | Check | Result | Notes | |---|---|---| | Backend unit tests | ✅ PASS | 0 failures, 88.0% coverage (gate: 87%) | | Lint | ✅ PASS | 0 issues | | Pre-commit hooks | ✅ PASS | All 6 active hooks passed | | Trivy | ✅ PASS | No new HIGH/CRITICAL vulns | | `secure = false` removed | ✅ CLEARED | 0 matches in handlers package | | CodeQL suppression removed | ✅ CLEARED | 0 matches in handlers package | --- ## Overall: ✅ PASS The CWE-614 remediation is complete and correct. All cookies set by `setSecureCookie` now unconditionally carry `Secure = true`. No regressions, no new security findings, and coverage remains above the required threshold. --- # QA Audit Report — PR-1: Allow Empty Value in UpdateSetting **Date:** 2026-03-17 **Scope:** Remove `binding:"required"` from `Value` field in `UpdateSettingRequest` **File:** `backend/internal/api/handlers/settings_handler.go` --- # QA Security Audit Report — Rate Limit CI Fix **Audited by**: QA Security Auditor **Date**: 2026-03-17 **Spec reference**: `docs/plans/rate_limit_ci_fix_spec.md` **Files audited**: - `scripts/rate_limit_integration.sh` - `Dockerfile` (GeoIP section, non-CI path) - `.github/workflows/rate-limit-integration.yml` --- ## Pre-Commit Check Results | Check | Command | Result | |-------|---------|--------| | Bash syntax | `bash -n scripts/rate_limit_integration.sh` | ✅ PASS (exit 0) | | Pre-commit hooks | `lefthook run pre-commit` (project uses lefthook; no `.pre-commit-config.yaml`) | ✅ PASS — all 6 hooks passed: `check-yaml`, `actionlint`, `end-of-file-fixer`, `trailing-whitespace`, `dockerfile-check`, `shellcheck` | | Caddy admin API trailing slash (workflow) | `grep -n "2119" .github/workflows/rate-limit-integration.yml` | ✅ PASS — line 71 references `/config/` (trailing slash present) | | Caddy admin API trailing slash (script) | All 6 occurrences of `localhost:2119/config` in script | ✅ PASS — all use `/config/` | --- ## Security Focus Area Results ### 1. Credential Handling — `TMP_COOKIE` **`mktemp` usage**: `TMP_COOKIE=$(mktemp)` at line 208. Creates a file in `/tmp` with `600` permissions via the OS. ✅ SECURE. **Removal on exit**: The `cleanup()` function at line 103 removes the file with `rm -f "${TMP_COOKIE:-}"`. However, `cleanup` is only registered via explicit calls — there is **no `trap cleanup EXIT`**. Only `trap on_failure ERR` is registered (line 108). **Gap**: On 5 early `exit 1` paths after line 208 (login failure L220, auth failure L251, Caddy readiness failure L282, security config failure L299, and handler verification failure L316), `cleanup` is never called. The cookie file is left in `/tmp`. **Severity**: LOW — The cookie contains session credentials for a localhost test server (`ratelimit@example.local` / `password123`, non-production). CI runners are ephemeral and auto-cleaned. Local runs will leave a `/tmp/tmp.XXXXXX` file until next reboot or manual cleanup. **Note**: The exit at line 386 (inside the 429 enforcement failure block) intentionally skips cleanup to leave containers running for manual inspection. This is by design and acceptable. **Recommendation**: Add `trap cleanup EXIT` immediately after `trap on_failure ERR` (line 109) to ensure the cookie file is always removed. --- ### 2. `curl` — Sensitive Values in Command-Line Arguments Cookie file path is passed via `-c ${TMP_COOKIE}` and `-b ${TMP_COOKIE}` (unquoted). No credentials, tokens, or API keys are passed as command-line arguments. All authentication is via the cookie file (read/write by path), which is the correct pattern — cookie values never appear in `ps` output. **Finding (LOW)**: `${TMP_COOKIE}` is unquoted in all 6 curl invocations. `mktemp` on Linux produces paths of the form `/tmp/tmp.XXXXXX` which never contain spaces or shell metacharacters under default `$TMPDIR`. However, under a non-standard `$TMPDIR` (e.g., `/tmp/my dir/`) this would break. This is a portability issue, not a security issue. **Recommendation**: Quote `"${TMP_COOKIE}"` in all curl invocations. --- ### 3. Shell Injection All interpolated values in curl `-d` payloads are either: - Script-level constants (`RATE_LIMIT_REQUESTS=3`, `RATE_LIMIT_WINDOW_SEC=10`, `RATE_LIMIT_BURST=1`, `TEST_DOMAIN=ratelimit.local`, `BACKEND_CONTAINER=ratelimit-backend`) - Values derived from API responses stored in double-quoted variables (`"$CREATE_RESP"`, `"$SEC_CONFIG_RESP"`) No shell injection vector exists. All heredoc expansions (`cat < sbom-generated.json`. ### Delete or Gitignore `.trivy_logs/charon_binary` The 23MB stale binary `.trivy_logs/charon_binary` (go1.25.4, Nov 2025) is a Trivy scan artifact causing several Critical/High CVE findings. Add `.trivy_logs/*.binary` or the whole `.trivy_logs/` directory to `.gitignore`. --- ## 5. Summary | # | Finding | Severity | False Positive? | Action Required | |---|---|---|---|---| | 1 | CVE-2025-68121 in `.trivy_logs/charon_binary` + `backend/bin/*` | **Critical** | No | Rebuild binaries with go1.26.1; delete stale `.trivy_logs/charon_binary` | | 2 | CVE-2026-33186 in Charon source | — | N/A | **Already fixed** (v1.79.3) | | 3 | CVE-2026-33186 in CrowdSec/Caddy binaries | High | Yes (for Charon) | Upgrade CrowdSec and Caddy Docker image tags | | 4 | GHSA-479m-364c-43vc (`goxmldsig`) | Medium | **Yes** | Upgrade Caddy Docker image | | 5 | GHSA-6g7g-w4f8-9c9x (`jsonparser`) | Medium | **Yes** | Upgrade CrowdSec Docker image | | 6 | GHSA-jqcq-xjh3-6g23 (`pgproto3/v2`) | Medium | **Yes** | Upgrade CrowdSec Docker image | | 7 | High stdlib CVEs in `backend/bin/` binaries | High | No | Rebuild with go1.26.1 | | 8 | Python venv packages | Medium | No (dev only) | `pip upgrade` in local envs | | 9 | Module cache false positives | Critical–High | **Yes** | Exclude `.cache/` from `grype dir:.` | | 10 | Stale `sbom-generated.json` | — | Yes | Delete or regenerate |