セキュアコーディングベストプラクティスハンドブック~後半~
本ブログはVeracode社ドキュメント「Secure Coding Best Practices Handbook」の翻訳版の後編です。
ベストプラクティス1~5につきましては、前編に記載しておりますので、まだ読んでいない方は、まずはそちらをご一読頂ければ幸いです。
<目次>
目次[非表示]
- 1.ベストプラクティス6:アクセス制御の実装
- 1.1.セキュリティ対策に関するポイント
- 1.2.対処されるリスク
- 1.3.参考
- 2.ベストプラクティス7:データの保護
- 2.1.セキュリティ対策に関するポイント
- 2.2.対処されるリスク
- 2.3.参考
- 3.ベストプラクティス8:ロギングおよび侵入検知の実装
- 3.1.セキュリティ対策に関するポイント
- 3.2.対処されるリスク
- 3.3.参考
- 4.ベストプラクティス9:セキュリティフレームワークとライブラリの活用
- 4.1.セキュリティ対策に関するポイント
- 4.2.専門家による特別なアドバイス
- 4.3.対処されるリスク
- 4.4.参考
- 5.ベストプラクティス10:エラーの監視と例外処理
- 5.1.セキュリティ対策に関するポイント
- 5.2.対処されたリスク
- 5.3.参考
ベストプラクティス6:アクセス制御の実装
アプリケーション開発の初期段階でアプリケーションに認証またはアクセス制御を構築することによって、アプリケーションの保護と回復力を大幅に向上させることができます。認可は認証と同じではないことに注意してください。OWASPによると、認可は「特定の機能やリソースへのアクセス要求を許可または拒否するプロセス」です。必要な場合、認可にはマルチテナントおよび水平な(データ固有)アクセス制御を含める必要があります。
セキュリティ対策に関するポイント
- 最初にアクセスを確認する、セキュリティ重視の設計を採用する。すべてのリクエストがアクセス制御チェックを通過することを保証するために、フィルタまたはその他の自動化されたメカニズムを使用することを検討する
- アクセス制御が設定されていない機能については、すべてのアクセスを拒否することを検討する
- 最小権限の原則に基づくコードとし、ユーザーまたはシステム・コンポーネントごとに、アクションの実行に必要な最小権限と期間を割り当てる
- 可能な場合は、アクセス制御ポリシーとアプリケーションコードを分離する
- ユーザーの役割をチェックするのではなく、コード内の機能にユーザーがアクセスできるかどうかをチェックすることを検討する
- アクセス制御を促進するために、サーバー側で信頼できるデータをサポートするフレームワークを採用する。フレームワークの主要な要素には、ユーザーIDとログイン状況、ユーザー資格、全体的なアクセス制御ポリシー、要求された機能とデータ、および時間と位置情報が含まれる
例:アクティビティに対するコーディング
コード上でユーザーの役割をチェックするのではなく、コード上の機能にユーザーがアクセスできるかどうかをチェックすることを検討してください。次に、ハードコーディングされたロールチェックの例を示します。
if (user.hasRole("ADMIN")) || (user.hasRole("MANAGER")) { deleteAccount();} |
次の文字列の使用を検討してください。
if (user.hasAccess("DELETE_ACCOUNT")) { |
対処されるリスク
安全でない直接オブジェクトの参照
機能レベルのアクセス制御の欠落
参考
ベストプラクティス7:データの保護
組織には、アプリケーション内の機密データを保護する義務があります。そのためには、重要なデータを保管中および転送中に暗号化する必要があります。これには、金融取引、ウェブデータ、ブラウザデータ、モバイルアプリ内の情報などが含まれます。EUの一般データ保護規則のような規制により、データ保護はコンプライアンス上の重要な問題となっています。
セキュリティ対策に関するポイント
- 自分で作成したライブラリを実装したいと考えないようにする。最近のほとんどの言語では暗号化ライブラリとモジュールが実装されていますが、実装されていない場合は、セキュリティチームに相談して、セキュリティに重点を置き、専門家による査読を受け、適切に管理されたライブラリを見つけるようにする
- 鍵管理、暗号化アーキテクチャ全体の設計、階層化、複雑なソフトウェアにおける信頼性の問題など、適用される暗号のより困難な側面を無視しない。ハードウェアセキュリティモジュール(HSM)ソリューションなどの既存の暗号化ハードウェアを使用すると、作業が簡単になる
- 不適切な鍵を使用したり、暗号化されたデータと一緒に鍵を保存したりしない
- 機密データや極秘データをメモリ上でアクセス可能にしたり、攻撃者が表示できる一時的な保存場所やログファイルに書き込むことを許可しない
- 転送中のデータを暗号化するには、トランスポート・レイヤー・セキュリティ(TLS)を使用する
例:暗号化された安全な擬似乱数生成器
基本的な暗号要素のセキュリティは、その基盤となる乱数生成器(RNG)に大きく依存します。暗号の使用に適したRNGは、暗号化された安全な擬似乱数生成器(CSPRNG)と呼ばれます。また、Math.randomは使用しないでください。Math.randomは乱数を確定的に生成し、その出力は非常に安全でないと考えられます。
Javaでは、Windowsで乱数器の対象を作成する最も安全な方法は次のとおりです。
SecureRandom secRan = SecureRandom.getInstance("Windows-PRNG") ; byte[] b = new byte[NO_OF_RANDOM_BYTES] ; secRan.nextBytes(b); |
Unixのようなシステムでは、次の例を使用します。
SecureRandom secRan = new SecureRandom(); byte[] ranBytes = new bytes[20]; secRan.nextBytes(ranBytes); |
対処されるリスク
機密データの漏洩
参考
ベストプラクティス8:ロギングおよび侵入検知の実装
ロギングは、デバッグやトラブルシューティング以外の目的でも使用することを推奨します。セキュリティイベントやメトリクスをロギングし追跡すると、システムに対する実際の攻撃シナリオを考慮する攻撃主導型防御と呼ばれるものを有効にするのに役立ちます。たとえば、サーバー側の検証で編集不可な項目への変更が検出された場合は、アラートを出すか、その他のアクションを実行してシステムを保護します。4つの主要な領域、つまり、アプリケーションの監視、ビジネス分析と知見、アクティビティ監査とコンプライアンス監視、システム侵入検知とフォレンジックに焦点を当てて下さい。
セキュリティ対策に関するポイント
- SLF4 J とLogback、またはApache Log 4j2などの拡張可能なロギング・フレームワークを使用して、すべてのログ・エントリーの整合性を確保する
- セキュリティと監査の両方の目的で、さまざまな監査ログとトランザクション・ログを別々に保持する
- 常にタイムスタンプと識別情報(送信元IPやユーザIDなど)をログに記録する
- オプトアウトデータ、セッションID、パスワードのハッシュ値、クレジットカード番号や社会保障番号などの機密データやプライベートデータはログに記録しない
- ログインジェクション(ログの偽造とも呼ばれる)から保護するために、信頼できないデータをログに記録する前に暗号化を実行する
- 最適なレベルでログに記録する、ロギングが少なすぎるとリスクが高くなる
使用例:本番環境でのモバイルアプリケーションロギングの無効化
モバイルアプリケーションでは、開発者がデバッグにロギング機能を使用しますが、これが機密情報の漏洩につながる可能性があります。これらのコンソールログには、Xcode IDE(iOSのプラットフォーム)またはLogcat(Androidのプラットフォーム)を使用してアクセスできるだけでなく、同じデバイスにインストールされているサードパーティアプリケーションからもアクセスできます。このため、本番環境ではロギング機能を無効にしてください。
Android
Android ProGuardツールを使用して、proguard-project.txt 構成ファイルに次のオプションを追加することで、ロギングコールを削除します。
-assumenosideeffects class android.util.Log { public static boolean isLoggable(java.lang.String, int); public static int v(...); public static int i(...); public static int w(...); public static int d(...); public static int e(...); } |
iOS
プリプロセッサを使用して、ログステートメントを削除します。
#ifndefDEBUG #define NSlog (...) #endif |
対処されるリスク
OWASP Top10の全てのリスク
参考
ベストプラクティス9:セキュリティフレームワークとライブラリの活用
すべてのWebアプリケーションのセキュリティコントロールを一から開発すると、多くの時間を無駄にし、意図せずにセキュリティの問題を作り出してしまいます。これを回避するには、確立されたセキュリティフレームワークを活用し、必要に応じてテスト/実証済みのセキュリティコントロールを提供する、信頼できるサードパーティライブラリを利用します。
セキュリティ対策に関するポイント
- サードパーティライブラリなどの新しいツールを使用するのではなく、既存の安全なフレームワーク機能を使用する
- 一部のフレームワークにはセキュリティ上の問題があるため、必要に応じて追加のコントロールやセキュリティ保護を組み込む
- Spring Security、Apache Shiro、Django Security、Flask Security などのWebアプリケーションセキュリティフレームワークを使用する
- セキュリティ上の問題がないか定期的に確認し、フレームワークとライブラリを最新の状態に保つ
専門家による特別なアドバイス
脆弱なオープンソースライブラリについて心に留めておくべき重要なことは、ライブラリに脆弱性が含まれているかどうかだけでなく、そのライブラリが脆弱性を簡単に悪用できる方法で使用されているかどうかを知ることが重要であるということです。Veracode社のソフトウェア構成分析ソリューションをお客様が使用した際に収集したデータによると、10回のうち少なくとも9回は、開発者が脆弱なライブラリを必ずしも脆弱な方法で使用しているわけではないことがわかりました。
ライブラリのステータスだけでなく、脆弱なメソッドが呼び出されているかどうかを理解することで、組織はリスクを特定し、最もリスクの高いライブラリの使用に基づいて修正の優先順位を付けることができます。
対処されるリスク
Webアプリケーションのすべての一般的な脆弱性
参考
ベストプラクティス10:エラーの監視と例外処理
エラーや例外処理は、面白いものではありませんが、入力検証と同様に防御的なコーディングの重要な要素です。エラーや例外処理を誤ると、攻撃者に情報が漏れる可能性があり、攻撃者はこの情報を使ってプラットフォームや設計をより良く理解することができます。エラー処理の小さなミスでさえ、分散システムで致命的な障害を引き起こすことが分かっています。
セキュリティ対策に関するポイント
- 慎重なコードレビューを行い、探索的テストやペンテスト、ファジング、フォールトインジェクションなどのネガティブテストを使用して、エラー処理の問題を特定する
- 例外を一元的に管理し、コード内でtry-catchブロックが重複しないようにします。さらに、予期しない動作がすべてアプリケーション内で正しく処理されていることを確認する
- ユーザーに送信されるエラーメッセージが重大なデータ漏えいの原因とならないようにし、QA(品質保証)、フォレンジック、インシデント対応チームが問題を理解するのに十分な情報を提供する方法で例外がログに記録されることを確認する
例:情報漏えい
スタックトレースやその他の内部エラーの詳細を返すと、攻撃者にあなたの環境に関する情報を与えてしまう可能性があります。状況に応じて異なるエラーを返すこと(たとえば、認証エラーの場合の「無効なユーザー」と「無効なパスワード」)も、攻撃者の侵入を助けることになります。
対処されたリスク
OWASP Top10の全てのリスク