Bug 705044 (CVE-2011-0633) - CVE-2011-0633 perl-libwww-perl: no hostname check against SSL certificate name by default
Summary: CVE-2011-0633 perl-libwww-perl: no hostname check against SSL certificate nam...
Keywords:
Status: CLOSED WONTFIX
Alias: CVE-2011-0633
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 705050
Blocks: 734541
TreeView+ depends on / blocked
 
Reported: 2011-05-16 13:35 UTC by Jan Lieskovsky
Modified: 2019-09-29 12:45 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-10-13 13:22:42 UTC
Embargoed:


Attachments (Terms of Use)
Enable SSL checks using IO::Socket::SSL::set_ctx_defaults (508 bytes, text/plain)
2011-09-16 13:13 UTC, Tomas Hoger
no flags Details
Back-port ssl_opts to libwww-perl-5.837 (11.33 KB, patch)
2011-10-12 08:41 UTC, Petr Pisar
no flags Details | Diff
Disable hostname verification by default (1.07 KB, patch)
2011-10-13 11:28 UTC, Petr Pisar
no flags Details | Diff

Description Jan Lieskovsky 2011-05-16 13:35:01 UTC
Common Vulnerabilities and Exposures assigned an identifier CVE-2011-0633 to
the following vulnerability:

The Net::HTTPS module in libwww-perl (LWP) before 6.00, as used in
WWW::Mechanize, LWP::UserAgent, and other products, when running in
environments that do not set the If-SSL-Cert-Subject header, does not
enable full validation of SSL certificates by default, which allows
remote attackers to spoof servers via man-in-the-middle (MITM) attacks
involving hostnames that are not properly validated. NOTE: it could be
argued that this is a design limitation of the Net::HTTPS API, and
separate implementations should be independently assigned CVE
identifiers for not working around this limitation. However, because
this API was modified within LWP, a single CVE identifier has been
assigned.

References:
[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0633
[2] http://cpansearch.perl.org/src/GAAS/libwww-perl-6.00/Changes
[3] http://vttynotes.blogspot.com/2010/12/man-in-middle-fun-with-perl-lwp.html
[4] http://vttynotes.blogspot.com/2011/03/quick-note-on-lwp-and-perl-security-cve.html

Comment 1 Jan Lieskovsky 2011-05-16 13:43:39 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; }

Comment 3 Jan Lieskovsky 2011-05-16 13:52:54 UTC
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.

Comment 4 Jan Lieskovsky 2011-05-16 13:53:46 UTC
Created perl-libwww-perl tracking bugs for this issue

Affects: fedora-all [bug 705050]

Comment 5 Petr Pisar 2011-08-31 08:07:20 UTC
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.

Comment 6 Tomas Hoger 2011-09-16 13:09:21 UTC
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.

Comment 7 Tomas Hoger 2011-09-16 13:13:21 UTC
Created attachment 523559 [details]
Enable SSL checks using IO::Socket::SSL::set_ctx_defaults

Comment 8 Tomas Hoger 2011-10-07 13:54:04 UTC
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.

Comment 9 Petr Pisar 2011-10-10 15:46:05 UTC
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.

Comment 10 Petr Pisar 2011-10-12 08:41:55 UTC
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.

Comment 11 Petr Pisar 2011-10-13 09:40:45 UTC
(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.

Comment 12 Petr Pisar 2011-10-13 11:28:04 UTC
Created attachment 527957 [details]
Disable hostname verification by default

This patch restores default behavior of libwww-perl before version 6.

Comment 13 Tomas Hoger 2011-10-13 13:22:42 UTC
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.

Comment 16 Fedora Update System 2011-10-22 08:24:33 UTC
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.

Comment 17 Fedora Update System 2011-10-22 08:29:14 UTC
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.

Comment 18 Yannick Lavanant 2011-11-07 11:44:29 UTC
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.

Comment 19 Tomas Hoger 2011-11-07 16:12:33 UTC
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

Comment 20 Yannick Lavanant 2011-11-08 09:34:11 UTC
(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


Note You need to log in before you can comment on or make changes to this bug.