CNPG pool sets sslmode=disable when TLS config is present but SSLMode unset, resulting in unencrypted connections #681
Labels
No labels
1week
2weeks
Failed compliance check
IP cameras
NATS
Possible security concern
Review effort 1/5
Review effort 2/5
Review effort 3/5
Review effort 4/5
Review effort 5/5
UI
aardvark
accessibility
amd64
api
arm64
auth
back-end
bgp
blog
bug
build
checkers
ci-cd
cleanup
cnpg
codex
core
dependencies
device-management
documentation
duplicate
dusk
ebpf
enhancement
eta 1d
eta 1hr
eta 3d
eta 3hr
feature
fieldsurvey
github_actions
go
good first issue
help wanted
invalid
javascript
k8s
log-collector
mapper
mtr
needs-triage
netflow
network-sweep
observability
oracle
otel
plug-in
proton
python
question
reddit
redhat
research
rperf
rperf-checker
rust
sdk
security
serviceradar-agent
serviceradar-agent-gateway
serviceradar-web
serviceradar-web-ng
siem
snmp
sysmon
topology
ubiquiti
wasm
wontfix
zen-engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
carverauto/serviceradar#681
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Imported from GitHub.
Original GitHub issue: #2143
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/issues/2143
Original created: 2025-12-16T05:15:41Z
Summary
NewCNPGPoolinpkg/db/cnpg_pool.gocreates a pgx connection pool for connecting to CloudNativePG/Timescale databases, handling both the connection URL configuration and optional TLS setup.SSLModeis not explicitly set, the function defaultssslmodeto"disable", which instructs PostgreSQL to completely disable SSL/TLS encryption.sslmode=disableeven when a complete TLS configuration (certificates, keys, CA) is provided, causing the TLS configuration to be ignored; the expected behavior is that when TLS configuration is provided, an appropriate SSL mode like"require","verify-ca", or"verify-full"should be used.Code with bug
Later in the same function:
Evidence
Example
Consider a configuration where a user provides TLS certificates to connect to a CNPG cluster:
Step-by-step execution:
cfg.SSLModeis empty string,sslModeis set to"disable"sslmode=disablepostgres://app_user:secret@cnpg-rw.serviceradar:5432/serviceradar?sslmode=disablepoolConfig.ConnConfig.TLSConfigsslmode=disablein the connection string AND a TLS config object. According to PostgreSQL/pgx behavior,sslmode=disabletakes precedence, meaning the connection will NOT be encrypted despite having valid TLS certificates configured.Inconsistency with codebase
Reference code
From
openspec/changes/add-mtls-only-edge-onboarding/design.md:28:From
openspec/changes/update-helm-demo-chart/tasks.md:36:Current code
pkg/db/cnpg_pool.go:63-67Contradiction
The documentation explicitly states that CNPG connections use TLS and that clients should use
sslmode=verify-full. However, the code defaults tosslmode=disablewhen no explicit SSL mode is provided. This creates a situation where:SSLModefield will have their connections silently downgraded to unencryptedsslmode=disabletells the driver to skip SSL entirelyFailing test
Test script
Test output
Full context
The
NewCNPGPoolfunction is called during database initialization by several components:Core service (
pkg/db/db.go:73): The main application callsnewCNPGPoolduring startup to establish the primary database connection pool used for all telemetry data, device updates, and service registry operations.Migration tool (
cmd/tools/cnpg-migrate/main.go:127): Thecnpg-migrateCLI tool callsNewCNPGPoolto connect to the database and apply schema migrations.DB event writer: As referenced in the documentation, the db-event-writer service connects to CNPG to ingest OTEL logs, metrics, and traces.
The CNPG cluster is the primary system of record for ServiceRadar, storing:
The codebase is designed to operate in production environments with SPIFFE mTLS enabled and TLS connections to the database. The compose-based deployments and Kubernetes/Helm configurations all provision TLS certificates for CNPG connections. Users following the documented deployment patterns would naturally provide TLS configuration without explicitly setting the
SSLModefield, as the presence of certificates would imply that TLS should be used.External documentation
Why has this bug gone undetected?
This bug has gone undetected for several reasons:
Workaround in deployment configurations: Most deployments explicitly set the
SSLModefield to"require","verify-ca", or"verify-full"in their configuration files, which bypasses the buggy default. The documentation references (like "compose clients default tosslmode=verify-full") suggest that configurations are explicitly setting this value.Local development with SSL disabled: Developers testing locally may run CNPG without TLS (using the default
sslmode=disable), so they never configure TLS certificates and therefore never encounter the conflicting configuration scenario.Silent failure mode: When
sslmode=disableis set, the connection succeeds but is simply unencrypted. There's no error message or warning indicating that the TLS configuration was ignored. The application functions normally, just without the expected encryption.Recent TLS adoption: Based on the git history and documentation references, TLS support for CNPG appears to be a relatively recent addition (references in "add-mtls-only-edge-onboarding" and related changes). The default to
"disable"may have been established before TLS configuration was fully implemented.Testing gap: There are no tests for the
cnpg_pool.gofile, and the integration tests that use CNPG either explicitly setSSLModeor run without TLS entirely.Configuration validation gap: The code doesn't validate the relationship between
TLSconfiguration andSSLMode. It accepts both being set in conflicting ways without warning.Recommended fix
The function should check if TLS configuration is provided and automatically use an appropriate SSL mode if none is explicitly set:
Alternatively, for a more conservative fix that maintains stricter backward compatibility:
The first approach (
"verify-full") is recommended because:sslmode=verify-full"Imported GitHub comment.
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/issues/2143#issuecomment-3663542651
Original created: 2025-12-17T04:04:35Z
closing as completed