bmcweb mTLS: UPN domain suffix matching authenticates parent-domain and TLD-only certificates

binreaper <[email protected]>
Newsgroups org.ozlabs.lists.openbmc
Message-ID <Edi-ZB9R4AJAZhrvwWnwKu4TZURV7FTcns18seYmP2-hZHZziG1BkyPF3iS1wJbE2wttI8MEHtDCBiVowlF2YYBjX4Gzl54iafbhmKespAw=@proton.me>
Hi all,

A second of the four bmcweb security findings I reported privately on 2026-02-23 remains unfixed in master. I posted the more severe of the two (HTTP/2 pre-auth body accumulation) to this list earlier today; this is the lower-severity sibling. Same redirect rationale (Ed Tanous's 2026-05-14 instruction to use public channels). A suggested Gerrit change accompanies this post.

## Summary

`isUPNMatch()` in `http/mutual_tls.cpp` performs domain suffix matching when validating mTLS client certificates in UserPrincipalName (UPN) mode. The algorithm strips dot-separated labels from right to left and returns true once the UPN domain runs out of labels, regardless of how many hostname labels remain. The result is that a certificate with a UPN of just a TLD (`user@com`) authenticates against any BMC in that TLD, and a parent-domain certificate (`[email protected]`) authenticates against any BMC nested under that parent (`bmc.lab.internal.example.com`).

- **Affected component**: bmcweb mTLS authentication, `http/mutual_tls.cpp::isUPNMatch()`.
- **Configuration prerequisite**: `CertificateMappingAttribute=UserPrincipalName` (not the default; default is `CommonName`). UPN mode is opt-in but is deployed by several large operators.
- **Severity**: CVSS 3.1 6.8 (Medium) — `AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N`. Attack complexity is High because the attacker needs a CA-signed client certificate with a parent-domain or TLD-only UPN; the scope is "anyone holding such a cert against any BMC under that suffix", which can be very broad in enterprise PKI deployments.

## Reproducer (no exploit code required)

The behavior is asserted by the project's own existing unit test, which I will not reproduce verbatim per the customary list etiquette, but the form is:

```
EXPECT_TRUE(isUPNMatch("user@com", "hostname.region.domain.com"));
```

That expectation is the bug. Any certificate the BMC will accept whose UPN domain is just `com` will authenticate the bearer against `hostname.region.domain.com`. The same applies to any other suffix relationship.

The "patches" landed on master on 2026-04-10 (commits `af44b2bd` "Make UPN domain matching case-insensitive" and `5d4a41fa` more UPN unit tests) touched the exact function and added unit tests, but they only made matching case-insensitive — they did not address the suffix-matching escalation. From the outside the bug looks closed; it is not.

## Suggested fix

The Gerrit change linked above replaces the right-to-left label walk with two checks:

1. Exact match: the UPN domain equals the BMC hostname.
2. One-label-prefix tolerance: the UPN domain equals the BMC hostname after stripping a single leading short-hostname label. This preserves the common pattern where the UPN uses the DNS domain (`domain.com`) and the BMC hostname prepends one label (`bmc-01.domain.com`).

Any deeper nesting is rejected. Case-insensitivity is retained via `bmcweb::asciiIEquals()`. The existing unit test that asserted the suffix-match behavior is corrected to `EXPECT_FALSE` and two additional positive cases (exact match, one-label prefix) are added.

This is a minimal-change fix. An alternative — minimum-label-depth enforcement (require the UPN domain to contain at least one dot) — would prevent only the TLD-only case and leave the parent-domain escalation intact. I went with the exact-plus-one-label form because it covers both bug classes and matches the actual operational pattern that UPN mode is configured for.

## What I'd appreciate

A maintainer review of the Gerrit change. The diff is small (~36/-28 across `http/mutual_tls.cpp` and `test/http/mutual_tls.cpp`). If a different shape of fix would land more cleanly with bmcweb's design, I'm happy to revise; if the one-label-prefix tolerance is itself too permissive, I'm happy to tighten further to exact-match-only.

## Timeline

- **2026-02-23** — Reported privately to `[email protected]` as the fourth of four findings; acknowledged the same day by Joseph Reynolds and forwarded to the bmcweb maintainers.
- **2026-04-10** — `af44b2bd` "Make UPN domain matching case-insensitive" + `5d4a41fa` more UPN unit tests landed on master. These touch the same function but do not address the suffix-matching escalation.
- **2026-05-05** — Status-check email to the maintainers. No reply on this finding.
- **2026-05-14** — Maintainer reply (Ed Tanous) redirected further correspondence on the remaining findings to public OpenBMC channels. This post is that follow-up.
- **2026-05-27** — H2-F1 (the more severe sibling finding) posted to this list with Gerrit change 90580; this post and Gerrit change 90581 cover AUTH-F6.

Best regards,
binreaper
[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.