この文書は2016年以降更新されていません
セキュアコーディングに関するチートシート
ドラフト版チートシート - 編集中
はじめに
このドキュメントの目的は、セキュアコーディングの実践に向けた全体的なガイドラインを作成することです。ドキュメント全体のサイズはコンパクトに抑えながら、理解しやすいものにすることを目指しています。特定の分野についての追加情報を探している場合は、このドキュメントに記載された詳細へのリンクを参照してください。
このドキュメントの使用方法
以下に挙げた情報は、広く受け入れられているセキュアコーディングの実践方法です。ただし、これらをベーステンプレートとして、それぞれのセクションを組織のポリシーとリスク許容度に応じた推奨事項で更新することをお勧めします。
セキュアコーディングポリシー
セキュアコーディングポリシーを常に維持します。セキュアコーディングの標準の維持 (この標準はテクノロジに固有のものと、テクノロジに依存しないものがあります)、トレーニングに向けたコードレビュー結果のフィードバック、入力データ検証、出力データ検証などのアクティビティを一覧にします。
セキュアコーディングポリシーは、なぜ必要になるのでしょうか。このポリシーは、組織全体で一貫性を維持するために役立ちます。また、Web 開発プロジェクトにおけるセキュアコーディング標準の使用を垂直的および水平的に拡大する際にも役立ちます。
認証
ユーザー認証
認証メカニズム
認証には、単一要素認証と多要素認証があります。通常、単一要素認証では、以下のいずれかが必要になります。
1.知識情報
2.所持情報
3.生体情報
4.場所情報
多要素認証では、上記の要素を複数使用します。
パスワードと PIN (個人識別番号) でユーザーを認証する場合、パスワードと PIN はどちらも知識情報になるため、単一要素認証になります。ただし、PIN がデバイス / ソフトトークンから生成される場合は、多要素認証になります。これは、所持情報であるデバイス / トークンから PIN が生成されるためです。
「リスクの高い」データ (クレジットカード、医療情報、個人を特定できるデータなど) を処理するトランザクションには、多要素認証を使用してください。
クライアント側認証のみを使用している場合は、その認証が迂回、改ざんまたは悪用される可能性のないことを確認します。
ユーザー名
認証目的の場合、ユーザー名は一意であることが必要になります。リスクの高い / 重要なデータを処理するシナリオでは、ユーザーに一意の名前を選択します。たとえば、銀行取引アプリケーション、ショッピングアプリケーション、個人を特定できるデータを処理するアプリケーションなどの場合です。
パスワードの複雑さ
パスワードの複雑さの詳細については、https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls を参照してください。
パスワードのローテーション
アプリケーション内で特権が付与されたアカウントには、90 日単位の周期でパスワードのローテーションを要求する必要があります。
オンラインのパスワード推測とパスワード攻撃
アプリケーションでは、以下のいずれかの方法で、オンラインのパスワード推測の試行を阻止する必要があります。
- アカウントのロックアウト - パスワードの試行が 5 回失敗したらアカウントをロックします。
- 一時的なアカウントのロックアウト - パスワードの試行が 5 回失敗したら一時的にアカウントをロックします。
- 自動化対策 Captcha - パスワードの試行が 5 回失敗したら正常な完了のために Captcha を要求します。
パスワードのリセット機能
- 可能であれば、パスワードのリセット時にアウトオブバンド検証を使用します。たとえば、登録済みのモバイルまたは電子メールの ID に OTP (One Time Password) を送信 します。このプロセスでは、ユーザーに電子メールの ID や電話番号の入力を求めてはいけません。悪意のあるユーザーが、その情報を悪用する可能性があるためです。
- 可能な場合は、ユーザー確認のためにセキュリティの質問について尋ねます。
電子メールの検証機能
アプリケーションで電子メールアドレスの所有権を検証する場合は、次の事項を調べます。
- 電子メールの検証リンクは、電子メールアドレスの所有権を検証するための要件のみを満たすようにして、認証されたセッションをユーザーに提供してはいけません (たとえば、ユーザーは通常と同じようにアプリケーションへのアクセスの認証を行う必要があります)。
- 電子メールの検証コードは、最初の使用後に無効にする必要があります。使用されなかった場合でも、8 時間後には無効にします。
パスワードの保存
- パスワードは、 オフラインでの高速なブルートフォース攻撃に耐える形式 (Bcrypt など) で保存する必要があります。
- パスワードの保存では、ハッシュアルゴリズムにユーザーごとの salt を加えることが良策になりますが、十分とはいえません。
- コード内や構成ファイル内にパスワードを保存してはいけません。
サーバー認証
SSL / TLS の使用時には、既知のルート証明書への信頼チェーンを辿ることでサーバー ID を確認します。
IP アドレスや DNS 名に依存してサーバー ID を確認してはいけません。
すべての内部接続と外部接続で、十分に適切な形式のユーザー認証とエンティティ認証が行われるようにします。
この制御は迂回できないようにします。
ロギングと監視
- すべての失敗をログに記録してレビューします。
- すべてのパスワードの失敗をログに記録してレビューします。
- すべてのアカウントのロックアウトをログに記録してレビューします。
セッション管理
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
セッション ID の長さ
- セッショントークンは、128 ビット以上にする必要があります。
セッション ID の作成
- セッショントークンは、可能な場合は Web サーバーで処理する必要があります。それ以外の場合は、暗号学的に安全な乱数生成器によって生成する必要があります。
アイドル時間タイムアウト
- 認証したセッションは、一定のアイドル期間経過後にタイムアウトにする必要があります (15 分が推奨されています)。
Secure フラグ
- "Secure" フラグは、Set-Cookie のたびに設定する必要があります。これにより、ブラウザーに対して HTTP 経由での Cookie の送信を決して行わないように指示を与えます。このフラグの目的は、ユーザーが HTTP リンクを辿ったときに、不用意な Cookie 値の露出を防止することです。
HTTP-Only フラグ
- "HTTP-Only" フラグは、悪意のあるスクリプトによる Cookie の値 (セッション ID など) へのアクセスを禁止するために設定する必要があります。
ログアウト
- セッション ID は、ログアウト時にサーバー側で無効化して、クライアント側で削除します (値を有効期限切れにして上書きします)。
ロギングと監視
- すべてのセッションをログに記録しますが、カード所有者データや個人を特定できる情報はロギングしません。
- 不審なアクティビティについて、すべてのログを監視します。
アクセス制御
https://www.owasp.org/index.php/Access_Control_Cheat_Sheet
プレゼンテーション層
- ユーザーがアクセスできないリンクや機能は、表示しないことをお勧めします。その目的は、不要なアクセス制御メッセージを最小限に抑えることと、不必要にユーザーに表示される特権情報を最小限に抑えることです。
ビジネス層
- システム内でアクションが実行される前に、確実にアクセス制御の検証を実行します。ユーザーは、細工した GET メッセージや POST メッセージで、許可されていない機能を実行しようとすることがあります。
データ層
- アクセス制御の検証を確実に実行して、ターゲットデータに対する操作がユーザーに許可されていることを確認します。操作 X の実行を許可されているユーザーが、すべてのデータセットに対しても操作 X を実行できるものと想定してはいけません。
ロギングと監視
- アクティビティに関連するアクセスのすべてをログに記録します。
- すべてのログを監視してレビューします。
入力データ検証
https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet
出力エンコード
XSS の防止とコンテンツセキュリティポリシー
- ユーザーが制御できる全てのデータは、HTML ページで返す際、悪意あるデータの実行 (XSS など) を防止するために、エンコードしておく必要があります。たとえば、<script> は <script> のようにして返します。
- エンコーディングの種類は、ユーザー制御のデータが挿入されるページのコンテキストによって決まります。たとえば、 HTML 本文内に配置されるデータには HTML エンティティエンコーディングが適しています。その一方、スクリプト内に配置されるユーザーデータには、JavaScript 固有の出力エンコーディングが必要になります。
XSS 対策の詳細については、次を参照してください。OWASP XSS 対策チートシート
SQL インジェクションの防止
- データの一部がユーザー制御であるかどうかを常に把握することは現実的ではありません。したがって、メソッド / 関数がデータを受け取って SQL ステートメントの一部として使用するときには、いつでもパラメーター化クエリを使用する必要があります。
- ユーザー制御のデータを使用して文字列連結で SQL ステートメントを組み立てる処理は、SQL インジェクション脆弱性の原因になります。
- パラメーター化クエリは、SQL インジェクションの防止を保証するアプローチです。
詳細資料: SQL インジェクション対策に関するチートシート
OS コマンドインジェクションの防止
- ユーザー制御データの OS への送信をできる限り回避します。
- 堅牢なエスケープ処理ルーチンを用意して、OS で実行可能な文字列をユーザーが追加できないようにします (たとえば、ユーザーが悪意のあるデータに | を追加して、別の OS コマンドを実行するなど)。エスケープ処理ルーチンの作成時には、積極的なアプローチを使用するようにしてください。例
詳細資料: Reviewing Code for OS Injection
XML インジェクションの防止
- 既存の入力値検証に加えて、XML として解釈可能な文字をエスケープ / エンコードする積極的なアプローチを定義します。少なくとも、次のような文字があります: < > " ' &
- 未処理の XML を受け入れる場合は、より強力な検証が必要になります。これは、複雑になる可能性があります。詳細については、インフラストラクチャのセキュリティチームに問い合わせてください。
安全な伝送 / ネットワーク層セキュリティ
SSL / TLS を使用する状況
- 暗号化されたチャネルを通じて情報を伝送する場合は、TLS を使用します (SSL はセキュリティに有効だと見なされなくなりました)。たとえば、カード所有者データ、個人を特定できる情報、情報分類ポリシーで "公開" に分類されない情報の伝送などです。
- ログインページからログアウトページまで、すべてを HTTPS 経由にする必要があります。
- ユーザーがログインフォームに記入するページには、HTTPS 経由でアクセスされるようにします。フォームを HTTPS 経由で POST 送信するのは言うまでもありません。
- すべての認証済みページは、HTTPS 経由で提示する必要があります。これには、CSS、スクリプト、イメージが含まれます。これを怠ると、中間者攻撃のベクトルを開いてしまうことになります。また、混在 SSL の警告メッセージがブラウザーに表示されるようにもなります。
- HTTP ページと HTTPS ページを切り替える方法には注意が必要です。このような遷移は、攻撃の潜在的なターゲットになります。
HTTP Strict Transport Security (HSTS) の実装
- HTTPS 経由でのみ提供されるアプリケーションは、HSTS を使用して、ドメインへの HTTP 接続を許可しないように準拠ブラウザーに指示する必要があります。
ファイルのアップロード
アップロードの検証
- 入力検証を使用して、アップロードされたファイル名が適切な拡張子タイプを使用していることを確認します。
- アップロードされたファイルが、定義済みの最大ファイルサイズを超えていないことを確認します。
アップロードの保存
- ファイルを OS 上に保存する際は新しいファイル名を使用します。このファイル名や一時ファイル名に、ユーザー制御のテキストを使用してはいけません。
- ユーザーがアップロードしたファイルはすべて別のドメインに保存します(mozillafiles.net と mozilla.org など)。アーカイブに悪意のあるコンテンツが含まれていないか、分析する必要があります。(マルウェア対策やスタティック分析など)
アップロードしたコンテンツの一般公開
- イメージが正しい Content-Type (image/jpeg や application/x-xpinstall) で提供されていることを確認します。
"特殊" なファイルに関する注意
- アップロード機能では、特定のファイルの種類と拡張子のみを許可するホワイトリストのアプローチを使用する必要があります。ただし、次に示すファイルの種類が許可されている場合には、セキュリティの脆弱性につながる可能性があるため、十分な注意が必要になります。
- "crossdomain.xml" は、Flash、Java および Silverlight でのクロスドメインのデータ読み込みを可能にします。認証によってサイトで許可されている場合、これによりクロスドメインのデータ窃盗や CSRF 攻撃を許す可能性があります。これは、問題になる特定のプラグインのバージョンによっては、かなり複雑になることがあるため、単に "crossdomain.xml" または "clientaccesspolicy.xml" という名前の付いたファイルを禁止することが最善策になります。
- ".htaccess" および ".htpasswd" は、ディレクトリ単位でのサーバー構成オプションを提供するものであり、許可してはいけません。http://en.wikipedia.org/wiki/Htaccess を参照してください。
アップロードの検証
- 画像書き換えライブラリを使用して、画像が正当であることを検証して、無関係なコンテンツを取り除きます。
- 保存した画像の拡張子は、単にアップロードのヘッダーを信じるのではなく、画像処理によって検出された画像のコンテンツタイプに基づいて妥当な画像の拡張子に設定します。
- 検出された画像のコンテンツタイプが定義済みの画像の種類 (jpg や png など) のリストに含まれていることを確認します。
エラー処理
一般的なエラーの種類: • ビジネスロジックの条件が満たされていない結果。 • ビジネスロジックが存在する環境に障害が発生した結果。 • アプリケーションが依存する上流システムまたは下流システムに障害が発生した結果。 • 技術的なハードウェア / 物理的障害。
このようなエラーには、次のように対処します。
- 値を返すメソッド / 関数のすべての呼び出しで、適切なエラー処理と戻り値のチェックを行うようにする。
- 例外とエラー条件が適切に処理されるようにする。
- ユーザーにシステムエラーを返さないようにする。
- 安全な方法でアプリケーションが失敗するようにする。
- エラーの発生時にはリソースを解放するようにする。
- スタックトレースがユーザーにスローされないようにする。
- 当該の言語に finally メソッドがある場合は、それを使用する。finally メソッドは常に呼び出されるコードであり、例外をスローしたメソッドが参照するリソースの解放にも使用できます。
これは、とても重要なことです。たとえば、あるメソッドが接続プールからデータベース接続を取得したときに、finally なしで例外が発生すると、接続オブジェクトは一定の時間 (タイムアウトになるまで) プールに返されなくなります。 これは、プールの枯渇につながります。メソッド finally() は、例外がスローされていない場合でも呼び出されます。
ロギングと監査
https://www.owasp.org/index.php/Logging_Cheat_Sheet
暗号化
- 認証と安全な通信のためのプロトコルとアルゴリズムについては、すべて暗号コミュニティによる入念な検査が必要です。
- 証明書は、ホスト名 / ユーザーに対して適切に検証されるようにします (つまり、証明書が誰のものであるかを検証します)。
- ワイルドカード証明書は、それに関するビジネスニーズがない場合は使用を避けます。
- 暗号化標準を維持して、開発者コミュニティにネットワークセキュリティプロトコル、アルゴリズム、許可された使用、暗号期間および鍵管理に承認された CipherSuite について知らせます。
Cookie 管理
- 機密情報を永続化しない / 暗号化する / 必要に応じて必要な期間だけ保存するようにして、機密情報が含まれないようにします。
- Cookie の改ざんによる不正なアクティビティを実行できないようにします。
- Secure フラグを設定して、通信回線を通した伝送が不用意に安全でない方法で行われないようにします。
- アプリケーションのコード内のすべての状態遷移において適切にCookie がチェックされ、Cookie 使用が強制適用されているかを判断します。
- Cookie 内に機密データを永続化する場合は、Cookie 全体を暗号化する必要があります。
- アプリケーションで使用する Cookie のすべて、その名前、および必要な理由を定義します。
安全な展開
- ホスト上の構成ファイル、ディレクトリ、およびリソースへのアクセスを認証と認可で保護し、直接的なアクセスを禁止します。
- “すべて拒否” ルールを使用して、ホスト上のリソースへのアクセスを禁止しておき、必要に応じてアクセス権を付与します。
- Apache HTTP サーバーでは、WEB-INF や META-INF のようなディレクトリが保護されていることを確認します。ディレクトリとサブディレクトリのアクセス許可が .htaccess ファイルで指定されている場合は、“すべて拒否” ルールを使用して保護されていることを確認します。
- Struts フレームワークを使用している場合は、web.xml で *.jsp ファイルへのアクセスを禁止して、JSP ファイルに直接アクセスできないようにします。
- クリーンな環境を維持します。アプリケーションで使用されることのないソースコードを含むファイルは削除します。
- 実稼働環境には、一切のソースコード / 開発ツールが含まれないようにします。
- 実稼働環境には、コンパイルしたコード / 実行可能ファイルのみが含まれるようにします。
- テストコード / デバッグコードを削除します (これらには、バックドアが含まれている可能性があります)。
- コメント付きのコードとメタタグは、機密データを含んでいる可能性があるため削除します。
- 可能であれば、リバースエンジニアリングを回避するために、ソースコードに難読化を施します。
未検証のリダイレクトと転送に関するチートシート
https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet
一般的な脆弱性
SQL インジェクション
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
クロスサイトスクリプティング
https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
クロスサイトリクエストフォージェリ
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
- 状態が変化する操作では、安全なランダムトークン (CSRF トークン) を要求することで CSRF 攻撃を阻止します。
- CSRF トークンの特徴
- ユーザーごと、およびユーザーセッションごとに一意。
- 1 つのユーザーセッションに結び付けられる。
- 巨大なランダム値。
- 暗号的に安全な乱数ジェネレーターによって生成されたもの。
- CSRF トークンは、フォームの hidden フィールドとして追加されるか、(状態が変化する操作が GET によって行われる場合は) URL に追加されます。
- サーバーでは、CSRF トークンの検証に失敗した場合はリクエストされたアクションを拒否します。
悪意のあるサイトによるフレーム内表示 (クリックジャッキング) の防止
HTML コンテンツを含むすべての応答に、x-frame-options ヘッダーを設定します。有効な値は、"DENY" または "SAMEORIGIN" です。
DENY は、すべてのサイトを対象に (ドメインに関係なく)、コンテンツのフレーム内表示をブロックします。 SAMEORIGIN は、すべてのサイトを対象に、コンテンツのフレーム内表示をブロックします。ただし、同一ドメイン内のサイトはブロックしません。
フレーム内表示に特別な必要性が認められない場合は、"DENY" 設定が推奨されます。
セキュリティの構成ミス
- 不要なサービス、ポート、プロトコルおよびデーモンは、すべて無効にします。
- 既定のパスワードやベンダーが用意したパスワードは、すべて変更します。
- 類似した機能を 1 つの VLAN にグループ化して、サーバーを保護します。
- 内部の仕組みを公開しないように、エラーメッセージを変更します。
- スタックトレースがコンテナーに残されないようにします。
- アクセスを許可するテータ / ページは最小限にします。
セキュリティで保護されていない直接的なオブジェクト参照
https://www.owasp.org/index.php/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet
ディレクトリの一覧表示
- サーバーではディレクトリの一覧表示を有効にしてはいけません。
並行実行と競合状態
- ロックメカニズムを使用して、共有リソースをロックします。
- 共有リソースを読み取る前にロックを取得します。
References
OWASP Cheat Sheets Project Homepage
Developer Cheat Sheets (Builder)
- Authentication Cheat Sheet (Spanish)
- Choosing and Using Security Questions Cheat Sheet
- Clickjacking Defense Cheat Sheet
- C-Based Toolchain Hardening Cheat Sheet
- Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet
- Cryptographic Storage Cheat Sheet
- DOM based XSS Prevention Cheat Sheet
- Forgot Password Cheat Sheet
- HTML5 Security Cheat Sheet
- Input Validation Cheat Sheet
- JAAS Cheat Sheet
- Logging Cheat Sheet
- .NET Security Cheat Sheet
- OWASP Top Ten Cheat Sheet
- Password Storage Cheat Sheet
- Pinning Cheat Sheet
- Query Parameterization Cheat Sheet
- Ruby on Rails Cheatsheet
- REST Security Cheat Sheet
- Session Management Cheat Sheet
- SAML Security Cheat Sheet
- SQL Injection Prevention Cheat Sheet
- Transaction Authorization Cheat Sheet
- Transport Layer Protection Cheat Sheet
- Unvalidated Redirects and Forwards Cheat Sheet
- User Privacy Protection Cheat Sheet
- Web Service Security Cheat Sheet
- XSS (Cross Site Scripting) Prevention Cheat Sheet
Assessment Cheat Sheets (Breaker)
- Attack Surface Analysis Cheat Sheet
- XSS Filter Evasion Cheat Sheet
- REST Assessment Cheat Sheet
- Web Application Security Testing Cheat Sheet
Mobile Cheat Sheets
OpSec Cheat Sheets (Defender)
Draft Cheat Sheets
- Access Control Cheat Sheet
- Application Security Architecture Cheat Sheet
- Business Logic Security Cheat Sheet
- PHP Security Cheat Sheet
- Secure Coding Cheat Sheet
- Secure SDLC Cheat Sheet
- Threat Modeling Cheat Sheet
- Grails Secure Code Review Cheat Sheet
- IOS Application Security Testing Cheat Sheet
- Key Management Cheat Sheet
- Insecure Direct Object Reference Prevention Cheat Sheet
- Content Security Policy Cheat Sheet