2

I want to access a website where the certificate cannot be verified (hostname not correct and I cannot change/update the certificate on the server which my application point). I'm using Mojo::UserAgent to get request. So how would go about ignoring this and continues to connect to the website? I've seen that there is not an option.

I don't want to use LWP::UserAgent.

I've done it using WWW::Curl and WWW::Curl::Easy but I want to clean the code using Mojo::UserAgent (as used in my entire application).

serenesat
  • 4,611
  • 10
  • 37
  • 53

3 Answers3

4

hostname not correct ... So how would go about ignoring this and continues to connect to the website?

It is a very bad idea just to abandon any kind of validation just because the hostname does not match the certificate. Why do you use TLS at all?

A much better way is to know up front which certificate you expect and verify that you exactly get this one. This can easily be done with the option SSL_fingerprint. Unfortunately Mojo::UserAgent does not offer a way to set connection specific arguments, so you need to set it immediately before the connection and back before you do other connections:

use IO::Socket::SSL 1.980;
IO::Socket::SSL::set_client_defaults(
    SSL_fingerprint => "sha256$55a5dfaaf..."
);
... use Mojo::UserAgent to connect ..
IO::Socket::SSL::set_client_defaults(); # set back

For more information about to use this option and how to get the fingerprint see Certificate error in Perl.

Another way in case only the hostname is bad would be to use the SSL_verifycn_name option to specify the hostname you expect inside the certificate.

IO::Socket::SSL::set_client_defaults(
    SSL_verifycn_name => 'foo.example.com',
);

Another way could be done with the set_args_filter_hack function which is intended to deal with modules which set strange defaults or which don't let the user set its own values:

my $hostname = undef;
IO::Socket::SSL::set_args_filter_hack(
    sub {
        my ($is_server,$args) = @_;
        $args->{SSL_verifycn_name} = $hostname if $hostname;
    }
);
...
$hostname = 'foo.example.com';
... do something with Mojo::UserAgent ...
$hostname = undef;

This way you can adapt the settings for each SSL handshake.

For more information see the documentation of IO::Socket::SSL, especially the part about the common usage errors. This part also documents what you should do instead of disabling any kind of validation if some part of the certificate is wrong.


'SSL connect attempt failed error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol'
curl ... SSL connection using TLS_RSA_WITH_RC4_128_MD5

My guess is what you are facing here is unrelated to the certificate validation. Given that this server is using a very old cipher RC4-MD5 I will assume that the server can only handle SSL 3.0. This version is disabled since a while for security reasons in IO::Socket::SSL. To explicitly use this insecure version temporarily:

IO::Socket::SSL::set_client_defaults(
    SSL_version => 'SSLv3'
);
Community
  • 1
  • 1
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
2

Mojo::UserAgent uses IO::Socket::SSL for SSL/TLS support, so you can disable server certificate verification using

IO::Socket::SSL::set_defaults(
    SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
);
hobbs
  • 223,387
  • 19
  • 210
  • 288
  • I've added the code as you wrote but my log shown that it's not useful :( Error result: `'error' => { 'message' => 'SSL connect attempt failed error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol' },` – Elia Bellussi Feb 04 '16 at 09:47
  • @Elia Bellussi, Actually, I think this Answer does indeed perform the requested task, and that you are now experiencing a second [problem](http://stackoverflow.com/q/15166950/589924). – ikegami Feb 04 '16 at 12:59
  • 1
    With `curl -k` it's ok. Here the code for options: `$curl->setopt(CURLOPT_SSL_VERIFYPEER,0);` and the output: `* warning: ignoring value of ssl.verifyhost * skipping SSL peer certificate verification * SSL connection using TLS_RSA_WITH_RC4_128_MD5 `. So I thought that it's only a problem of certificate. – Elia Bellussi Feb 04 '16 at 14:50
  • 1
    This disables any kind of validation for every user of IO::Socket::SSL (LWP, Mojo, Net::SMTP, ....) within this program. If you do this within a module this would affect every program using this module. I consider this a bad idea. – Steffen Ullrich Feb 04 '16 at 17:58
  • @SteffenUllrich nothing is stopping you from setting it back afterwards. – hobbs Feb 04 '16 at 18:00
  • 1
    Yes, the only things which stop you are that you might not be aware that this affects anything else using IO::Socket::SSL as a side effect and that you don't know that you need to and how you should reset it. Maybe you could add these infomation to your answer. – Steffen Ullrich Feb 04 '16 at 18:29
2

This is an old question, but Mojolicious is alive and kicking. As such I've battled with this recently. Directly from the documents:

my $bool = $ua->insecure;
$ua      = $ua->insecure($bool);

Do not require a valid TLS certificate to access HTTPS/WSS sites, defaults to the value of the MOJO_INSECURE environment variable.

# Disable TLS certificate verification for testing
say $ua->insecure(1)->get('https://127.0.0.1:3000')->result->code;

In my application $bool is set from a configuration file, so I can switch it back on, where we need it.

Hugh Barnard
  • 352
  • 2
  • 12