Comment puis-je obtenir LWP pour valider les certificats de serveur SSL?
Comment puis-je obtenir LWP pour vérifier que le certificat du serveur, je me connecte à est signé par une autorité de confiance et délivré à l'accueil correct? Aussi loin que je peux dire, il n'a même pas vérifier que le certificat prétend être le nom d'hôte que je suis connecté. Ça semble être un trou de sécurité majeur (surtout avec la récente DNS vulnérabilités).
Mise à jour: Il s'avère que je voulais, c'était HTTPS_CA_DIR
, parce que je n'ai pas de ca-bundle.crt. Mais HTTPS_CA_DIR=/usr/share/ca-certificates/
a fait le tour. Je suis marquant la réponse que accepté de toute façon, parce que c'était assez proche.
Mise à jour 2: Il s'avère que HTTPS_CA_DIR
et HTTPS_CA_FILE
s'appliquent uniquement si vous utilisez Net::SSL sous-jacents de la bibliothèque SSL. Mais LWP travaille également avec IO::Socket::SSL, qui ignore les variables d'environnement et heureux de parler à n'importe quel serveur, n'importe quel certificat qu'il présente. Est-il plus général de la solution?
Mise à jour 3: Malheureusement, la solution n'est pas encore terminée. Ni Net::SSL ni IO::Socket::SSL est en train de vérifier le nom de l'hôte contre le certificat. Cela signifie que quelqu'un peut obtenir une légitime certificat pour certains domaine, et alors l'identité de n'importe quel autre domaine sans LWP se plaindre.
Mise à jour 4: LWP 6.00 résout enfin le problème. Voir ma réponse pour plus de détails.
Vous devez vous connecter pour publier un commentaire.
À cette faille de sécurité a enfin été corrigé dans la version 6.00 de libwww-perl. À partir de cette version, par défaut LWP::UserAgent vérifie que les serveurs HTTPS présenter un certificat valide correspondant au nom d'hôte devrait (sauf
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}
est définie sur la valeur false ou, pour la compatibilité ascendante si cette variable n'est pas définie, soit$ENV{HTTPS_CA_FILE}
ou$ENV{HTTPS_CA_DIR}
est réglé).Cela peut être contrôlée par le nouveau ssl_opts option de LWP::UserAgent. Voir ce lien pour plus de détails sur la façon dont le Certificat les certificats d'Autorité sont situés. Mais être prudent, la façon de LWP::UserAgent l'habitude de travailler, si vous fournissez un
ssl_opts
de hachage pour le constructeur, puisverify_hostname
par défaut à 0 au lieu de 1. (Ce bug a été fixée dans la LWP 6.03.) Pour être sûr, toujours spécifierverify_hostname => 1
dans votressl_opts
.Donc
use LWP::UserAgent 6;
devrait être suffisant pour avoir des certificats de serveur de validation.Il y a deux moyens de le faire selon laquelle le protocole SSL module que vous avez installés. Le LWP docs vous recommandons d'installer Crypt::SSLeay. Si c'est ce que vous avez fait, le réglage du
HTTPS_CA_FILE
variable d'environnement pour pointer vers votre ca-bundle.le crt devrait faire l'affaire. (le Crypt::SSLeay docs mentionne cela, mais c'est un peu la lumière sur les détails). Aussi, selon votre configuration, vous devrez peut-être définir laHTTPS_CA_DIR
variable d'environnement à la place.Exemple pour Crypt::SSLeay:
Noter que get ne
die
, mais retourne uneundef
.Alternativement, vous pouvez utiliser le
IO::Socket::SSL
module (également disponible sur le CPAN). Pour faire de cet vérifier le certificat du serveur, vous devez modifier le SSL contexte par défaut:Cette version provoque également
get()
pour retourner le fnud, mais affiche un message d'avertissement àSTDERR
lorsque vous l'exécuter (en tant que bien comme un tas de débogage si vous importez le debug* symboles de IO::Socket::SSL):J'ai atterri sur cette page, vous cherchez un moyen de contourner la validation de SSL, mais toutes les réponses étaient toujours très utile. Voici mes conclusions. Pour ceux qui cherchent à contourner la validation de SSL (pas recommandé, mais il peut y avoir des cas où vous avez absolument), je suis sur lwp 6.05 et cela a fonctionné pour moi:
Je l'ai aussi testé sur une page avec un POST et il a également travaillé. La clé est d'utiliser Net::SSL avec verify_hostname = 0.
Si vous use LWP::UserAgent directement (et non par LWP::Simple), vous pouvez valider le nom d'hôte dans le certificat par l'ajout du "Si-SSL-Cert-Sujet" en-tête de votre HTTP::Request objet. La valeur de l'en-tête est traitée comme une expression régulière pour être appliquée sur l'objet du certificat, et si elle ne correspond pas, la demande échoue. Par exemple:
imprime
Toutes les solutions présentées ici contiennent une faille de sécurité importante en ce qu'elles uniquement de vérifier la validité du certificat de la chaîne de confiance, mais ne comparez pas le Nom Commun du certificat pour le nom de l'hôte auquel vous vous connectez. Ainsi, un homme dans le milieu peut présenter l'arbitraire d'un certificat pour vous et LWP sera heureux de l'accepter dès lors qu'il est signé par une autorité de certification de confiance. Le faux Nom Commun du certificat n'est pas pertinent car il n'est jamais vérifié par LWP.
Si vous utilisez
IO::Socket::SSL
comme LWP du backend, vous pouvez activer la vérification du Nom Commun en définissant laverifycn_scheme
paramètre comme ceci:$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}
,$ENV{HTTPS_CA_FILE}
, ou$ENV{HTTPS_CA_DIR}
ensemble, tout ce qui peut désactiver le nom d'hôte de la vérifier.lwp-request -m HEAD https://host1
œuvres.lwp-request -m HEAD https://host1-alt
échoue parce que le nom ne correspond pas.PERL_LWP_SSL_VERIFY_HOSTNAME=0 lwp-request -m HEAD https://host1-alt
œuvres.Vous pouvez également envisager de Net::SSLGlue ( http://search.cpan.org/dist/Net-SSLGlue/lib/Net/SSLGlue.pm ) Mais, prenez garde, il dépend de la récente IO::Socket::SSL et Net::SSLeay versions.
Vous êtes en droit d'être inquiets à ce propos. Malheureusement, je ne pense pas que c'est possible de le faire à 100% en toute sécurité dans le cadre de toute faible niveau de SSL/TLS liaisons j'ai regardé pour Perl.
Essentiellement, vous devez passer dans le nom d'hôte du serveur auquel vous voulez vous connecter à la bibliothèque SSL avant l'établissement de la liaison est en cours. Alternativement, vous pouvez vous arranger pour un rappel de se produire au bon moment et annuler la poignée de main de l'intérieur de la fonction de rappel si ce n'est pas découvrez. Des gens qui écrivent des liaisons Perl pour OpenSSL semblait avoir des difficultés à faire l'interface de rappel de manière cohérente.
La méthode pour vérifier le nom d'hôte sur le serveur cert dépend du protocole, trop. De sorte que devrait être un paramètre d'une fonction parfaite.
Vous pourriez vouloir voir s'il y a des liaisons de Netscape/Mozilla NSS bibliothèque. Il semblait plutôt bonne à faire cela quand je l'ai regardé.
Il suffit de faire exécuter la commande suivante dans le Terminal:
sudo cpan installer Mozilla::CA
Il doit résoudre.