Differences between revisions 2 and 5 (spanning 3 versions)
Revision 2 as of 2010-11-09 14:59:29
Size: 748
Editor: techtonik
Comment: + information about limitation across Python versions
Revision 5 as of 2010-11-09 18:52:15
Size: 2208
Editor: techtonik
Comment: testcase for server certificate vulnerability in Python 2.x ssl code
Deletions are marked like this. Additions are marked like this.
Line 5: Line 5:
SSL support is available from http://pypi.python.org/pypi/ssl Unfortunately, no binaries are available for Windows, and that's a major showstopper when using Python 2.5. SSL support is available from http://pypi.python.org/pypi/ssl Unfortunately, there are no binaries for Windows, and that's a major showstopper when using Python 2.5.
Line 8: Line 8:
SSL module from http://pypi.python.org/pypi/ssl is bundled with installer. But it has some bugs (unfortunately, Python bug tracker doesn't allow to query these reliably) SSL module from http://pypi.python.org/pypi/ssl is bundled with installer. It has a serious security issue that allows successful MITM attack using valid certificate from an other site - http://bugs.python.org/issue1589 Basically, the module validates that certificate is correct and correctly signed by root certificate, but it does not check that certificate actually belongs to the connected site, i.e. that site name matches the name specified in certificate.
Line 10: Line 10:
=== Validating server certificate === === Validating server identity ===
Client need to connect to server over SSL, fetch its certificate, check that the certificate is valid (signed properly) and belongs to this server (server name).

Let's illustrate '''ssl''' vulnerability in Python 2.x versions. The following snippet should fail - it replaces HOST "www.google.com" to connect to with its IP address. If you try to use this IP in Chrome like https://74.125.232.50 - it will show an error, but '''ssl''' library will not.

{{{
import socket
import ssl

HOST = "www.google.com"
PORT = 443

# replace HOST name with IP, this should fail connection attempt,
# but it doesn't in Python 2.x
HOST = socket.getaddrinfo(HOST, PORT)[0][4][0]
print(HOST)

# create socket and connect to server
# server address is specified later in connect() method
sock = socket.socket()
sock.connect((HOST, PORT))

# wrap socket to add SSL support
sock = ssl.wrap_socket(sock,
  # flag that certificate from the other side of connection is required
  # and should be validated when wrapping
  cert_reqs=ssl.CERT_REQUIRED,
  # file with root certificates
  ca_certs="cacerts.txt"
)
}}}

=== Get updated list of root certificates ===

SSL stands for Secure Sockets Layer and is designed to create secure connection between client and server. Secure means that connection is encrypted and therefore protected from eavesdropping. It also allows to validate server identity.

SSL libraries availability and limitations

  • Python 2.5 (the version AppEngine is running)

SSL support is available from http://pypi.python.org/pypi/ssl Unfortunately, there are no binaries for Windows, and that's a major showstopper when using Python 2.5.

  • Python 2.6

SSL module from http://pypi.python.org/pypi/ssl is bundled with installer. It has a serious security issue that allows successful MITM attack using valid certificate from an other site - http://bugs.python.org/issue1589 Basically, the module validates that certificate is correct and correctly signed by root certificate, but it does not check that certificate actually belongs to the connected site, i.e. that site name matches the name specified in certificate.

Validating server identity

Client need to connect to server over SSL, fetch its certificate, check that the certificate is valid (signed properly) and belongs to this server (server name).

Let's illustrate ssl vulnerability in Python 2.x versions. The following snippet should fail - it replaces HOST "www.google.com" to connect to with its IP address. If you try to use this IP in Chrome like https://74.125.232.50 - it will show an error, but ssl library will not.

import socket
import ssl

HOST = "www.google.com"
PORT = 443

# replace HOST name with IP, this should fail connection attempt,
# but it doesn't in Python 2.x
HOST = socket.getaddrinfo(HOST, PORT)[0][4][0]
print(HOST)

# create socket and connect to server
# server address is specified later in connect() method
sock = socket.socket()
sock.connect((HOST, PORT))

# wrap socket to add SSL support
sock = ssl.wrap_socket(sock,
  # flag that certificate from the other side of connection is required
  # and should be validated when wrapping 
  cert_reqs=ssl.CERT_REQUIRED,
  # file with root certificates
  ca_certs="cacerts.txt"
)

Get updated list of root certificates

SSL (last edited 2010-11-21 08:55:53 by techtonik)

Unable to edit the page? See the FrontPage for instructions.