トランスポート層セキュリティ
Transport Layer Security Cheat Sheet
- 原典
- Transport Layer Security Cheat Sheet(OWASP Cheat Sheet Series)
- 原文
- GitHub 上の Markdown
- 底本
bac04fb5(2026-07-29 時点)- ライセンス
- CC BY-SA 4.0(原典と同一。訳文も同ライセンスで再配布できます)
はじめに
このチートシートは、Transport Layer Security(TLS)を用いてアプリケーションのトランスポート層の保護を実装するための指針を示す。 主に HTTPS で Web アプリケーションへ接続するクライアントを TLS で保護する方法に焦点を置くが、その多くは TLS の他の用途にもあてはまる。 正しく実装されれば、TLS はいくつもの安全上の利点を与える。
- 機密性:攻撃者が通信の内容を読むことに対する保護を与える。
- 完全性:攻撃者がサーバーに対してリクエストを再送するなど、通信の改変に対する保護を与える。
- 認証:クライアントが正当なサーバーに接続していることを確認できるようにする。クライアント証明書を使わないかぎり、クライアントの身元は検証されないことに注意する。
SSL と TLS
Secure Socket Layer(SSL)は、HTTPS という形で HTTP の通信を暗号化するために使われた元来のプロトコルである。 SSL には公開された版が二つあり、バージョン 2 と 3 である。 どちらも深刻な暗号上の弱点を持ち、もはや使うべきではない。
さまざまな理由から、次の版のプロトコル(実質的には SSL 3.1)は Transport Layer Security(TLS)バージョン 1.0 と名付けられた。 その後、TLS のバージョン 1.1、1.2、1.3 が公開されている。
「SSL」「SSL/TLS」「TLS」の語はしばしば同じ意味で使われ、多くの場合はより現代的な TLS プロトコルを指して「SSL」と言われる。 このチートシートでは、レガシーなプロトコルを指す場合を除いて「TLS」の語を用いる。
サーバーの設定
強固なプロトコルのみに対応する
Web アプリケーションは既定で TLS 1.3 を使い、互換性のために TLS 1.2 に対応してもよい。 TLS 1.0 と TLS 1.1 は RFC 8996(2021 年 3 月)によって正式に非推奨とされており、無効にしなければならない。 これらは PCI DSS でも禁じられ、NIST SP 800-52 Rev. 2 でも許されず、主要なブラウザからは削除されている。 SSLv2 と SSLv3 は常に無効にしなければならない。
サポートの終わったクライアントとの相互運用が事業上どうしても必要な場合は、機微なデータへアクセスできない専用のエンドポイントに切り離す。 主要なエンドポイントを弱めてはならない。 プロトコルのダウングレード攻撃を防ぐため、「TLS_FALLBACK_SCSV」拡張を有効にするべきである。
強固な暗号スイートのみに対応する
TLS が対応する暗号(暗号スイート)は多数あり、安全性の水準はさまざまである。
TLS 1.3 では、標準の AEAD 暗号スイート(AES-GCM または ChaCha20-Poly1305)を使う。
TLS 1.2 がなお必要な場合も、そこでも AEAD に基づくスイートを優先し、CBC モードの暗号を避ける。 少なくとも次の種類の暗号スイートは常に無効にするべきである。
- Null 暗号
- 匿名の暗号(
TLS_*_anon_*) - EXPORT 暗号(
TLS_*_EXPORT_*) - 前方秘匿性を与えない RSA による鍵輸送(
TLS_RSA_*)と、一時的または静的な Diffie-Hellman 鍵合意(TLS_DH_*、TLS_ECDH_*)
Mozilla Foundation は、Web、データベース、メールのサーバー向けに使いやすい安全な設定の生成ツールを提供している。 この道具を使えば、サイトの管理者は使用しているソフトウェアを選び、幅広いブラウザのバージョンとサーバーソフトウェアに対して安全性と互換性の釣り合いをとった設定ファイルを得られる。
適切な Diffie-Hellman の群を設定する
TLS 1.3 より前のプロトコル版における、一時的な Diffie-Hellman 鍵交換(暗号スイート名の "DHE" や "EDH" で示される)で使うパラメータ生成の慣行には実用上の問題があった。 たとえばサーバーのパラメータの選択にクライアントが関与できず、無条件に受け入れるか切断するかしかできなかった。 またランダムなパラメータの生成がしばしばサービス妨害攻撃を招いた(CVE-2022-40735、CVE-2002-20001)。
どの Diffie-Hellman の群に対応するかの交渉には supported_groups 拡張が使われる。
- 使える有限体 Diffie-Hellman の群は RFC7919 で規定された
ffdhe2048、ffdhe3072、ffdhe4096、ffdhe6144、ffdhe8192である。 - 楕円曲線 Diffie-Hellman の群には
x25519、prime256v1、x448、secp384r1が含まれる。 - 耐量子計算機暗号では、現在
X25519MLKEM768が使われている(厳密には群ではない)。
OpenSSL では、有効にする群の一覧を openssl.cnf で設定できる。
たとえば次のようになる。
openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_module
[ssl_module]
system_default = tls_system_default
[tls_system_default]
Groups = X25519MLKEM768:x25519:prime256v1:x448:ffdhe2048:ffdhe3072
Apache の設定は次のようになる。
SSLOpenSSLConfCmd Curves X25519MLKEM768:X25519:prime256v1:secp384r1
NGINX での同じ群の指定は次のようになる。
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1:secp384r1;
TLS 1.2 以前の版では、Diffie-Hellman のパラメータを設定しないことが推奨される。
圧縮を無効にする
TLS の圧縮は無効にするべきである。 CRIME と呼ばれる脆弱性から守るためである。 これはセッション Cookie のような機微な情報を攻撃者が復元しうるものである。
暗号ライブラリにパッチを当てる
SSL と TLS のプロトコル自体の脆弱性に加えて、SSL と TLS のライブラリにも歴史的に多数の脆弱性があり、Heartbleed が最も有名である。 したがって、これらのライブラリを最新のセキュリティパッチで最新に保つことが重要である。
サーバーの設定を検査する
サーバーを堅牢にしたら、その設定を検査するべきである。 検査についてさらに詳しくは OWASP Testing Guide の SSL/TLS の検査の章を参照する。
サーバーの設定を手早く検証できるオンラインの道具はいくつもある。
- SSL Labs Server Test
- CryptCheck
- Hardenize
- ImmuniWeb
- Observatory by Mozilla
- Scanigma
- Stellastra
- OWASP PurpleTeam(
cloud)
加えて、オフラインで使える道具もいくつもある。
- O-Saft - OWASP SSL advanced forensic tool
- CipherScan
- CryptoLyzer
- SSLScan - Fast SSL Scanner
- SSLyze
- testssl.sh
- tls-scan
- OWASP PurpleTeam(
local)
証明書
強固な鍵を使い、それを保護する
暗号鍵の生成に使う秘密鍵は、その秘密鍵と対応する証明書の想定される寿命に対して十分に強固でなければならない。 現在の最良の慣行は、RSA の鍵を使う場合に少なくとも 2048 ビットの鍵長を選ぶことである。 鍵の寿命と同等の鍵強度についてさらに詳しくはこちらと NIST SP 800-57 を参照する。
秘密鍵は、ファイルシステムの権限やその他の技術的および管理的な対策によって、不正なアクセスから保護するべきである。
強固な暗号ハッシュアルゴリズムを使う
証明書は、古い MD5 や SHA-1 のアルゴリズムではなく、ハッシュアルゴリズムに SHA-256 を使うべきである。 古いものは複数の暗号上の弱点を持ち、現代のブラウザから信頼されない。
正しいドメイン名を使う
証明書のドメイン名(subject)は、その証明書を提示するサーバーの完全修飾名と一致しなければならない。
歴史的にはこれは証明書の commonName(CN)属性に保存されていた。
しかし現代の Chrome は CN 属性を無視し、FQDN が subjectAlternativeName(SAN)属性にあることを要求する。
互換性のため、証明書は主要な FQDN を CN に持ち、FQDN の完全な一覧を SAN に持つべきである。
加えて、証明書を作るときは次を考慮するべきである。
- "www" のサブドメインも含めるべきかを検討する。
- 修飾されていないホスト名を含めない。
- IP アドレスを含めない。
- 外部に向けた証明書に内部のドメイン名を含めない。
- サーバーが内部と外部の両方の FQDN でアクセスされる場合は、複数の証明書で設定する。
ワイルドカード証明書の使用を注意深く検討する
ワイルドカード証明書は便利であるが、最小権限の原則に反する。
単一の証明書がそのドメインのすべてのサブドメイン(*.example.org など)で有効になるからである。
複数のシステムがワイルドカード証明書を共有していると、その鍵が複数のシステムに存在しうるため、証明書の秘密鍵が漏洩する可能性が高まる。
加えてその鍵の価値が大きく高まり、攻撃者にとってより魅力的な標的になる。
ワイルドカード証明書の使用に関する問題は複雑であり、オンライン上にさまざまな議論がある。
ワイルドカード証明書の使用のリスクを評価するときは、次の点を検討するべきである。
- 便宜のためではなく、真に必要がある場合にのみワイルドカード証明書を使う。
- 代わりに、システムが自身の証明書を自動的に要求し更新できるよう ACME の使用を検討する。
- 信頼の水準が異なるシステムにワイルドカード証明書を決して使わない。
- 二つの VPN ゲートウェイはワイルドカード証明書を共有できる。
- 同じ Web アプリケーションの複数のインスタンスは証明書を共有できる。
- VPN ゲートウェイと公開の Web サーバーはワイルドカード証明書を共有すべきでない。
- 公開の Web サーバーと内部のサーバーはワイルドカード証明書を共有すべきでない。
- TLS の終端を行うリバースプロキシの使用を検討し、ワイルドカードの秘密鍵が一つのシステムにのみ存在する状態にする。
- 証明書が失効したり漏洩したりしたときにすべてを更新できるよう、その証明書を共有するすべてのシステムの一覧を維持するべきである。
- サブドメイン(
*.foo.example.orgなど)や別のドメインに対して発行することで、ワイルドカード証明書の範囲を限定する。
アプリケーションの利用者層に適した認証局を使う
利用者から信頼されるには、証明書は信頼された認証局(CA)によって署名されていなければならない。 インターネットに面したアプリケーションでは、OS やブラウザによって広く知られ自動的に信頼される CA のいずれかであるべきである。
Let's Encrypt の CA は、主要なすべてのブラウザから信頼される、ドメイン検証済みの SSL 証明書を無料で提供している。 したがって、CA から証明書を購入する利点があるかを検討する。
内部のアプリケーションでは、内部の CA を使える。 これは証明書の FQDN が(外部の CA に対しても、証明書の透明性の一覧の中で公開される形でも)露出しないことを意味する。 ただしその証明書は、署名に使われた内部 CA の証明書を取り込んで信頼した利用者からのみ信頼される。
CAA レコードで証明書を発行できる CA を制限する
Certification Authority Authorization(CAA)の DNS レコードを使えば、あるドメインに対して証明書を発行してよい CA を定義できる。 このレコードは CA の一覧を含み、その一覧に含まれない CA は、そのドメインに対する証明書の発行を拒否するべきである。 これは、評判の劣る CA を通じて攻撃者がそのドメインの不正な証明書を得ることを防ぐ助けになる。 すべてのサブドメインに適用すれば、管理者や開発者が使える CA を制限し、不正なワイルドカード証明書の取得を防ぐという運用面の利点も得られる。
証明書の検証の種類を検討する
証明書には異なる検証の種類がある。 検証は、あなたがその証明書を持ってよいことを認証局(CA)が確かめる処理であり、これは認可である。 CA/Browser Forum は、CA とブラウザのベンダー、および Web の安全性に関心を持つ関係者からなる組織である。 彼らは検証の種類に基づいて CA が従うべき規則を定める。 基本の検証は Domain Validated(DV)と呼ばれる。 公に発行されるすべての証明書はドメイン検証を受けなければならない。 この処理は、証明書で要求された名前やエンドポイントを実際に制御していることの証明を伴う。 通常は DNS における、公式のメールアドレスへの、あるいは証明書を受け取るエンドポイントへのチャレンジとレスポンスを伴う。
Organization Validated(OV)の証明書は、要求者の組織情報を証明書の subject に含む。 たとえば C = GB, ST = Manchester, O = Sectigo Limited, CN = sectigo.com のようになる。 OV の証明書を取得する処理は、正しい企業と本当に話していることを CA に示す方法で、要求元の企業と公式に連絡をとることを要する。
Extended validation(EV)の証明書は、DV と OV のすべての検証に加えて、さらに高い水準の検証を与える。 これは実質的に「このサイトは本当に Example Company Inc. によって運営されている」と「このドメインは本当に example.org である」の違いと見られる。 最新の Extended Validation の指針を参照する。
歴史的にはこれらはブラウザで異なる表示になり、しばしばアドレスバーに企業名や緑色のアイコンや背景が表示された。 しかし 2019 年以降、EV の証明書が追加の保護を与えるとは考えられていないため、主要なブラウザはこのような形で EV の状態を表示しない(Chromium。Chrome、Edge、Brave、Opera が対象。Firefox、Safari)。
すべてのブラウザと TLS のスタックは DV、OV、EV の証明書の違いを認識しないので、安全性の面では実質的に同じである。 不正な証明書を得るために攻撃者が必要とするのは、そのドメインを実効的に制御する水準に到達することだけである。 OV や EV の証明書を得るための攻撃者側の追加の労力は、事故の範囲を広げることには何ら寄与しない。 むしろそうした行為は検出につながる可能性が高い。 OV と EV の証明書を得るための追加の手間は可用性のリスクを生みうるので、その使用はこの点を踏まえて見直すべきである。
アプリケーション
すべてのページで TLS を使う
TLS は、ログインページのように機微とみなされるページだけでなく、すべてのページで使うべきである。 TLS の使用を強制しないページがあれば、攻撃者にセッショントークンのような機微な情報を盗聴する機会や、利用者に対する他の攻撃を行うために応答へ悪意ある JavaScript を注入する機会を与えうる。
公開のアプリケーションでは、Web サーバーがポート 80 で暗号化されていない HTTP の接続を待ち受け、それを即座に恒久的なリダイレクト(HTTP 301)で転送するのが適切な場合もある。 ドメイン名を手で入力する利用者に、より良い体験を与えられる。 そのうえで HTTP Strict Transport Security(HSTS)ヘッダで補い、以後 HTTP でサイトへアクセスすることを防ぐべきである。
API のみのエンドポイントは HTTP を完全に無効にし、暗号化された接続のみに対応するべきである。 それが不可能な場合、API のエンドポイントは暗号化されていない HTTP 接続によるリクエストをリダイレクトするのではなく失敗させるべきである。
TLS のコンテンツと非 TLS のコンテンツを混在させない
TLS で提供されるページは、暗号化されていない HTTP で読み込まれるリソース(JavaScript や CSS のファイルなど)を含むべきではない。 そうした暗号化されていないリソースは、攻撃者にセッション Cookie の盗聴やページへの悪意あるコードの注入を許しうる。 現代のブラウザは、安全なページに暗号化されていない HTTP で能動的なコンテンツを読み込もうとする試みも遮断する。
Cookie の "Secure" 属性を使う
すべての Cookie は「Secure」属性を付けるべきである。 これはブラウザに、暗号化された HTTPS の接続でのみ Cookie を送るよう指示し、暗号化されていない HTTP の接続から盗聴されることを防ぐ。 サイトが HTTP(ポート 80)を待ち受けていない場合でもこれは重要である。 能動的な中間者攻撃を行う攻撃者が、Cookie を盗むためにポート 80 で偽装した Web サーバーを利用者に提示しうるからである。
機微なデータのキャッシュを防ぐ
TLS は転送中のデータの保護を与えるが、データが要求元のシステムに到達したあとの保護は何も与えない。 したがってその情報は、利用者のブラウザのキャッシュや、TLS の復号を行うよう設定された介在プロキシに保存されうる。
機微なデータを応答で返す場合は、HTTP ヘッダを用いてブラウザとプロキシサーバーにその情報をキャッシュしないよう指示するべきである。 保存されたり他の利用者へ返されたりすることを防ぐためである。 現代の HTTP/1.1 以降のクライアントと中継装置に対しては、次の一つのヘッダで足りる。
Cache-Control: no-store
no-store は最も強いキャッシュの指示であり、共有キャッシュも私的キャッシュも応答のいかなる部分も保存することを禁じる。
旧来の組み合わせである Cache-Control: no-cache, no-store, must-revalidate に Pragma: no-cache と Expires: 0 を加えたものは、HTTP/1.1 より前のキャッシュに対応しなければならない場合にのみ必要であり(2024 年以降は実質的に廃れている)、現代のスタックでは no-store を超える保護を与えない。
Cache-Control が支配するのは HTTP のキャッシュであり、ブラウザが Cookie を Cookie の保管領域に保存するかどうかは制御しないことに注意する。
それは Cookie の属性(Max-Age、Expires、セッション)によって制御される。
サインアウト時にクライアント側で既にキャッシュされたデータも消したい場合は、加えて Clear-Site-Data を送る(Clear-Site-Data: "cache", "cookies", "storage" など)。
HTTP Strict Transport Security を使う
HTTP Strict Transport Security(HSTS)は、利用者のブラウザに常に HTTPS でサイトを要求するよう指示し、利用者が証明書の警告を無視して進むことも防ぐ。 HSTS の実装についてさらに詳しくは HTTP Strict Transport Security を参照する。
クライアント証明書と相互 TLS
一般的な TLS の構成では、サーバー上の証明書によってクライアントがサーバーの身元を検証でき、両者のあいだに暗号化された接続が与えられる。 しかしこの方法には主に二つの弱点がある。
- サーバーがクライアントの身元を検証する仕組みを持たない。
- そのドメインの正当な証明書を入手した攻撃者が接続を傍受できる。この傍受は、信頼された CA の証明書をクライアントの機器に導入することで、TLS の通信を検査するために企業がしばしば行うものである。
相互 TLS(mTLS)の中核であるクライアント証明書が、これらの問題に対処する。 mTLS では、クライアントとサーバーが TLS を用いて互いを認証する。 クライアントは自身の証明書によってサーバーへ身元を証明する。 これはクライアントの強固な認証を可能にするだけでなく、クライアントの機器に信頼された CA の証明書があっても、中間の者が TLS の通信を復号することを防ぐ。
課題と考慮点
クライアント証明書が公開のシステムで使われることは稀である。 いくつもの課題があるからである。
- クライアント証明書の発行と管理には、大きな運用の手間がかかる。
- 技術に詳しくない利用者にとって、クライアント証明書のインストールは難しい。
- 組織による TLS の復号の慣行が、mTLS の主要な構成要素であるクライアント証明書の認証を失敗させうる。
こうした課題があっても、価値の高いアプリケーションや API、とくに利用者が技術的に洗練されているか同じ組織に属する場合には、クライアント証明書と mTLS を検討するべきである。
公開鍵のピンニング
公開鍵のピンニングを使えば、サーバーの証明書が正当で信頼されているだけでなく、そのサーバーに期待される証明書と一致することも保証できる。 これは、検証処理の弱点の悪用、信頼された認証局の侵害、あるいはクライアントへの管理者アクセスによって正当な証明書を入手できる攻撃者に対する保護を与える。
公開鍵のピンニングは HTTP Public Key Pinning(HPKP)の標準としてブラウザに追加された。 しかしいくつもの問題があったため、その後非推奨となり、もはや推奨されず、現代のブラウザでも対応されていない。
ただし公開鍵のピンニングは、モバイルアプリケーション、リッチクライアント、サーバー間の通信ではなお安全上の利点を与えうる。 これについてさらに詳しくは証明書ピンニングを参照する。
関連資料
- OWASP Testing for Weak TLS
- OWASP Application Security Verification Standard (ASVS) - Communication Security Verification Requirements (V9)
- Mozilla Mozilla Recommended Configurations
- NIST SP 800-52 Rev. 2 Guidelines for the Selection, Configuration, and Use of Transport Layer Security (TLS) Implementations
- NIST NIST SP 800-57 Recommendation for Key Management, Revision 5
- NIST SP 800-95 Guide to Secure Web Services
- IETF RFC 5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
- IETF RFC 2246 The Transport Layer Security (TLS) Protocol Version 1.0 (1999 年 1 月)
- IETF RFC 4346 The Transport Layer Security (TLS) Protocol Version 1.1 (2006 年 4 月)
- IETF RFC 5246 The Transport Layer Security (TLS) Protocol Version 1.2 (2008 年 8 月)