Skip to content

🐛 fix(scripts): make security-testssl.sh complete a scan end-to-end#66

Merged
s-b-e-n-s-o-n merged 2 commits into
mainfrom
fix/testssl-listen-config-keys
May 21, 2026
Merged

🐛 fix(scripts): make security-testssl.sh complete a scan end-to-end#66
s-b-e-n-s-o-n merged 2 commits into
mainfrom
fix/testssl-listen-config-keys

Conversation

@s-b-e-n-s-o-n
Copy link
Copy Markdown
Contributor

Summary

The 🔒 Security: testssl.sh (sockguard TLS posture) job in security-grype-weekly.yml has failed on every weekly run since the script was added — it never completed a single scan. This PR fixes six independent defects so the DAST check actually works.

Defects fixed

# Bug Fix
1 Config used listen.tcp: — no such key; the struct field is listen.address:. mapstructure silently dropped it, so sockguard opened no TCP listener. tcpaddress (commit faa501c)
2 drwetter/testssl.sh runs as non-root (uid 1000); it could not write its JSON report into the mode-0700 mktemp work dir. Dedicated 0777 output subdir, bind-mount only that (also keeps the CA/server private keys out of the container)
3 jq severity gate parsed --jsonfile-pretty (a nested object) as a flat array. Switch to --jsonfile (flat array of finding objects)
4 The gate failed on every run: the ephemeral self-signed test cert always trips cert_chain_of_trust / cert_expirationStatus / cert_notAfter / cert_revocation as HIGH/CRITICAL. Exclude cert_* finding ids — the check measures sockguard's wire posture, not the fixture cert's PKI
5 jq was not in the toolchain sanity-check despite the gate depending on it. Added
6 --dry-run described a testssl exit-code gate the script never used. Corrected the plan text

Also gitignores the testssl-output.{json,txt} files the script copies to the repo root for local triage.

Verification

Ran end-to-end inside a real Linux Docker environment (the macOS/colima host cannot faithfully reproduce --network=host + bind-mount permissions). The full testssl.sh scan completes and the script exits 0 with zero wire-posture HIGH/CRITICAL findings — sockguard negotiates TLS 1.3 only, modern AEAD suites, and X25519MLKEM768 post-quantum key exchange (testssl Grade B, capped only by the self-signed test chain).

--dry-run and the security-testssl.test.mjs seam (4/4) both pass.

…estssl config

The generated sockguard YAML used `listen.tcp` which does not exist in
ListenConfig (mapstructure tag is `address`). Viper/mapstructure silently
drops unknown keys, so sockguard started with no TCP listener and never
opened 127.0.0.1:18443, breaking the weekly QA-4 TLS posture CI job since
2026-05-18.

Stale key:  listen.tcp   →   correct key: listen.address
No other keys in the generated config were stale.

A loopback 127.0.0.1 address with full TLS (cert_file + key_file +
client_ca_file) passes config validation without any insecure_allow_*
flags — the plainTCPListenerErrors guard only fires for non-loopback
addresses.
The testssl.sh DAST job has failed on every weekly security run since the
script was added — it never finished a single scan. Beyond the stale
listen.tcp key fixed in faa501c, five further defects blocked it:

- 🐛 The drwetter/testssl.sh container runs as non-root (uid 1000) and
  could not write its JSON report into the mode-0700 mktemp work dir.
  Give it a dedicated 0777 output subdirectory and bind-mount only that,
  which also keeps the CA / server private keys out of the container.
- 🐛 The jq severity gate parsed --jsonfile-pretty output (a nested
  object) as a flat array. Switch to --jsonfile, whose top-level array of
  finding objects is what the gate indexes.
- 🐛 The gate failed on every run because the ephemeral self-signed test
  certificate always trips cert_chain_of_trust / cert_expirationStatus /
  cert_notAfter / cert_revocation as HIGH/CRITICAL. Exclude cert_* finding
  ids — this check measures sockguard's wire posture, not the fixture
  cert's PKI properties.
- 🔧 Add jq to the toolchain sanity-check; the gate depends on it.
- 📝 Correct the --dry-run "fail conditions" line, which described a
  testssl exit-code gate the script never used.

Also gitignore the testssl-output.{json,txt} files the script copies to
the repo root for local triage.

Verified end-to-end in a Linux Docker environment: the full scan
completes and the script exits 0 with zero wire-posture HIGH/CRITICAL
findings (sockguard negotiates TLS 1.3 only, modern AEAD suites, and
X25519MLKEM768 PQ key exchange — testssl Grade B, capped only by the
self-signed test chain).
@vercel
Copy link
Copy Markdown

vercel Bot commented May 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sockguard-website Ready Ready Preview, Comment May 21, 2026 3:15pm

Copy link
Copy Markdown
Member

@biggest-littlest biggest-littlest left a comment

Choose a reason for hiding this comment

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

testssl.sh DAST script fix — verified end-to-end in a real Linux Docker environment, scan completes and exits 0. Shell-only change, no Go code touched.

@s-b-e-n-s-o-n s-b-e-n-s-o-n merged commit 4bd6f3b into main May 21, 2026
66 of 67 checks passed
@s-b-e-n-s-o-n s-b-e-n-s-o-n deleted the fix/testssl-listen-config-keys branch May 21, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants