HTTPS client certificate authentication security issues. Part 1/3
Sometimes we need to improve web authentication by client certificates. It’s much better than passwords, allows to enable 2nd factor because of hardware keys and just sounds so strong, isn’t it? ;)
Let’s look inside it to understand how secure is it and what to check to be sure, that you didn’t reduce the security level of your company when implemented client certificate authentication. As always, it’s not a cryptography-related question, but an implementation risk. In this article, I’ll sum up all of our penetration testing experience to make client certificate authentication security checklist.
Certificate status headers spoofing
Load balancers set HTTP headers for the backends. Backends trust data from these headers. So, the following schema is usual:
That’s why sometimes it’s possible to send SSL header right inside initial HTTP request from the client to bypass this mechanism.
X-Client-Info, X-Client-Certificate, X-SSL-Certificate, SSLClientCertStatus and lot of others typically used when load balancer like F5, NetScaler, Nginx, HAProxy or Apache validates user certificate and forward requests to application servers. I uploaded the list of those headers I know to the public repo: https://github.com/wallarm/cert-headers.
Actually, there are two issues possible:
- identity spoofing, when you need any valid certificate to proxy your request to the backend, but then injected headers identifies you as another user;
- authentication bypass, when load balancer forwards any requests to backends and you can identify yourself as a valid user just because of the HTTP header in your request
Obviously, load balancers try to protect HTTP header redefinition by cutting it from the original client request. At the same time, it’s totally unguaranteed, that backend and load balancer parse those headers in the same way. As the result, following tricks helps:
- Spaces, tabs, 0x00–0x20, etc prefixes and postfixes for the spoofed header. Like this (space before the first byte, space before the colon delimiter, ):
GET / HTTP/1.1
X-SSL-CLIENT-CN : admin
- Mixing lower/uppercases in header names
- Multiple colons delimiters. Some application servers parse “HOST:::: aaa” normally as a “HOST:aaa”
- Protocol manipulations. Try HTTP/1.0 and 0.9. Sometimes it confuses load balancers.
That’s all for now. In the next parts, I’ll try to explain other types of issues, like certificate validation logic errors, SSRF, and some other tricks.
Have a good bug hunting!