Description
The module-level ssl.wrap_socket function was deprecated in Python 3.7 and removed in Python 3.12. Replace it with ssl.SSLContext to configure certificate validation, hostname checking and minimum TLS versions explicitly.
Potential impact
- Compatibility failure: The removed function cannot be called in Python 3.12 or later.
- Connection impersonation: Without certificate and hostname validation, an attacker able to intercept traffic may impersonate the server.
- Data exposure: Sensitive data may be sent over an unverified connection.
Remediation
- Use
ssl.create_default_context()or a correctly configuredssl.SSLContextto enable certificate and hostname validation. - Require TLS 1.2 or later and permit TLS 1.3 where possible.
- Configure a trusted CA bundle, the expected hostname and server-certificate chain validation.
Examples
The before example shows the historical API removed in Python 3.12. The server excerpt requires a certificate, private key and request-handling code to be supplied separately; it does not require client-certificate authentication.
Before
python
# Historical ssl.wrap_socket API
import socket
import ssl
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
wrapped_socket = ssl.wrap_socket(sock)
wrapped_socket.connect(('example.com', 443))
After
Client
python
# SSLContext client
import socket
import ssl
hostname = 'www.python.org'
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
Server
python
# SSLContext server
import socket
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('/path/to/certchain.pem', '/path/to/private.key')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
sock.bind(('127.0.0.1', 8443))
sock.listen(5)
with context.wrap_socket(sock, server_side=True) as ssock:
conn, addr = ssock.accept()
...
Explanation
- Before: The module-level
ssl.wrap_socketAPI has been removed and should no longer be used. - After: Use
ssl.create_default_context()andSSLContext.wrap_socket()for current TLS configuration. The client example establishes the connection and checks the server certificate and hostname; the server context loads its own certificate and private key.
References
- OWASP: Transport Layer Protection Cheat Sheet
- CWE: CWE-327: Use of a Broken or Risky Cryptographic Algorithm
- Python Documentation: ssl: TLS/SSL wrapper for socket objects
- Python 3.12: What's New In Python 3.12