Bug 705044 (CVE-2011-0633)
Summary: | CVE-2011-0633 perl-libwww-perl: no hostname check against SSL certificate name by default | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | [Other] Security Response | Reporter: | Jan Lieskovsky <jlieskov> | ||||||||
Component: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> | ||||||||
Status: | CLOSED WONTFIX | QA Contact: | |||||||||
Severity: | medium | Docs Contact: | |||||||||
Priority: | medium | ||||||||||
Version: | unspecified | CC: | mmaslano, perl-maint-list, ppisar, psabata, yannick | ||||||||
Target Milestone: | --- | Keywords: | Security | ||||||||
Target Release: | --- | ||||||||||
Hardware: | All | ||||||||||
OS: | Linux | ||||||||||
Whiteboard: | |||||||||||
Fixed In Version: | Doc Type: | Bug Fix | |||||||||
Doc Text: | Story Points: | --- | |||||||||
Clone Of: | Environment: | ||||||||||
Last Closed: | 2011-10-13 13:22:42 UTC | Type: | --- | ||||||||
Regression: | --- | Mount Type: | --- | ||||||||
Documentation: | --- | CRM: | |||||||||
Verified Versions: | Category: | --- | |||||||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||
Cloudforms Team: | --- | Target Upstream Version: | |||||||||
Embargoed: | |||||||||||
Bug Depends On: | 705050 | ||||||||||
Bug Blocks: | 734541 | ||||||||||
Attachments: |
|
Description
Jan Lieskovsky
2011-05-16 13:35:01 UTC
Public PoC from [3]: ==================== #!/usr/bin/perl require LWP::UserAgent; my $ua = LWP::UserAgent->new; # If no If-SSL-Cert-Subject header exists, no hostname validation is on # Here's a certificate check that can by bypassed by anyone. Think attacker.domain.combinationlockfactory.com #$ua->default_header("If-SSL-Cert-Subject"=>'domain.com'); # Any of the following lines will validate https://www.godaddy.com... #$ua->default_header("If-SSL-Cert-Subject"=>'Domain Control Validated'); #$ua->default_header("If-SSL-Cert-Subject"=>'www.Go'); #$ua->default_header("If-SSL-Cert-Subject"=>'www.GoDaddy.com'); $ua->timeout(10); my $response = $ua->get('https://www.godaddy.com/'); if ($response->is_success) { print $response->content; } else { die $response->status_line; } This issue affects the versions of the perl-libwww-perl package, as shipped with Red Hat Enterprise Linux 5 and 6. -- This issue affects the versions of the perl-libwww-perl package, as shipped with Fedora release of 13 and 14. Created perl-libwww-perl tracking bugs for this issue Affects: fedora-all [bug 705050] I arranged test with certificate issued for different name, and even perl-libwww-perl-6.02-3.fc16.noarch in F17 does not check hostname by default. Private key (authority and server) (evil.key): -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAxwEKZHck9pJGh7S45uruYWjIa2aAuIa24XwFioeblZW8S0o+ FjtkgsSs3EnuBHS/wOhyOZNUxK74lAQ67X5UEupwnG/6g32DP9d08GI6qiwLHHes YI2m866qBEg/0M/tomrobw625c2lHCb2SwLPHpH0o8mRSEPCtUFesjkn0OBDWGpz +JNYPbx4gn502Lpy/SHM6nr+U5fgVve01PhitzfnGgbm3/MI4bzPHGmuuqXQHq5m PWVqrU9lmttyTsxWfsw7NJk/OMojqA7PfVszUIP324CRNT8Mr5Wa3KqBJtDCtnbj BC2SNJzC0pw5tiU6u68PNF1fpdrPHPGDJZ6FmwIDAQABAoIBABaoLiw5CmrORZxu vXyA8+oAOY1Mysv3fnvWmHTospSJyznRNpdmZK+kv7+G5UP5nNlUPakDdqu79g44 GxNuBhlvOqn878snr5lFqQkzTdWRFSTFFUma5w6obK/3H9jgy3/p5xO526X3T1yQ rQrmQ3mKCY3aRaGyIUlsq2DkM/3KTzU3bZiMixycV8d2mNGSIweO8TWc0eRxOxYj 5/s1pEhcU5Up04lmqTs+0G9pcoLJBHuknREwaillICGRadNr4dfQ0u7ASmLTx1PJ tiKwrxb1JU8DZmNt6bZuwVfY8dDVtki61K+s2UbDGGJkUwvO4iUd6JBwHLmNi5Ij wQn7VV0CgYEA1QRjT9Tuiiqr1wtTQthR5Ge3iFJqdIinuBtUwhyTqZWtO2Dcf8Sd FJMpL7zWCYjnSmSyfv+9C/8G9c2/zo43YMNSgU3lxteWrFJQ5end9GEiXhQQLxHh l3MJtsNQ1/1LD3sG1NhnHrPQCJsAvFxot2QOtfZ9j3cYXcSF4kVWKvcCgYEA7yjL FsJjivofoLM/s+Q1JAvNBL4Chc3IFS2woihgExK7wJ48X8G61jQfW9g2ewmD8mnR D4tIkNkFzo6pyZEkVHz+A9F9esb91c3BRwEQC+C0tMrUFwplBLCMPeaHLw/6WSM2 F6hIc40AShyMFjqaXA7WRt/PEIqhiSZaDkxLDX0CgYEAjcrl8HXkcsQErpgzTAOC P29qk6uIgRmVys8mlC9Be1jOfv/yxnmxtchfWg9wydf/XV26Ex9YT2vqziOu0WeJ JTfe64NWuA05lmsUvnX18H3XypfAThSw/YbtqGJKpftMw3k5CuUhfyZiC9hhnQBG FAzeXfE9kwnLhl8SX5OXz/ECgYALpugmJrhk2ATcdn8/C3pPVEfb2EoVLM53wa8e Z2su4rXFD7CPVcf9kbKJbgJRgkgscl1eLYIOlJRE2QyKpoinmSNjGjzL05Agb5Lg G7wlaABF4q/so3QCg3uBtI6Xi2a+GwoSov9Mqez+r19f4eENZSepclQLUUXHgdfX ZH4vnQKBgE2GlH7L6ELgJk0EDACf11LjzxVpvxgF6ptG+HNHcfCstg3O0kK2GM/s D15KiCyECP7C3aQubwkMUzxXe0AZ1tlhvhFWr2UZLcbiYPoi8IpVolSXXHbux37v h4OS1EWq5uQ0NEu+hYXT4P27xMdxBHQvxsB0lcCwpyc5mV3tCGIJ -----END RSA PRIVATE KEY----- Certificate (authority and server, both CN and SubjectAltName are set to "evil") (evil.cert): -----BEGIN CERTIFICATE----- MIIDBTCCAe2gAwIBAgIETl3a2zANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRl dmlsMB4XDTExMDgzMTA2NTUyNVoXDTE3MDQwOTA2NTUyN1owDzENMAsGA1UEAxME ZXZpbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcBCmR3JPaSRoe0 uObq7mFoyGtmgLiGtuF8BYqHm5WVvEtKPhY7ZILErNxJ7gR0v8DocjmTVMSu+JQE Ou1+VBLqcJxv+oN9gz/XdPBiOqosCxx3rGCNpvOuqgRIP9DP7aJq6G8OtuXNpRwm 9ksCzx6R9KPJkUhDwrVBXrI5J9DgQ1hqc/iTWD28eIJ+dNi6cv0hzOp6/lOX4Fb3 tNT4Yrc35xoG5t/zCOG8zxxprrql0B6uZj1laq1PZZrbck7MVn7MOzSZPzjKI6gO z31bM1CD99uAkTU/DK+VmtyqgSbQwrZ24wQtkjScwtKcObYlOruvDzRdX6Xazxzx gyWehZsCAwEAAaNpMGcwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHREECDAGggRldmls MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHpAAwHQYDVR0OBBYE FGJjr3FfRfHs8cVw7QQ2QhdIjQ7bMA0GCSqGSIb3DQEBBQUAA4IBAQCKkRa3p0qZ XFyG+zv9skgVz0/5I/rYe7bf5VdN4KB7MPkSiEDIWjap2ayxOxQ3TF0JI4oGvvBl 9UzP3pg9AOGyzJ8BEto+lrZVe+jzPD5kIiaHWYf+oexHhRaO/V6Nw5YGC3uKjJhS k3gvHL2ep5uc8wM3wAB83/MW9zqdqCNCLrZiqZ8zTXbJnIX44LwE4dHH8z5/bDfC ctEWy88m7brJdOMS1scmAVUjoPJ9XosMVJJKzIJFxSoFKXGz0OUuYqRPSODSe643 bhHbZ1Rlj7Gn8E+SV9uylvV/eytm4buk/1ybZaT+gp54SDJIvK+m6mwxEHk2GVE1 PUcgdFkhpwWA -----END CERTIFICATE----- Run HTTPS server as: $ gnutls-serv --x509keyfile evil.key --x509certfile evil.cert --port 6666 --disable-client-cert --http And check clients now: Wget verifies hostname: $ wget -O /dev/null https://localhost:6666/ --ca-certificate=evil.cert --2011-08-31 09:49:43-- https://localhost:6666/ Resolving localhost... ::1, 127.0.0.1 Connecting to localhost|::1|:6666... failed: Connection refused. Connecting to localhost|127.0.0.1|:6666... connected. ERROR: no certificate subject alternative name matches requested host name “localhost”. To connect to localhost insecurely, use ‘--no-check-certificate’. LWP::UserAgent (perl-libwww-perl-6.02-3.fc16) does not by default: $ HTTPS_CA_FILE=evil.cert perl -MLWP::UserAgent -le 'my $ua=LWP::UserAgent->new; print $ua->get(q{https://localhost:6666/})->status_line' 200 OK Explicitly requested verification works: $ PERL_LWP_SSL_VERIFY_HOSTNAME=1 HTTPS_CA_FILE=evil.cert perl -MLWP::UserAgent -le 'my $ua=LWP::UserAgent->new; print $ua->get(q{https://localhost:6666/})->status_line' 500 Can't connect to localhost:6666 (certificate verify failed) LWP::UserAgent documentation says: > "verify_hostname" => $bool > When TRUE LWP will for secure protocol schemes ensure it > connects to servers that have a valid certificate matching the > expected hostname. If FALSE no checks are made and you can't > be sure that you communicate with the expected peer. The no > checks behaviour was the default for libwww-perl-5.837 and > earlier releases. > > This option is initialized from the > PERL_LWP_SSL_VERIFY_HOSTNAME environment variable. If this > envirionment variable isn't set; then "verify_hostname" > defaults to 1. So libwww-perl 6.02 conflicts with its own documentation and does not fix this problem. It still requires application modification. Also if I understand this problem correctly, libwww-perl before 6.00 has no way how to enable hostname verfification in general. One can explicitly compare hostname against arbitrary string only. The original report and CVE assignment sounds somewhat odd to me. There's a long post about LWP not checking connection hostname against SSL certificate hostname by default, but it does not mention that there's no SSL certificate checking at all, so any check configured using If-SSL-Cert-Subject header can be bypassed by a MITM attacker that generates (self-signed) certificate with expected subject (and issuer). (In reply to comment #5) > I arranged test with certificate issued for different name, and even > perl-libwww-perl-6.02-3.fc16.noarch in F17 does not check hostname by default. My testing shows it does. Both certificate and name verification is done by default. > $ HTTPS_CA_FILE=evil.cert If you look into LWP/UserAgent.pm, you should see that the use of HTTPS_CA_FILE or HTTPS_CA_DIR environment variable disabled name verification, reportedly for Crypt::SSLeay compatibility. PERL_LWP_SSL_CA_FILE / PERL_LWP_SSL_CA_PATH can be used instead. > Also if I understand this problem correctly, libwww-perl before 6.00 has no > way how to enable hostname verfification in general. One can explicitly > compare hostname against arbitrary string only. Right, there does not seem to be an LWP-way to enable SSL certificate and hostname check in pre-6.00. With sufficiently recent IO::Socket::SSL, it can be asked directly to do the checks (LWP fix seems to add LWP config options that are translated to IO::Socket::SSL options). Hostname checking got added to IO::Socket::SSL in version 1.14 (see bug #509819, comment #2), hence only available in RHEL-6 and later. I'm going to attach an example that enables checks with 5.x LWP. I'm quite hesitant to push such change to released products, as it's quite likely to break scripts in use. We can consider adding LWP options that can be used to enable checks, but they are not too likely to get used if we divert from new upstream defaults and keep old no-checks default. Created attachment 523559 [details]
Enable SSL checks using IO::Socket::SSL::set_ctx_defaults
Petr, what do you think, would it make sense to backport support for setting SSL options via LWP UserAgent object without enabling them by default? Enabling SSL checking by default rather tricky change for already released product, especially if we don't rebase to upstream 6.x. I see code before version 6 is unfortunate giving no easy way how to check certificate name. Even if I think the default behavior should be to check to resolve this vulnerability, I will try to back-port the ssl_opts and environment variables handling. I think the environment variable override could allow to enable names check selectively without touching existing applications. Created attachment 527625 [details]
Back-port ssl_opts to libwww-perl-5.837
This back-ports changes from libwww-perl-6 to support ssl_opts and all the control environment variables. The CA file defaults to standard NSS bundle.
This patch keeps verification enabled by default as libwww-perl-6 does. Default state can be implemented by patch on top of this one.
This patch does not provide support for old IO::Socket::SSL. This will be solved in separate patch.
(In reply to comment #1) > Public PoC from [3]: [...] > # Any of the following lines will validate https://www.godaddy.com... > #$ua->default_header("If-SSL-Cert-Subject"=>'Domain Control Validated'); > #$ua->default_header("If-SSL-Cert-Subject"=>'www.Go'); > #$ua->default_header("If-SSL-Cert-Subject"=>'www.GoDaddy.com'); [...] > my $response = $ua->get('https://www.godaddy.com/'); The <https://www.godaddy.com/> test is wrong because RFC 2459 (Internet X.509 Public Key Infrastructure Certificate and CRL Profile) says the host name comparison is case-insensitive. Thus conforming code should accept certificate for `www.GoDaddy.com' when connecting to <https://www.godaddy.com/>. I can see the point this test exhibits. I want just note I discourage to use _this domain name and with this certificate_ as test case for this vulnerability. Created attachment 527957 [details]
Disable hostname verification by default
This patch restores default behavior of libwww-perl before version 6.
Thank you, Petr. As we can't flip this default for released product, I have filed RFE bug to add ssl_opts support - bug #745800. I'm also closing this wontfix for released products. Future products using LWP 6 or later will use new upstream default. perl-libwww-perl-5.837-4.fc15 has been pushed to the Fedora 15 stable repository. If problems still persist, please make note of it in this bug report. perl-libwww-perl-5.837-3.fc14 has been pushed to the Fedora 14 stable repository. If problems still persist, please make note of it in this bug report. Since perl-libwww-perl.noarch 0:5.837-3.fc14 has been published the VMWaare Command line interface script I used to use to manage ESX servers are no longer working. I tried to re-issue self signed certificates to make sure the server name matched, but I still get no connectivity. I had to downgrade perl-libwww-perl to get my code to work again. Yannick, what you describe does not sound surprising, given that the update enabled all SSL certificate checks by default (there's no point in only checking hostname, if you don't check the cert is properly signed by the CA you trust). Hence those scripts need to be told which CA to trust, or disable the checks if you want to use the old insecure way. Default trusted CA list is ca-bundle.crt from ca-certificates, but adding self-signed server certificate there is not the best idea. Comments above hint some environment variables you can use to change LWP's SSL checking behaviour without modifying scripts. You can try these two first: PERL_LWP_SSL_CA_FILE=/path/to/you/server.crt - to check against correct issuing certificate PERL_LWP_SSL_VERIFY_HOSTNAME=0 - to disable checks (In reply to comment #19) > Yannick, what you describe does not sound surprising, given that the update > enabled all SSL certificate checks by default (there's no point in only > checking hostname, if you don't check the cert is properly signed by the CA you > trust). Hence those scripts need to be told which CA to trust, or disable the > checks if you want to use the old insecure way. Default trusted CA list is > ca-bundle.crt from ca-certificates, but adding self-signed server certificate > there is not the best idea. Comments above hint some environment variables you > can use to change LWP's SSL checking behaviour without modifying scripts. You > can try these two first: > > PERL_LWP_SSL_CA_FILE=/path/to/you/server.crt - to check against correct issuing > certificate > > PERL_LWP_SSL_VERIFY_HOSTNAME=0 - to disable checks Ah fair enough. Yeah, I added the environment setting and that worked. Thanks for that Tomas. I know self signed certs are not secure, but these servers are not accessible from the outside so the risk is acceptable. Thanks again as this was becoming a pain having to downgrade after each general update. Yannick |