Skip to main content

Incus CVE-2026-40243

LOW
Improper Authentication (CWE-287)
2026-05-04 https://github.com/lxc/incus GHSA-c839-4qxr-j4x3
2.3
CVSS 4.0 · GitHub Advisory

Severity by source

GitHub Advisory PRIMARY
2.3 LOW
CVSS:4.0/AV:A/AC:H/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:4.0/AV:A/AC:H/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Adjacent
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

2
Source Code Evidence Fetched
May 04, 2026 - 19:31 vuln.today
Analysis Generated
May 04, 2026 - 19:31 vuln.today

DescriptionGitHub Advisory

Summary

Broken TLS validation logic in the OVN database connection logic could allow connections to an attacker's OVN database.

OVN uses mTLS for authentication, so the attacker cannot actually perform a full man in the middle attack as they won't be able to authenticated with the real OVN deployment. At best they can provide a replacement empty database which Incus will briefly interact with before hitting errors due to the rest of the OVN stack not reacting to the committed changes.

Also worth noting that the OVN control plane is typically run on the same servers that run Incus, there is typically no routing involved between an Incus server and the OVN control plane, making such an attack extremely difficult to pull off in the first place.

Details

The OVN client implementations within Incus disable Go standard TLS server verification (InsecureSkipVerify: true) and replace it with custom peer-certificate verification logic. That replacement verifier does not anchor trust in the configured CA certificate. Instead, it constructs the verification root set from certificates supplied by the peer during the handshake. As a result, the configured CA is parsed but not used as the trust anchor for the final verification decision.

Although a configured CA certificate (tlsCAcert) is parsed and added to a client CA pool, that pool is not used during the final verification decision. Instead, the callback creates a fresh roots pool from the raw certificates received over the wire and verifies the presented leaf certificate against those attacker-influenced roots. No endpoint identity validation is visible in the provided verification logic.

In OVN-enabled Incus deployments that use these SSL database connection paths, this affects authenticated connections from Incus to the OVN northbound and southbound databases. Incus documents clustered OVN deployments in which the OVN distributed database runs across multiple servers, and upstream OVN documentation describes the northbound database as the interface used by the cloud management system and the southbound database as the central coordination point for logical and physical network state.

Because the custom verifier accepts peer-supplied trust anchors, an attacker able to impersonate or intercept the OVN endpoint on the management network can present a rogue self-signed certificate chain. Incus will accept this certificate as valid, collapsing the configured CA-based trust model. Because Incus exposes dedicated OVN TLS settings for a CA certificate, client certificate, and client key, the implementation clearly intends to authenticate OVN database connections using operator-supplied trust material rather than peer-supplied certificates. By abandoning the configured CA pool and instead trusting peer-supplied roots, the implementation defeats the intended authentication boundary on OVN database connections and permits endpoint impersonation by an active attacker able to intercept or stand in for the OVN database service.

In clustered OVN-backed Incus deployments, this flaw reduces CA-anchored authentication of OVN database connections to endpoint impersonation for an attacker with a suitable position on the management or control-plane network. This is especially significant because OVN northbound and southbound databases are the authoritative control-plane interfaces for logical network configuration, translation, and distribution to hypervisors and gateways. As a result, the issue is best understood as a control-plane authentication failure with potentially broad networking impact, not merely as generic TLS misconfiguration.

Affected Files: https://github.com/lxc/incus/blob/v6.22.0/internal/server/network/ovn/ovn_nb.go https://github.com/lxc/incus/blob/v6.22.0/internal/server/network/ovn/ovn_sb.go https://github.com/lxc/incus/blob/v6.22.0/internal/server/network/ovn/ovn_icnb.go https://github.com/lxc/incus/blob/v6.22.0/internal/server/network/ovn/ovn_icsb.go

Affected Code:

func NewNB(dbAddr string, sslCACert string, sslClientCert string, sslClientKey string) (*NB, error) {
    [...]
    if strings.Contains(dbAddr, "ssl:") {
        [...]
        tlsConfig := &tls.Config{
            Certificates:       []tls.Certificate{clientCert},
            InsecureSkipVerify: true,
        }

        if sslCACert != "" {
            [...]
            tlsCAcert, err := x509.ParseCertificate(tlsCAder.Bytes)
            if err != nil {
                return nil, err
            }

            tlsCAcert.IsCA = true
            tlsCAcert.KeyUsage = x509.KeyUsageCertSign

            clientCAPool := x509.NewCertPool()
            clientCAPool.AddCert(tlsCAcert)

            tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, chains [][]*x509.Certificate) error {
                if len(rawCerts) < 1 {
                    return errors.New("Missing server certificate")
                }

                roots := x509.NewCertPool()
                for _, rawCert := range rawCerts {
                    cert, _ := x509.ParseCertificate(rawCert)
                    if cert != nil {
                        roots.AddCert(cert)
                    }
                }

                cert, _ := x509.ParseCertificate(rawCerts[0])
                if cert == nil {
                    return errors.New("Bad server certificate")
                }

                opts := x509.VerifyOptions{
                    Roots: roots,
                }

                _, err := cert.Verify(opts)
                return err
            }
        }

        options = append(options, ovsdbClient.WithTLSConfig(tlsConfig))
    }
    [...]
}

