From d2dc589f141b6f2275085b9015f08b1747a2598c Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Tue, 2 Jun 2026 03:09:33 +0200 Subject: [PATCH] fix(node): capture node cert via VerifyConnection for fingerprint fetch FetchCertFingerprint read the leaf certificate from a bare insecure TLS handshake, which CodeQL flagged as go/disabled-certificate-check. The function intentionally accepts any cert (trust-on-first-use, so the admin can pin a not-yet-trusted node), so verification cannot be enabled. Capture the leaf cert inside a VerifyConnection callback instead, matching the existing pattern in nodeHTTPClientFor that already clears the same query. Behavior is unchanged. --- web/service/node.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/web/service/node.go b/web/service/node.go index 81cc4ac2..5aa6bffb 100644 --- a/web/service/node.go +++ b/web/service/node.go @@ -136,10 +136,20 @@ func (s *NodeService) FetchCertFingerprint(ctx context.Context, n *model.Node) ( if err != nil { return "", err } + var fingerprint string client := &http.Client{ Transport: &http.Transport{ - DialContext: netsafe.SSRFGuardedDialContext, - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + DialContext: netsafe.SSRFGuardedDialContext, + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + VerifyConnection: func(cs tls.ConnectionState) error { + if len(cs.PeerCertificates) > 0 { + sum := sha256.Sum256(cs.PeerCertificates[0].Raw) + fingerprint = base64.StdEncoding.EncodeToString(sum[:]) + } + return nil + }, + }, }, } resp, err := client.Do(req) @@ -147,11 +157,10 @@ func (s *NodeService) FetchCertFingerprint(ctx context.Context, n *model.Node) ( return "", err } defer resp.Body.Close() - if resp.TLS == nil || len(resp.TLS.PeerCertificates) == 0 { + if fingerprint == "" { return "", common.NewError("node did not present a TLS certificate") } - sum := sha256.Sum256(resp.TLS.PeerCertificates[0].Raw) - return base64.StdEncoding.EncodeToString(sum[:]), nil + return fingerprint, nil } func (s *NodeService) GetAll() ([]*model.Node, error) {