📄
概念 📚 software-design-concepts

通信保護(TLS)

TLS 1.2/1.3の仕組み・証明書管理・HSTS・証明書ピンニングなど安全な通信を実現する実装指針

TLS(Transport Layer Security)は、クライアントとサーバー間の通信を暗号化し、盗聴・改ざん・なりすましから保護するプロトコルである。TLS 1.3はTLS 1.2と比較してハンドシェイクのラウンドトリップ数を削減し(1-RTT、一部のケースでは0-RTT)、前方秘匿性(Forward Secrecy)を必須とすることでセキュリティと性能の両方を向上させた。古いTLS 1.0・1.1はPCI DSSなど多くのコンプライアンス基準でも無効化が必須となっている。

証明書チェーン検証は、サーバー証明書からルートCAまでの信頼チェーンを検証するプロセスであり、中間CAの証明書がサーバーから適切に送信されていないとクライアントによっては検証エラーが発生する。HSTS(HTTP Strict Transport Security)は、ブラウザにHTTPS接続を強制させるレスポンスヘッダーであり、max-ageを長く設定してHSTSプリロードリストに登録することで、最初のHTTPリクエストによる攻撃(SSLストリッピング)を防げる。

証明書ピンニング(Certificate Pinning)は、特定の証明書または公開鍵フィンガープリントをクライアントに埋め込み、正規のCAが署名した別の証明書でも接続を拒否する仕組みであり、モバイルアプリでの中間者攻撃対策として使われる。ただし証明書更新時にアプリのアップデートも必須となるため、運用コストが高くなる点に注意が必要である。Let’s EncryptとACMEプロトコルによる証明書の自動更新は、手動更新忘れによる証明書期限切れを防ぐ実用的な解決策となっている。

コードレビューで着目するポイント

  • TLS 1.0・1.1が無効化されており、TLS 1.2以上のみが許可されているか
  • 弱い暗号スイート(RC4・DES・3DES・NULL暗号)が無効化されているか
  • サーバー設定でHSTSヘッダーが適切なmax-age(最低6ヶ月)で設定されているか
  • 証明書の有効期限監視が設定されており、期限切れの前に自動またはアラートで更新されるか
  • 自己署名証明書が本番環境で使われていないか
  • HTTPSへのリダイレクトが設定されており、平文のHTTP通信が発生しない構成になっているか
  • クライアント側(モバイルアプリ等)で証明書ピンニングを実装している場合、バックアップピンが設定されているか

典型的なアンチパターン

証明書検証の無効化: 開発時のデバッグ目的でverify=False(PythonのRequestsライブラリ等)を設定したコードが本番環境に残る。これにより中間者攻撃(MITM)が完全に有効になる。開発環境には自己署名CAをローカルに信頼設定し、証明書検証は常に有効にすること。

HSTSなしのHTTPS: HTTPSは設定されているが、HSTSヘッダーがないため最初のリクエストがHTTPで送信される可能性がある。SSLストリッピング攻撃により最初のリクエストが傍受・改ざんされるリスクが残る。

バックアップピンなしの証明書ピンニング: 証明書ピンニングを実装したが、証明書更新時のバックアップピンが用意されていない。証明書の更新タイミングでアプリが全ユーザーに対して接続不能になる障害が発生する。

参考リソース

  • Mozilla SSL Configuration Generator (https://ssl-config.mozilla.org/) — Nginx・Apacheなど主要サーバーの推奨TLS設定を生成するツール
  • SSL Labs Server Test (https://www.ssllabs.com/ssltest/) — TLS設定を自動評価してグレード付けするサービス
  • Let’s Encrypt (https://letsencrypt.org/) — 無料のACME対応証明書発行サービス
  • HSTS Preload List (https://hstspreload.org/) — HSTSプリロードへの登録申請サイト
  • RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 — TLS 1.3の公式仕様