You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Viewer: anchor a relative Root Certificate to darling.json's directory, not the process working directory #1970
Split out of #1953's security review rather than folded into PR #1968, because it changes Viewer behavior for every bring-your-own connection string, not just exported ones - that is a decision worth its own change.
The gap
ViewerSettings.Parse returns a BYO postgres.connectionStringverbatim (Darling/PerformanceMonitor.Darling.Viewer/ViewerSettings.cs:134-141), so Npgsql resolves a relative Root Certificate=server.crt against the Viewer process's working directory - which is not necessarily the folder holding darling.json and the certificate beside it. A desktop shortcut's "Start in", or launching from Explorer's last-used directory, silently changes the anchor.
That makes the working directory the trust anchor for a verify-full pin. If the Viewer is ever launched with a working directory an attacker can write (Downloads, a shared folder), a planted server.crt becomes the pinned root; combined with LAN position that is interception of the store session and the credential inside it.
--export-viewer-config (#1953) deliberately emits the relative name - the service host cannot know the viewer machine's absolute path - and documents the caveat and the absolute-path alternative in three places. So this is a sharp edge that is currently documented, not removed.
The fix
In ViewerSettings.TryLoad, when the parsed BYO connection string's Root Certificate is a relative path, rewrite it to Path.Combine(Path.GetDirectoryName(resolvedConfigPath)!, value). The Viewer already knows the config path it loaded, so "the certificate beside darling.json" becomes true regardless of working directory, the exported folder keeps working when copied anywhere, and an absolute path set by hand is left alone.
Also worth pinning while in there
What Npgsql 10 does when the configured RootCertificate file does not exist. The shipped assembly's metadata suggests an existence guard with a fall-through to the machine trust store, which would mean VerifyFull validating against public CAs instead of the pinned PEM. A self-signed store certificate would not chain to a public root, so the practical outcome is probably a connection failure - but "probably" is not the standard for a pinning control, and a test should settle it.
Shipped in #1977. A relative or bare Root Certificate now anchors to the directory of the darling.json the viewer actually read, not the process working directory - which was the trust anchor for a VerifyFull pin and changed with a shortcut's Start-in or Explorer's last-used folder. One pure resolver (ViewerCertificateAnchor) is the single implementation, consumed by both the connection-string rewrite and the #1954 startup diagnostics, with a structural test that fails if either ever computes its own answer. Absolute paths pass through as written, the keyword is never added to a string that lacked it, and there is deliberately no SSL Mode gate - anchoring under Require changes nothing Npgsql reads, while gating would leave a stale working-directory anchor for the operator who later tightens the mode. The exported folder now works unedited wherever it is copied: the export's README/JSON caveat telling operators to hand-edit a full path is gone, and the pinned doc tests now assert its absence. Verified against shipped Npgsql 10.0.3 by reflection that Root Certificate round-trips through the builder with only the certificate value changed.
Activity
Refuse the destinations that would have destroyed something
Lead with the placement that actually works, and pin the rest
Prove the exported folder resolves its certificate unedited (#1970)
Retouch the #1953 entry: the working-directory caveat is obsolete wit…
Guard Anchor's setter and re-serialization so the never-throws claim …
Anchor a relative Root Certificate to darling.json's directory (#1970)
Merge pull request #1977 from erikdarlingdata/fix/1970-cert-anchor
erikdarlingdata commentedon Aug 1, 2026
Shipped in #1977. A relative or bare Root Certificate now anchors to the directory of the darling.json the viewer actually read, not the process working directory - which was the trust anchor for a VerifyFull pin and changed with a shortcut's Start-in or Explorer's last-used folder. One pure resolver (ViewerCertificateAnchor) is the single implementation, consumed by both the connection-string rewrite and the #1954 startup diagnostics, with a structural test that fails if either ever computes its own answer. Absolute paths pass through as written, the keyword is never added to a string that lacked it, and there is deliberately no SSL Mode gate - anchoring under Require changes nothing Npgsql reads, while gating would leave a stale working-directory anchor for the operator who later tightens the mode. The exported folder now works unedited wherever it is copied: the export's README/JSON caveat telling operators to hand-edit a full path is gone, and the pinned doc tests now assert its absence. Verified against shipped Npgsql 10.0.3 by reflection that Root Certificate round-trips through the builder with only the certificate value changed.
Store TLS is a real two-cert chain — Windows refused the self-signed …