Skip to content

TLS Hostname Verification Bypass via Overly Permissive Wildcard Matching

High
scaprile published GHSA-jp6g-796f-39vp Aug 12, 2026

Software

mongoose

Affected versions

<= 7.21

Patched versions

7.22

Description

Mongoose's built-in TLS 1.3 hostname verification uses the generic mg_match() pattern matcher to compare certificate SAN/CN values against the expected hostname. mg_match() treats * as "match any character except /", which matches dots. Per RFC 6125 Section 6.4.3, a wildcard * in a certificate SAN/CN must only match a single DNS label (no dots). This allows a certificate with SAN *.example.com to incorrectly match hostnames like foo.bar.example.com, and a certificate with SAN *.com to match www.example.com.

This enables man-in-the-middle attacks where an attacker with a wildcard certificate for a parent domain can impersonate any subdomain of arbitrary depth.

Vulnerable Code

tls_builtin.c:1507-1539 -- SAN verification uses mg_match

static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
                                  const char *server_name,
                                  struct mg_addr *server_ip) {
  // ...
  while (mg_der_next(&field, &name) > 0) {
    if (name.type == 0x87 && name.len == 4) {  // IPv4
      // ...
    } else {       // text SAN
      if (mg_match(mg_str(server_name),
                   mg_str_n((char *) name.value, name.len),  // cert SAN as pattern
                   NULL))
        return 1;  // match
    }
  }
  return -1;
}

tls_builtin.c:1568-1575 -- CN verification also uses mg_match

static int mg_tls_verify_cert_cn(struct mg_der_tlv *subj, const char *host) {
  struct mg_der_tlv v;
  int matched = 0;
  if (mg_der_find_oid(subj, (uint8_t *) "\x55\x04\x03", 3, &v) > 0) {
    matched = mg_match(mg_str(host), mg_str_n((char *) v.value, v.len), NULL);
  }
  return matched;
}

str.c:71-105 -- mg_match wildcard semantics

mg_match() stops * at / but not at . -- in DNS context there are no / characters so * matches across labels.

Proof of Concept

Compiled test program:

mg_match("www.example.com", "*.com", NULL)              => 1 (WRONG: should be 0)
mg_match("foo.bar.example.com", "*.example.com", NULL)  => 1 (WRONG: should be 0)
mg_match("foo.example.com", "*.example.com", NULL)      => 1 (correct)

Impact

  • Man-in-the-middle: attacker on network path can intercept TLS connections from Mongoose clients by presenting a wildcard certificate that matches more hostnames than RFC 6125 permits
  • IoT exposure: Mongoose is primarily deployed on IoT devices and embedded systems connecting to cloud services, with no user interface to detect certificate anomalies
  • Both SAN and CN verification paths are affected

Verified against cesanta/mongoose master commit 0a3db82.

Severity

High

CVE ID

CVE-2026-73253

Weaknesses

Improper Certificate Validation

The product does not validate, or incorrectly validates, a certificate. Learn more on MITRE.

Credits