As I was searching for a standard way to parse X509Certificate in Java, StackOverflow https://stackoverflow.com/a/65003189 recommended using Spring Security's SubjectDnX509PrincipalExtractor.
However, as mentioned in StackOverflow comment, the RFC 2253 requires handling edge cases like escaped commas \, or quoted values.
Quick Google search found similar requirements on pages like: * https://www.ibm.com/docs/en/sia?topic=server-commas-in-cn-attribute * https://devblogs.microsoft.com/scripting/how-can-i-work-with-a-cn-that-has-a-comma-in-it/
Describe the bug
SubjectDnX509PrincipalExtractor.java uses regex "CN=(.*?)(?:,|$)". This doesn't satisfy the standard and can cause incorrect values to be parsed. As I'm not personally working with this Spring Security feature at all, I can't assess the actual impact, but it looks dangerous.
To Reproduce To simplify the Regex example: when running
Matcher matcher = Pattern.compile("CN=(.*?)(?:,|$)", Pattern.CASE_INSENSITIVE).matcher("cn=abc\\,xyz, ou=users");
matcher.find();
String match = matcher.group(1);
it matches abc\.
Expected behavior
it should match abc,xyz after also removing the escaping \ character in this context, right?
Quotes " could also probably be used and escaped.
Sample This doesn't require any specific sample. I don't have a Spring Security project where I could illustrate the internal usage of this class in an actual use-case.
fyi, LdapName seems to parse it correctly:
X509CertInfo info = new X509CertInfo();
info.setIssuer(new X500Name("CN=abc\\, d\\\"def, L=a"));
return new LdapName(new X509CertImpl(info).getIssuerX500Principal().getName()).getRdns()
having type CN with value abc, d"ef