The same verification pattern is duplicated in the other affected files listed above.

Verification-Logic Proof of Concept

Because the vulnerability resides entirely in the certificate-verification logic, it can be demonstrated in isolation without a live interception lab. The following Go harness reproduces the effective OVN client verification logic, generates a rogue self-signed certificate, and demonstrates that the implemented trust decision accepts peer-supplied roots instead of the configured CA pool.

Commands:

cat <<'EOF' > poc_ovn_tls_roots.go
package main

import (
    "crypto/ed25519"
    "crypto/rand"
    "crypto/x509"
    "crypto/x509/pkix"
    "fmt"
    "math/big"
    "time"
)

func main() {
    pub, priv, _ := ed25519.GenerateKey(rand.Reader)

    template := x509.Certificate{
        SerialNumber: big.NewInt(1),
        Subject: pkix.Name{
            Organization: []string{"Attacker Corp MITM"},
        },
        NotBefore:             time.Now(),
        NotAfter:              time.Now().Add(time.Hour),
        KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
        BasicConstraintsValid: true,
        IsCA:                  true,
    }

    rogueCertBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, pub, priv)

    verifyPeerCertificate := func(rawCerts [][]byte) error {
        if len(rawCerts) < 1 {
            return fmt.Errorf("missing server certificate")
        }

        roots := x509.NewCertPool()
        for _, rawCert := range rawCerts {
            cert, _ := x509.ParseCertificate(rawCert)
            if cert != nil {
                roots.AddCert(cert)
            }
        }

        cert, _ := x509.ParseCertificate(rawCerts[0])
        if cert == nil {
            return fmt.Errorf("bad server certificate")
        }

        opts := x509.VerifyOptions{
            Roots: roots,
        }

        _, err := cert.Verify(opts)
        return err
    }

    err := verifyPeerCertificate([][]byte{rogueCertBytes})
    if err == nil {
        fmt.Println("[!] VULNERABLE: The reproduced OVN client verification logic accepted the rogue attacker certificate.")
    } else {
        fmt.Printf("Safe: Rejected with error: %v\n", err)
    }
}
EOF

go run poc_ovn_tls_roots.go

Result:

[!] VULNERABLE: The reproduced OVN client verification logic accepted the rogue attacker certificate.

It is recommended to verify peer certificates against the configured CA pool rather than against roots synthesized from untrusted peer input. The safest fix is to remove the custom VerifyPeerCertificate logic and rely on Go standard TLS verification with tls.Config.RootCAs set to the configured CA pool and, where applicable, ServerName set appropriately for identity validation.

Credit

This issue was discovered and reported by the team at 7asecurity (https://7asecurity.com/)

AnalysisAI

Broken TLS certificate verification in Incus OVN database connections accepts peer-supplied certificate roots instead of anchoring trust in the configured CA certificate, allowing an attacker positioned on the management network to impersonate the OVN northbound or southbound database. While mTLS prevents full man-in-the-middle attacks and OVN control planes typically run on the same servers as Incus (limiting network attack surface), the flaw collapses the intended CA-based authentication boundary on critical control-plane database connections. Affected versions below 7.0.0 are vulnerable; no active exploitation confirmed in CISA KEV at time of analysis.

Technical ContextAI

Incus uses OVN (Open Virtual Network) for network management in clustered deployments. The vulnerability exists in the Go TLS client implementations for OVN northbound (NB) and southbound (SB) database connections, plus their interconnect variants (ICNB/ICSB). The code disables Go's standard TLS server verification (InsecureSkipVerify: true) and implements custom peer-certificate validation via the VerifyPeerCertificate callback. The custom verifier parses the configured CA certificate into a pool but never uses that pool for verification. Instead, it constructs a fresh x509.CertPool from raw certificates supplied by the peer during the TLS handshake and verifies the leaf certificate against those peer-supplied roots. This defeats the intended mTLS authentication model: the configured tlsCAcert, sslClientCert, and sslClientKey are operator-supplied trust material, but the implementation ignores the CA pool and accepts any self-signed certificate presented by the peer. The root cause is CWE-287 (Improper Authentication) combined with improper trust boundary implementation.

RemediationAI

Upgrade Incus to version 7.0.0 or later, which removes the custom VerifyPeerCertificate callback and relies on Go standard TLS verification with RootCAs set to the configured CA pool and ServerName set for identity validation. No workarounds are available for versions below 7.0.0 other than network-level mitigations: isolate the OVN control plane on a separate, restricted network segment and implement strict network ACLs to prevent unauthorized access to OVN database ports (typically 6641 for NB, 6642 for SB). Disable SSL/TLS on OVN connections only if the OVN infrastructure and all Incus servers are on a fully trusted, air-gapped network (high risk and not recommended). After patching, verify that the configured CA certificate, client certificate, and client key are still in place and correct, as the standard verification path will enforce their use. Review OVN deployment topology to ensure control-plane servers are not exposed to untrusted networks. See GitHub advisory GHSA-c839-4qxr-j4x3 for additional context and confirmation.

Share

CVE-2026-40243 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy