CVE-2026-103503 (GCVE-0-2026-103503)

Vulnerability from cvelistv5 – Published: 2026-10-12 15:17 – Updated: 2026-10-12 15:17
VLAI
Title
Hex trusts its bundled CA certificates when cacerts_path is set
Summary
Improper Certificate Validation vulnerability in hexpm hex allows an attacker who can intercept HTTPS connections, and holds a certificate for a Hex host issued by a CA in Hex's bundled CA store, to impersonate that host to users who set cacerts_path to a CA store that leaves that CA out. cacerts_path (HEX_CACERTS_PATH) is documented as the path to the CA certificate store, used instead of the CA bundle that ships with Hex. Hex.HTTP.SSL.ssl_opts/1 passes the configured store as the cacerts option, but builds the partial_chain callback from the bundled store whether cacerts_path is set or not. Hex.HTTP.SSL.partial_chain/2 accepts a server chain when any certificate in it has the same public key as a bundled CA certificate, so a chain that leads to a bundled CA passes verification although the configured store doesn't contain that CA. Hostname verification still applies. This issue affects hex: from 0.20.2 before 2.5.2.
CWE
  • CWE-295 - Improper Certificate Validation
Assigner
EEF CNA under the mitre root
CNA scorecard A 96/100 over 309 records in the last 180 days details
Impacted products
Vendor Product Version CPE status
hexpm hex Affected: 0.20.2 , < 2.5.2 (semver)
    cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*
