On 24 Jun 13:29, Froehlich, Dominik wrote:
> Hi,
>
> Not sure if you would call this a security issue, hence I am asking this on
> the mailing list prior to opening a github issue:
>
> I’ve noticed that it is really easy to bypass the check on client
> certificates of a domain when the client can present a valid certificate for
> another domain.
>
> Consider this HAproxy config:
>
> global
> log /dev/log len 4096 format rfc3164 syslog info
>
> defaults
> log global
> mode http
> timeout connect 5s
> timeout client 1h
> timeout server 5s
>
> frontend myfrontend
> bind :443 ssl crt /etc/cert/server.pem crt-list /crt-list
> log-format "%ci:%cp [%tr] (%ID) %ft %b/%s %TR/%Tw/%Tc/%Tr/%Tt %ST %B %CC
> %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r %sslc %sslv"
>
> capture request header Host len 256
>
> http-request set-header X-SSL-Client %[ssl_c_used]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-Session-ID %[ssl_fc_session_id,hex]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-Verify %[ssl_c_verify]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-Subject-DN %{+Q}[ssl_c_s_dn]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-Subject-CN %{+Q}[ssl_c_s_dn(cn)]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-Issuer-DN %{+Q}[ssl_c_i_dn]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore]
> if { ssl_c_used }
> http-request set-header X-SSL-Client-NotAfter %{+Q}[ssl_c_notafter]
> if { ssl_c_used }
>
> use_backend bob if { hdr(host) -m dom bob.com }
> use_backend alice if { hdr(host) -m dom alice.com }Thanks for taking the time to write this report. SNI and host header are indeed different. You should consider using req.ssl_sni instead of hdr(host). Regards, > > default_backend alice > > backend alice > server alice localhost:8080 check > > backend bob > server bob localhost:8081 check > > --- > So this HAproxy hosts two domains alice.com and bob.com. It uses the > following crt-list to make TLS connections: > > /etc/cert/server.pem [ca-file /alice.ca.pem verify required] *.alice.com > /etc/cert/server.pem [ca-file /bob.ca.pem verify required] *.bob.com > > --- > So any client connecting to alice.com must present a certificate signed by > the Alice CA and any client connecting to bob.com must present a certificate > signed by the Bob CA. > > > However, I noticed that HAproxy does allow me to “spoof” the host header to > bob.com even though I did a TLS handshake with alice.com. The request will be > forwarded to bob.com with the alice.com certificate: > > curl -v -k --cert alice.com.crt --key alice.com.key --resolve > www.alice.com:9443:127.0.0.1<http://www.alice.com:9443:127.0.0.1> > https://www.alice.com:9443/headers -H "host: www.bob.com<http://www.bob.com>" > > * Added www.alice.com:9443:127.0.0.1 to DNS cache > * Hostname www.alice.com was found in DNS cache > * Trying 127.0.0.1... > * TCP_NODELAY set > * Connected to www.alice.com (127.0.0.1) port 9443 (#0) > * ALPN, offering h2 > * ALPN, offering http/1.1 > * successfully set certificate verify locations: > * CAfile: /etc/ssl/cert.pem > CApath: none > (…) > > GET /headers HTTP/1.1 > > Host: www.bob.com > > User-Agent: curl/7.64.1 > > Accept: */* > > > < HTTP/1.1 200 OK > < date: Thu, 24 Jun 2021 13:07:17 GMT > < content-length: 578 > < content-type: text/plain; charset=utf-8 > < > Hello from Bob! > > ----- Headers Received ----- > Accept : [*/*] > User-Agent : [curl/7.64.1] > X-Ssl-Client : [1] > X-Ssl-Client-Issuer-Dn : > [/C=US/ST=California/L=AliceLand/O=Alice.com/CN=Alice.com Root > CA/[email protected]] > X-Ssl-Client-Notafter : [220624125634Z] > X-Ssl-Client-Notbefore : [210624125634Z] > X-Ssl-Client-Session-Id : > [D941ECCAACAFEBC5CB3AE17794B54DC3DFC7549C401DB20D7EC5ADC48244D3D0] > X-Ssl-Client-Subject-Cn : [Alice] > X-Ssl-Client-Subject-Dn : > [/C=US/ST=Michigan/L=Detroit/O=Alice.com/CN=Alice/[email protected]] > X-Ssl-Client-Verify : [0] > > --- > So basically anyone who can get a client certificate from Alice.com can use > it to also connect to Bob.com without getting validated against Bob’s CA. > > I’ve tested this with HAproxy 2.2.14. > > My questions: > > * HAproxy does seem to treat SNI (L5) and HTTP Host Header (L7) as > unrelated. Is this true? > * Applications offloading TLS to HAproxy usually trust that mTLS requests > coming in are validated correctly. They usually don’t revalidate the entire > certificate again and only check for the subject’s identity. Is there a way > to make SNI vs host header checking more strict? > * What’s the best practice to dispatch mTLS requests to backends? I’ve > used a host header based approach here but it shows the above vulnerabilities. > > > Best regards, > Dom -- (o- Julien Pivotto //\ Open-Source Consultant V_/_ Inuits - https://www.inuits.eu
signature.asc
Description: PGP signature

