説明
モジュールレベルのssl.wrap_socket関数はPython 3.7で非推奨となり、Python 3.12で削除されました。ssl.SSLContextに置き換え、証明書検証、ホスト名検証、最小TLSバージョンなどを明示的に構成してください。
想定される影響
- 互換性の問題: Python 3.12以降では、削除された関数を呼び出せません。
- 接続相手へのなりすまし: 証明書とホスト名を検証しない場合、通信を傍受できる攻撃者にサーバーを装われるおそれがあります。
- 情報漏えい: 検証されていない接続へ機密データを送信する可能性があります。
対処方法
ssl.create_default_context()または適切に設定したssl.SSLContextを使い、証明書とホスト名の検証を有効にしてください。- TLS 1.2以上を使用し、可能な場合はTLS 1.3も許可してください。
- 信頼するCAバンドル、期待するホスト名、サーバー証明書チェーンの検証を構成してください。
例
変更前は、Python 3.12で削除された過去のAPIを示しています。サーバーの例は、証明書・秘密鍵とリクエスト処理を別途用意する抜粋です。クライアント証明書による認証を要求する構成ではありません。
変更前
python
# 過去の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))
変更後
クライアント側
python
# SSLContextのクライアント
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())
サーバー側
python
# SSLContextのサーバー
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()
...
説明
- 変更前: モジュールレベルの
ssl.wrap_socketは削除されたAPIであり、使用を続けるべきではありません。 - 変更後:
ssl.create_default_context()とSSLContext.wrap_socket()でTLSを構成します。クライアントの例は接続を確立してサーバー証明書とホスト名を検証し、サーバーのコンテキストは自身の証明書と秘密鍵を読み込みます。
参考資料
- 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