Create a notification for this product.
hexpm hex Affected: c9b26a46928bfcd546773571e09c1d05f4cd9fb7 , < * (git)
    cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "cpes": [
            "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Hex.HTTP.SSL\u0027"
          ],
          "packageName": "hex",
          "packageURL": "pkg:otp/hex?repository_url=https:%2F%2Fgithub.com%2Fhexpm%2Fhex\u0026vcs_url=repository_url=git%2Bhttps:%2F%2Fgithub.com%2Fhexpm%2Fhex.git",
          "product": "hex",
          "programFiles": [
            "lib/hex/http/ssl.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:ssl_opts/1"
            },
            {
              "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:partial_chain/2"
            }
          ],
          "repo": "https://github.com/hexpm/hex",
          "vendor": "hexpm",
          "versions": [
            {
              "lessThan": "2.5.2",
              "status": "affected",
              "version": "0.20.2",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Hex.HTTP.SSL\u0027"
          ],
          "packageName": "hexpm/hex",
          "packageURL": "pkg:github/hexpm/hex",
          "product": "hex",
          "programFiles": [
            "lib/hex/http/ssl.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:ssl_opts/1"
            },
            {
              "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:partial_chain/2"
            }
          ],
          "repo": "https://github.com/hexpm/hex",
          "vendor": "hexpm",
          "versions": [
            {
              "changes": [
                {
                  "at": "5f5a2136c7cf5991b6e8a30d645ca9f8e74b0785",
                  "status": "unaffected"
                },
                {
                  "at": "6232a6498015e559743bec4f4fbec9138837cec8",
                  "status": "unaffected"
                }
              ],
              "lessThan": "*",
              "status": "affected",
              "version": "c9b26a46928bfcd546773571e09c1d05f4cd9fb7",
              "versionType": "git"
            }
          ]
        }
      ],
      "configurations": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eAffects users who set \u003ccode\u003ecacerts_path\u003c/code\u003e or \u003ccode\u003eHEX_CACERTS_PATH\u003c/code\u003e to a CA store that leaves out some of the CAs bundled with Hex. Users who don\u0027t set it trust the bundled store already and aren\u0027t affected.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Affects users who set `cacerts_path` or `HEX_CACERTS_PATH` to a CA store that leaves out some of the CAs bundled with Hex. Users who don\u0027t set it trust the bundled store already and aren\u0027t affected."
            }
          ],
          "value": "Affects users who set cacerts_path or HEX_CACERTS_PATH to a CA store that leaves out some of the CAs bundled with Hex. Users who don\u0027t set it trust the bundled store already and aren\u0027t affected."
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "2.5.2",
                  "versionStartIncluding": "0.20.2",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Eric Meadows-J\u00f6nsson"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "dateAssigned": "2026-10-10T12:59:48.000Z",
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eImproper Certificate Validation vulnerability in hexpm hex allows an attacker who can intercept HTTPS connections, and holds a certificate for a Hex host issued by a CA in Hex\u0027s bundled CA store, to impersonate that host to users who set \u003ccode\u003ecacerts_path\u003c/code\u003e to a CA store that leaves that CA out.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ecacerts_path\u003c/code\u003e (\u003ccode\u003eHEX_CACERTS_PATH\u003c/code\u003e) is documented as the path to the CA certificate store, used instead of the CA bundle that ships with Hex. \u003ccode\u003eHex.HTTP.SSL.ssl_opts/1\u003c/code\u003e passes the configured store as the \u003ccode\u003ecacerts\u003c/code\u003e option, but builds the \u003ccode\u003epartial_chain\u003c/code\u003e callback from the bundled store whether \u003ccode\u003ecacerts_path\u003c/code\u003e is set or not. \u003ccode\u003eHex.HTTP.SSL.partial_chain/2\u003c/code\u003e accepts a server chain when any certificate in it has the same public key as a bundled CA certificate, so a chain that leads to a bundled CA passes verification although the configured store doesn\u0027t contain that CA. Hostname verification still applies.\u003c/p\u003e\n\u003cp\u003eThis issue affects hex: from 0.20.2 before 2.5.2.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Improper Certificate Validation vulnerability in hexpm hex allows an attacker who can intercept HTTPS connections, and holds a certificate for a Hex host issued by a CA in Hex\u0027s bundled CA store, to impersonate that host to users who set `cacerts_path` to a CA store that leaves that CA out.\n\n`cacerts_path` (`HEX_CACERTS_PATH`) is documented as the path to the CA certificate store, used instead of the CA bundle that ships with Hex. `Hex.HTTP.SSL.ssl_opts/1` passes the configured store as the `cacerts` option, but builds the `partial_chain` callback from the bundled store whether `cacerts_path` is set or not. `Hex.HTTP.SSL.partial_chain/2` accepts a server chain when any certificate in it has the same public key as a bundled CA certificate, so a chain that leads to a bundled CA passes verification although the configured store doesn\u0027t contain that CA. Hostname verification still applies.\n\nThis issue affects hex: from 0.20.2 before 2.5.2."
            }
          ],
          "value": "Improper Certificate Validation vulnerability in hexpm hex allows an attacker who can intercept HTTPS connections, and holds a certificate for a Hex host issued by a CA in Hex\u0027s bundled CA store, to impersonate that host to users who set cacerts_path to a CA store that leaves that CA out.\n\ncacerts_path (HEX_CACERTS_PATH) is documented as the path to the CA certificate store, used instead of the CA bundle that ships with Hex. Hex.HTTP.SSL.ssl_opts/1 passes the configured store as the cacerts option, but builds the partial_chain callback from the bundled store whether cacerts_path is set or not. Hex.HTTP.SSL.partial_chain/2 accepts a server chain when any certificate in it has the same public key as a bundled CA certificate, so a chain that leads to a bundled CA passes verification although the configured store doesn\u0027t contain that CA. Hostname verification still applies.\n\nThis issue affects hex: from 0.20.2 before 2.5.2."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-94",
          "descriptions": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eUsers set \u003ccode\u003ecacerts_path\u003c/code\u003e to limit which CAs can authenticate Hex\u0027s servers, for example to their organization\u0027s internal CA. Every CA in Hex\u0027s bundled store can still authenticate those servers, so a certificate mis-issued by one of those CAs, or obtained through compromised domain validation, lets an attacker on the network path impersonate hex.pm, repo.hex.pm, a self-hosted repository or a mirror. The attacker receives the API keys, OAuth tokens and repository keys Hex sends, and can alter API responses. Registry signatures and package checksums still prevent changes to registry contents and packages.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Users set `cacerts_path` to limit which CAs can authenticate Hex\u0027s servers, for example to their organization\u0027s internal CA. Every CA in Hex\u0027s bundled store can still authenticate those servers, so a certificate mis-issued by one of those CAs, or obtained through compromised domain validation, lets an attacker on the network path impersonate hex.pm, repo.hex.pm, a self-hosted repository or a mirror. The attacker receives the API keys, OAuth tokens and repository keys Hex sends, and can alter API responses. Registry signatures and package checksums still prevent changes to registry contents and packages."
                }
              ],
              "value": "Users set cacerts_path to limit which CAs can authenticate Hex\u0027s servers, for example to their organization\u0027s internal CA. Every CA in Hex\u0027s bundled store can still authenticate those servers, so a certificate mis-issued by one of those CAs, or obtained through compromised domain validation, lets an attacker on the network path impersonate hex.pm, repo.hex.pm, a self-hosted repository or a mirror. The attacker receives the API keys, OAuth tokens and repository keys Hex sends, and can alter API responses. Registry signatures and package checksums still prevent changes to registry contents and packages."
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "HIGH",
            "attackRequirements": "PRESENT",
            "attackVector": "NETWORK",
            "baseScore": 5.9,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "ACTIVE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:A/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "NONE",
            "vulnConfidentialityImpact": "HIGH",
            "vulnIntegrityImpact": "LOW",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-295",
              "description": "CWE-295 Improper Certificate Validation",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-10-12T15:17:45.545Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "name": "GitHub Advisory",
          "tags": [
            "related",
            "vendor-advisory"
          ],
          "url": "https://github.com/hexpm/hex/security/advisories/GHSA-rw8q-hg7m-cxgr"
        },
        {
          "name": "EEF CNA record for CVE-2026-103503",
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-103503.html"
        },
        {
          "name": "OSV record EEF-CVE-2026-103503",
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-103503"
        },
        {
          "name": "Introducing commit c9b26a4 in hexpm/hex",
          "tags": [
            "related"
          ],
          "url": "https://github.com/hexpm/hex/commit/c9b26a46928bfcd546773571e09c1d05f4cd9fb7"
        },
        {
          "name": "Fix commit 5f5a213 in hexpm/hex",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/hexpm/hex/commit/5f5a2136c7cf5991b6e8a30d645ca9f8e74b0785"
        },
        {
          "name": "Fix commit 6232a64 in hexpm/hex",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/hexpm/hex/commit/6232a6498015e559743bec4f4fbec9138837cec8"
        }
      ],
      "solutions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eUpgrade Hex to 2.5.2 or later, for example with \u003ccode\u003emix local.hex\u003c/code\u003e. With \u003ccode\u003ecacerts_path\u003c/code\u003e (\u003ccode\u003eHEX_CACERTS_PATH\u003c/code\u003e) set, Hex then only accepts server certificates that chain to a CA in that file, and it doesn\u0027t trust copies of CA certificates sent by the server.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Upgrade Hex to 2.5.2 or later, for example with `mix local.hex`. With `cacerts_path` (`HEX_CACERTS_PATH`) set, Hex then only accepts server certificates that chain to a CA in that file, and it doesn\u0027t trust copies of CA certificates sent by the server."
            }
          ],
          "value": "Upgrade Hex to 2.5.2 or later, for example with mix local.hex. With cacerts_path (HEX_CACERTS_PATH) set, Hex then only accepts server certificates that chain to a CA in that file, and it doesn\u0027t trust copies of CA certificates sent by the server."
        }
      ],
      "source": {
        "discovery": "UNKNOWN"
      },
      "title": "Hex trusts its bundled CA certificates when cacerts_path is set",
      "workarounds": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eThere\u0027s no Hex configuration that stops the bundled CAs from being trusted.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "There\u0027s no Hex configuration that stops the bundled CAs from being trusted."
            }
          ],
          "value": "There\u0027s no Hex configuration that stops the bundled CAs from being trusted."
        }
      ],
      "x_proofOfConcept": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003col\u003e\n\u003cli\u003eCreate a PEM file that contains only an unrelated test CA certificate and set \u003ccode\u003ecacerts_path\u003c/code\u003e to it.\u003c/li\u003e\n\u003cli\u003eOpen a TLS connection to hex.pm with the options from \u003ccode\u003eHex.HTTP.SSL.ssl_opts(\"https://hex.pm\")\u003c/code\u003e. The handshake succeeds, and the accepted chain leads to ISRG Root X2 cross-signed by ISRG Root X1, neither of which is in the PEM file.\u003c/li\u003e\n\u003cli\u003eRemove the \u003ccode\u003epartial_chain\u003c/code\u003e option and connect again. The handshake fails with \u003ccode\u003eunknown_ca\u003c/code\u003e.\u003c/li\u003e\n\u003c/ol\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "1. Create a PEM file that contains only an unrelated test CA certificate and set `cacerts_path` to it.\n2. Open a TLS connection to hex.pm with the options from `Hex.HTTP.SSL.ssl_opts(\"https://hex.pm\")`. The handshake succeeds, and the accepted chain leads to ISRG Root X2 cross-signed by ISRG Root X1, neither of which is in the PEM file.\n3. Remove the `partial_chain` option and connect again. The handshake fails with `unknown_ca`."
            }
          ],
          "value": "* Create a PEM file that contains only an unrelated test CA certificate and set cacerts_path to it.\n* Open a TLS connection to hex.pm with the options from Hex.HTTP.SSL.ssl_opts(\"https://hex.pm\"). The handshake succeeds, and the accepted chain leads to ISRG Root X2 cross-signed by ISRG Root X1, neither of which is in the PEM file.\n* Remove the partial_chain option and connect again. The handshake fails with unknown_ca."
        }
      ],
      "x_technicalAnalysis": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003col\u003e\n\u003cli\u003e\u003ccode\u003eHex.HTTP.SSL.get_ca_certs/0\u003c/code\u003e returns the certificates from \u003ccode\u003ecacerts_path\u003c/code\u003e when it\u0027s set, and \u003ccode\u003essl_opts/1\u003c/code\u003e passes them as \u003ccode\u003ecacerts\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003essl_opts/1\u003c/code\u003e sets \u003ccode\u003epartial_chain\u003c/code\u003e to \u003ccode\u003e\u0026amp;partial_chain(Certs.cacerts(), \u0026amp;1)\u003c/code\u003e, which always uses the bundled store.\u003c/li\u003e\n\u003cli\u003eWhen the server\u0027s chain doesn\u0027t lead to a certificate in \u003ccode\u003ecacerts\u003c/code\u003e, OTP calls \u003ccode\u003epartial_chain\u003c/code\u003e with the chain. \u003ccode\u003epartial_chain/2\u003c/code\u003e returns \u003ccode\u003e{:trusted_ca, der}\u003c/code\u003e for the first certificate whose public key matches a bundled CA certificate, and OTP validates the chain with that certificate as the trust anchor.\u003c/li\u003e\n\u003cli\u003eChain validation and the hostname check from \u003ccode\u003ecustomize_hostname_check/1\u003c/code\u003e still run, so the attacker needs a certificate for the requested host that chains to a bundled CA.\u003c/li\u003e\n\u003c/ol\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "1. `Hex.HTTP.SSL.get_ca_certs/0` returns the certificates from `cacerts_path` when it\u0027s set, and `ssl_opts/1` passes them as `cacerts`.\n2. `ssl_opts/1` sets `partial_chain` to `\u0026partial_chain(Certs.cacerts(), \u00261)`, which always uses the bundled store.\n3. When the server\u0027s chain doesn\u0027t lead to a certificate in `cacerts`, OTP calls `partial_chain` with the chain. `partial_chain/2` returns `{:trusted_ca, der}` for the first certificate whose public key matches a bundled CA certificate, and OTP validates the chain with that certificate as the trust anchor.\n4. Chain validation and the hostname check from `customize_hostname_check/1` still run, so the attacker needs a certificate for the requested host that chains to a bundled CA."
            }
          ],
          "value": "* Hex.HTTP.SSL.get_ca_certs/0 returns the certificates from cacerts_path when it\u0027s set, and ssl_opts/1 passes them as cacerts.\n* ssl_opts/1 sets partial_chain to \u0026partial_chain(Certs.cacerts(), \u00261), which always uses the bundled store.\n* When the server\u0027s chain doesn\u0027t lead to a certificate in cacerts, OTP calls partial_chain with the chain. partial_chain/2 returns {:trusted_ca, der} for the first certificate whose public key matches a bundled CA certificate, and OTP validates the chain with that certificate as the trust anchor.\n* Chain validation and the hostname check from customize_hostname_check/1 still run, so the attacker needs a certificate for the requested host that chains to a bundled CA."
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-103503",
    "datePublished": "2026-10-12T15:17:45.545Z",
    "dateReserved": "2026-10-08T15:45:02.372Z",
    "dateUpdated": "2026-10-12T15:17:45.545Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2026-103503",
      "date": "2026-10-13",
      "epss": "0.00191",
      "percentile": "0.0816"
    },
    "nvd": {
      "cve": {
        "affected": [
          {
            "affectedData": [
              {
                "cpes": [
                  "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
                ],
                "defaultStatus": "unaffected",
                "modules": [
                  "\u0027Elixir.Hex.HTTP.SSL\u0027"
                ],
                "packageName": "hex",
                "packageURL": "pkg:otp/hex?repository_url=https:%2F%2Fgithub.com%2Fhexpm%2Fhex\u0026vcs_url=repository_url=git%2Bhttps:%2F%2Fgithub.com%2Fhexpm%2Fhex.git",
                "product": "hex",
                "programFiles": [
                  "lib/hex/http/ssl.ex"
                ],
                "programRoutines": [
                  {
                    "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:ssl_opts/1"
                  },
                  {
                    "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:partial_chain/2"
                  }
                ],
                "repo": "https://github.com/hexpm/hex",
                "vendor": "hexpm",
                "versions": [
                  {
                    "lessThan": "2.5.2",
                    "status": "affected",
                    "version": "0.20.2",
                    "versionType": "semver"
                  }
                ]
              },
              {
                "collectionURL": "https://github.com",
                "cpes": [
                  "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
                ],
                "defaultStatus": "unaffected",
                "modules": [
                  "\u0027Elixir.Hex.HTTP.SSL\u0027"
                ],
                "packageName": "hexpm/hex",
                "packageURL": "pkg:github/hexpm/hex",
                "product": "hex",
                "programFiles": [
                  "lib/hex/http/ssl.ex"
                ],
                "programRoutines": [
                  {
                    "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:ssl_opts/1"
                  },
                  {
                    "name": "\u0027Elixir.Hex.HTTP.SSL\u0027:partial_chain/2"
                  }
                ],
                "repo": "https://github.com/hexpm/hex",
                "vendor": "hexpm",
                "versions": [
                  {
                    "changes": [
                      {
                        "at": "5f5a2136c7cf5991b6e8a30d645ca9f8e74b0785",
                        "status": "unaffected"
                      },
                      {
                        "at": "6232a6498015e559743bec4f4fbec9138837cec8",
                        "status": "unaffected"
                      }
                    ],
                    "lessThan": "*",
                    "status": "affected",
                    "version": "c9b26a46928bfcd546773571e09c1d05f4cd9fb7",
                    "versionType": "git"
                  }
                ]
              }
            ],
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
          }
        ],
        "cveTags": [],
        "descriptions": [
          {
            "lang": "en",
            "value": "Improper Certificate Validation vulnerability in hexpm hex allows an attacker who can intercept HTTPS connections, and holds a certificate for a Hex host issued by a CA in Hex\u0027s bundled CA store, to impersonate that host to users who set cacerts_path to a CA store that leaves that CA out.\n\ncacerts_path (HEX_CACERTS_PATH) is documented as the path to the CA certificate store, used instead of the CA bundle that ships with Hex. Hex.HTTP.SSL.ssl_opts/1 passes the configured store as the cacerts option, but builds the partial_chain callback from the bundled store whether cacerts_path is set or not. Hex.HTTP.SSL.partial_chain/2 accepts a server chain when any certificate in it has the same public key as a bundled CA certificate, so a chain that leads to a bundled CA passes verification although the configured store doesn\u0027t contain that CA. Hostname verification still applies.\n\nThis issue affects hex: from 0.20.2 before 2.5.2."
          }
        ],
        "id": "CVE-2026-103503",
        "lastModified": "2026-10-13T14:31:20.750",
        "metrics": {
          "cvssMetricV40": [
            {
              "cvssData": {
                "Automatable": "NOT_DEFINED",
                "Recovery": "NOT_DEFINED",
                "Safety": "NOT_DEFINED",
                "attackComplexity": "HIGH",
                "attackRequirements": "PRESENT",
                "attackVector": "NETWORK",
                "availabilityRequirement": "NOT_DEFINED",
                "baseScore": 5.9,
                "baseSeverity": "MEDIUM",
                "confidentialityRequirement": "NOT_DEFINED",
                "exploitMaturity": "NOT_DEFINED",
                "integrityRequirement": "NOT_DEFINED",
                "modifiedAttackComplexity": "NOT_DEFINED",
                "modifiedAttackRequirements": "NOT_DEFINED",
                "modifiedAttackVector": "NOT_DEFINED",
                "modifiedPrivilegesRequired": "NOT_DEFINED",
                "modifiedSubAvailabilityImpact": "NOT_DEFINED",
                "modifiedSubConfidentialityImpact": "NOT_DEFINED",
                "modifiedSubIntegrityImpact": "NOT_DEFINED",
                "modifiedUserInteraction": "NOT_DEFINED",
                "modifiedVulnAvailabilityImpact": "NOT_DEFINED",
                "modifiedVulnConfidentialityImpact": "NOT_DEFINED",
                "modifiedVulnIntegrityImpact": "NOT_DEFINED",
                "privilegesRequired": "NONE",
                "providerUrgency": "NOT_DEFINED",
                "subAvailabilityImpact": "NONE",
                "subConfidentialityImpact": "NONE",
                "subIntegrityImpact": "NONE",
                "userInteraction": "ACTIVE",
                "valueDensity": "NOT_DEFINED",
                "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:A/VC:H/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",
                "version": "4.0",
                "vulnAvailabilityImpact": "NONE",
                "vulnConfidentialityImpact": "HIGH",
                "vulnIntegrityImpact": "LOW",
                "vulnerabilityResponseEffort": "NOT_DEFINED"
              },
              "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
              "type": "Secondary"
            }
          ]
        },
        "published": "2026-10-12T16:17:02.427",
        "references": [
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://cna.erlef.org/cves/CVE-2026-103503.html"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/hexpm/hex/commit/5f5a2136c7cf5991b6e8a30d645ca9f8e74b0785"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/hexpm/hex/commit/6232a6498015e559743bec4f4fbec9138837cec8"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/hexpm/hex/commit/c9b26a46928bfcd546773571e09c1d05f4cd9fb7"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/hexpm/hex/security/advisories/GHSA-rw8q-hg7m-cxgr"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://osv.dev/vulnerability/EEF-CVE-2026-103503"
          }
        ],
        "sourceIdentifier": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "vulnStatus": "Deferred",
        "weaknesses": [
          {
            "description": [
              {
                "lang": "en",
                "value": "CWE-295"
              }
            ],
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "type": "Secondary"
          }
        ]
      }
    },
    "redhat_vex": {
      "current_release_date": "2026-10-12T16:25:21+00:00",
      "cve": "CVE-2026-103503",
      "id": "CVE-2026-103503",
      "initial_release_date": "2026-10-12T15:17:45.545000+00:00",
      "product_status:known_not_affected": "1",
      "source": "Red Hat CSAF VEX",
      "status": "final",
      "title": "hex: hex: Host impersonation via improper CA certificate store validation",
      "url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-103503.json",
      "version": "3"
    }
  }
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…