.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Net::LDAP::Security 3pm" .TH Net::LDAP::Security 3pm "2015-04-02" "perl v5.20.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Net::LDAP::Security \- Security issues with LDAP connections .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& none .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This document discusses various security issues relating to using \s-1LDAP\s0 and connecting to \s-1LDAP\s0 servers, notably how to manage these potential vulnerabilities: .IP "\(bu" 4 do you know that you are connected to the right server .IP "\(bu" 4 can someone sniff your passwords/userids from the directory connection .IP "\(bu" 4 can someone sniff other confidential information from the directory connection .PP \&\fBNet::LDAP\fR provides ways to address these vulnerabilities: through the use of \s-1LDAPS,\s0 or LDAPv3 and \s-1TLS,\s0 and/or the use of \s-1SASL.\s0 Each of these will be explained below. .SS "How does an \s-1LDAP\s0 connection work" .IX Subsection "How does an LDAP connection work" A normal LDAPv2 or LDAPv3 connection works by the client connecting directly to port 389 (by default), and then issuing various \s-1LDAP\s0 requests like search, add, etc. .PP There is no way to guarantee that an \s-1LDAP\s0 client is connected to the right \s-1LDAP\s0 server. Hackers could have poisoned your \s-1DNS,\s0 so \&'ldap.example.com' could be made to point to 'ldap.hacker.com'. Or they could have installed their own server on the correct machine. .PP It is in the nature of the \s-1LDAP\s0 protocol that all information goes between the client and the server in 'plain text'. This is a term used by cryptographers to describe unencrypted and recoverable data, so even though \s-1LDAP\s0 can transfer binary values like \s-1JPEG\s0 photographs, audio clips and X.509 certificates, everything is still considered \&'plain text'. .PP If these vulnerabilities are an issue to, then you should consider the other possibilities described below, namely \s-1LDAPS,\s0 LDAPv3 and \s-1TLS,\s0 and \&\s-1SASL.\s0 .SS "How does an \s-1LDAPS\s0 connection work" .IX Subsection "How does an LDAPS connection work" \&\s-1LDAPS\s0 is an unofficial protocol. It is to \s-1LDAP\s0 what \s-1HTTPS\s0 is to \s-1HTTP,\s0 namely the exact same protocol (but in this case LDAPv2 or LDAPv3) running over a \fIsecured\fR \s-1SSL \s0(\*(L"Secure Socket Layer\*(R") connection to port 636 (by default). .PP Not all servers will be configured to listen for \s-1LDAPS\s0 connections, but if they do, it will commonly be on a different port from the normal plain text \s-1LDAP\s0 port. .PP Using \s-1LDAPS\s0 can \fIpotentially\fR solve the vulnerabilities described above, but you should be aware that simply \*(L"using\*(R" \s-1SSL\s0 is not a magic bullet that automatically makes your system \*(L"secure\*(R". .PP First of all, \s-1LDAPS\s0 can solve the problem of verifying that you are connected to the correct server. When the client and server connect, they perform a special \s-1SSL \s0'handshake', part of which involves the server and client exchanging cryptographic keys, which are described using X.509 certificates. If the client wishes to confirm that it is connected to the correct server, all it needs to do is verify the server's certificate which is sent in the handshake. This is done in two ways: .IP "1." 4 check that the certificate is signed (trusted) by someone that you trust, and that the certificate hasn't been revoked. For instance, the server's certificate may have been signed by Verisign (www.verisign.com), and you decide that you want to trust Verisign to sign legitimate certificates. .IP "2." 4 check that the least-significant cn \s-1RDN\s0 in the server's certificate's \&\s-1DN\s0 is the fully-qualified hostname of the hostname that you connected to when creating the \s-1LDAPS\s0 object. For example if the server is , then the \&\s-1RDN\s0 to check is cn=ldap.example.com. .PP You can do this by using the cafile and capath options when creating a \&\fBNet::LDAPS\fR object, \fIand\fR by setting the verify option to 'require'. .PP To prevent hackers 'sniffing' passwords and other information on your connection, you also have to make sure the encryption algorithm used by the \s-1SSL\s0 connection is good enough. This is also something that gets decided by the \s-1SSL\s0 handshake \- if the client and server cannot agree on an acceptable algorithm the connection is not made. .PP \&\fBNet::LDAPS\fR will by default use all the algorithms built into your copy of OpenSSL, except for ones considered to use \*(L"low\*(R" strength encryption, and those using export strength encryption. You can override this when you create the \fBNet::LDAPS\fR object using the \&'ciphers' option. .PP Once you've made the secure connection, you should also check that the encryption algorithm that is actually being used is one that you find acceptable. Broken servers have been observed in the field which 'fail over' and give you an unencrypted connection, so you ought to check for that. .SS "How does \s-1LDAP\s0 and \s-1TLS\s0 work" .IX Subsection "How does LDAP and TLS work" \&\s-1SSL\s0 is a good solution to many network security problems, but it is not a standard. The \s-1IETF\s0 corrected some defects in the \s-1SSL\s0 mechanism and published a standard called \s-1RFC 2246\s0 which describes \s-1TLS \&\s0(\*(L"Transport Layer Security\*(R"), which is simply a cleaned up and standardized version of \s-1SSL.\s0 .PP You can only use \s-1TLS\s0 with an LDAPv3 server. That is because the standard (\s-1RFC 4511\s0) for \s-1LDAP\s0 and \s-1TLS\s0 requires that the \fInormal\fR \s-1LDAP\s0 connection (ie., on port 389) can be switched on demand from plain text into a \s-1TLS\s0 connection. The switching mechanism uses a special extended \&\s-1LDAP\s0 operation, and since these are not legal in LDAPv2, you can only switch to \s-1TLS\s0 on an LDAPv3 connection. .PP So the way you use \s-1TLS\s0 with LDAPv3 is that you create your normal LDAPv3 connection using \f(CW\*(C`Net::LDAP::new()\*(C'\fR, and then you perform the switch using \f(CW\*(C`Net::LDAP::start_tls()\*(C'\fR. The \f(CW\*(C`start_tls()\*(C'\fR method takes pretty much the same arguments as \f(CW\*(C`Net::LDAPS::new()\*(C'\fR, so check above for details. .SS "How does \s-1SASL\s0 work" .IX Subsection "How does SASL work" \&\s-1SASL\s0 is an authentication framework that can be used by a number of different Internet services, including LDAPv3. Because it is only a framework, it doesn't provide any way to authenticate by itself; to actually authenticate to a service you need to use a specific \s-1SASL \&\s0\fImechanism\fR. A number of mechanisms are defined, such as \s-1CRAM\-MD5.\s0 .PP The use of a mechanism like \s-1CRAM\-MD5\s0 provides a solution to the password sniffing vulnerability, because these mechanisms typically do not require the user to send across a secret (eg., a password) in the clear across the network. Instead, authentication is carried out in a clever way which avoids this, and so prevents passwords from being sniffed. .PP \&\fBNet::LDAP\fR supports \s-1SASL\s0 using the \fBAuthen::SASL\fR class. Currently the only \fBAuthen::SASL\fR subclasses (ie., \s-1SASL\s0 mechanism) available are \&\s-1CRAM\-MD5\s0 and \s-1EXTERNAL.\s0 .PP Some \s-1SASL\s0 mechanisms provide a general solution to the sniffing of all data on the network vulnerability, as they can negotiate confidential (ie., encrypted) network connections. Note that this is over and above any \s-1SSL\s0 or \s-1TLS\s0 encryption! Unfortunately, perl's \fBAuthen::SASL\fR code cannot negotiate this. .SH "SEE ALSO" .IX Header "SEE ALSO" Net::LDAP, Net::LDAPS, Authen::SASL .SH "ACKNOWLEDGEMENTS" .IX Header "ACKNOWLEDGEMENTS" Jim Dutton provided lots of useful feedback on the early drafts. .SH "AUTHOR" .IX Header "AUTHOR" Chris Ridd .PP Please report any bugs, or post any suggestions, to the perl-ldap mailing list . .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (c) 2001\-2004 Chris Ridd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.