Follow-up from the TOFU CA-pinning change (#1027 / PR #1028).
Context
CA pinning means the stored trust anchor is now a CA rather than a single leaf. Two endpoints can write/clear that anchor:
POST /api/signalk/reset-tofu — clears the stored anchor (next connect re-captures).
PUT /api/config — from_json applies tofu_ca_pem / tofu_fingerprint directly and saves, so a config write can set the anchor with no handshake.
Both ride the device's general HTTP auth (HTTPServer::auth_required_). This is working as designed: with an access password set, they're protected like every other endpoint. The only exposure is that auth is off by default, which leaves the entire HTTP surface open — not anything TOFU-specific. So this is not a new vulnerability introduced by CA pinning.
Why it's still worth a look
CA pinning raises the impact of an unauthorized anchor write: a planted CA is trusted to mint arbitrary leaves for that identity indefinitely, whereas the old leaf pin re-trusted one cert for one connection. So in the (default) auth-off posture, an attacker who can already reach the device's HTTP API gets a more durable foothold than before — even though they could already do plenty with the API open.
Options to consider (none blocking)
- Require auth for the anchor-writing paths (
reset-tofu, and the anchor fields in config) even when general auth is off — i.e. treat trust-anchor changes as privileged regardless of the global default.
- Distinguish trusted on-disk config load from untrusted
PUT /api/config so externally-supplied anchor fields are ignored (the only writers become handshake-capture and disk-load). This is the cleaner fix but touches the shared config/saveable load path, not just TOFU.
- Guide (or default) SSL deployments toward enabling auth, since TLS pinning's value is undercut if the device's own API is open.
Not a gate on PR #1028 — the auth model already provides the mitigation (set a password).
Follow-up from the TOFU CA-pinning change (#1027 / PR #1028).
Context
CA pinning means the stored trust anchor is now a CA rather than a single leaf. Two endpoints can write/clear that anchor:
POST /api/signalk/reset-tofu— clears the stored anchor (next connect re-captures).PUT /api/config—from_jsonappliestofu_ca_pem/tofu_fingerprintdirectly and saves, so a config write can set the anchor with no handshake.Both ride the device's general HTTP auth (
HTTPServer::auth_required_). This is working as designed: with an access password set, they're protected like every other endpoint. The only exposure is that auth is off by default, which leaves the entire HTTP surface open — not anything TOFU-specific. So this is not a new vulnerability introduced by CA pinning.Why it's still worth a look
CA pinning raises the impact of an unauthorized anchor write: a planted CA is trusted to mint arbitrary leaves for that identity indefinitely, whereas the old leaf pin re-trusted one cert for one connection. So in the (default) auth-off posture, an attacker who can already reach the device's HTTP API gets a more durable foothold than before — even though they could already do plenty with the API open.
Options to consider (none blocking)
reset-tofu, and the anchor fields in config) even when general auth is off — i.e. treat trust-anchor changes as privileged regardless of the global default.PUT /api/configso externally-supplied anchor fields are ignored (the only writers become handshake-capture and disk-load). This is the cleaner fix but touches the shared config/saveable load path, not just TOFU.Not a gate on PR #1028 — the auth model already provides the mitigation (set a password).