-
Notifications
You must be signed in to change notification settings - Fork 606
CVE 2026 103604
Issue affecting: BC C# .NET 2.6.2 and earlier, and the 2.7.0-beta.98 pre-release.
Fixed versions: BC C# .NET 2.7.0
Platform affected: All CLRs.
When an X509Name is converted to a string, each attribute value is escaped as RFC 4514 requires: a backslash is placed before each of the characters , " \ + = < > ; and before leading and trailing spaces. X509Name.ToString and IetfUtilities.ValueToString, which IetfUtilities.CanonicalString and IetfUtilities.RdnAreEqual rely on, did this by inserting each backslash into the StringBuilder they were scanning. Every insertion moves the rest of the value, so the work grows with the square of the number of characters to escape. The values come from whoever created the certificate, CRL, certification request or other structure the name was parsed from, and parsing does not limit their length.
An application is exposed if it converts names from untrusted input to strings, for example when it logs or displays a certificate's subject or issuer, calls X509Certificate.ToString(), or reads directoryName entries with GetSubjectAlternativeNames(). It is also exposed if it compares such names with IetfUtilities.RdnAreEqual, which PKIX path validation does when a CA in the path imposes directoryName name constraints. In our tests, converting a name with one attribute value of 60,000 commas took about one second, and 120,000 commas about four seconds. The cost is paid again on every conversion, so a few parallel requests can keep every CPU core busy. Parsing a name, X509Name.Equivalent and X509Name.GetHashCode are not affected.
BC C# .NET 2.7.0 escapes each value in a single pass, appending to a new buffer instead of inserting into the one being scanned, so the time grows only linearly with the length of the value. The same 120,000-character value now takes under two milliseconds. The strings produced are unchanged, except that IetfUtilities.ValueToString no longer adds a stray extra backslash to a value made up only of spaces. Nothing needs to be configured.
Users of earlier versions who cannot upgrade immediately should check the length of a name's attribute values before converting it to a string. X509Name.GetValueList() returns the values without escaping them, so an application can skip or truncate names containing values longer than it needs (RFC 5280 gives upper bounds of 64 or 128 characters for common naming attributes such as commonName, organizationName and localityName). Limiting the size of certificates, CRLs and requests accepted from untrusted parties also limits the cost, including for name-constraint checking.
The corresponding issue in BC Java was fixed in BC Java 1.85 (CVE-2026-58059).
Fix Commits:
- https://github.com/bcgit/bc-csharp/commit/bd03e38bbb49db5be33f4463fc40997400c545cc (escapes X509Name and IetfUtilities values in a single linear pass)
Credit: Discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research.