この文書は2016年以降更新されていません

.NET セキュリティに関するチートシート

OWASP 作成
ジャンプ先: 移動検索
Cheatsheets-header.jpg

最終改訂日 (yy/mm/dd):2015/03/29

はじめに

このページは、.NET のセキュリティに関する簡単で基本的なヒントを開発者に提供することを目的としています。

.NET Framework

.NET Framework は、Microsoft のエンタープライズ開発向け主要プラットフォームです。.NET Framework は、ASP.NET、Windows デスクトップアプリケーション、Windows Communication Foundation サービス、SharePoint、Visual Studio Tools for Office、その他のテクノロジをサポートする API です。

.NET Framework の更新

.NET Framework は、Microsoft の Windows Update サービスによって最新の状態に保たれます。開発者が別途 .NET Framework を更新する必要は通常ありません。Windows Update には、Windows Updateまたは Windows 搭載コンピューターの Windows Update プログラムからアクセスできます。

個々のフレームワークを更新するには、NuGet を使用します。Visual Studio は更新を促すメッセージを表示するので、ライフサイクルに組み込んでください。

サードパーティのライブラリは個別に更新する必要があり、Nuget を使用しないものもあるので注意してください。たとえば、ELMAH は別途更新する必要があります。

.NET Framework のガイダンス

.NET Framework は、高度な型システム、データ、グラフィック、ネットワーク、ファイル処理、および Microsoft エコシステムでの企業アプリケーションの開発に必要とされるその他大部分のものをサポートする一連の API です。.NET Framework は、アセンブリレベルで厳密な名前とバージョンが設定されたほぼユビキタスなライブラリです。

データアクセス

  • 例外なくすべてのデータアクセスに パラメータ化 SQL コマンドを使用する。
  • SqlCommandを、連結された SQL 文字列から成る文字列パラメータとともに使用しない。
  • ユーザーからの入力で許容できる値をホワイトリスト化する。列挙型、TryParse、または値のルックアップを使用して、ユーザーの入力したデータが想定どおりであることを保証する。
    • 列挙型は、想定外の値に対してはなお脆弱です。.NET は基となるデータ型 (既定では整数) へのキャストの成否しか検証しないからです。Enum.IsDefined を使用すると、入力値が、定義された定数リストの中で有効であるかどうかを検証できます。
  • 選択したデータベースでデータベースユーザーを設定する際には、最小権限の原則を適用する。データベースユーザーがアクセスできるのは、ユースケースで想定されるアイテムだけに限定することが必要です。
  • Entity Framework の使用は、非常に有効な SQL インジェクション対策メカニズムです。Entity Framework で独自のアドホッククエリを作成すると、プレーンな SQL クエリとまったく同様に SQL インジェクション攻撃を受けやすくなるので注意する。
  • SQL Server の使用時は、SQL 認証よりも統合認証を優先する。

暗号化

  • 暗号化処理を独自に実装しない。
  • 機密データを安全にローカルに保存するには、Windows データ保護 API (DPAPI) を使用する。
  • .NET Framework の標準ライブラリには、認証なしの暗号化実装しか用意されていません。より新しくモダンな Cryptography API: Next Generation に基づく AES-GCM などの認証付き暗号化モードは、CLRSecurity ライブラリから入手できます。
  • 強力なハッシュアルゴリズムを使用する。
    • .NET 4.5 で最強のパスワードハッシュ化アルゴリズムは PBKDF2 で、System.Security.Cryptography.Rfc2898DeriveBytes として実装されています。
    • .NET 4.5 で一般的なハッシュ化要件に対応した最強のハッシュ化アルゴリズムは System.Security.Cryptography.SHA512 です。
    • ハッシュ関数を使用してパスワードなどの一意でない入力値をハッシュ化するときは、元の値に salt 値を加えてからハッシュ化します。
  • 使用するアプリケーションまたはプロトコルが将来の暗号アルゴリズムの変更に簡単に対応可能であることを確認する。
  • Nuget を使用して、すべてのパッケージを最新の状態に保つ。開発セットアップで更新プログラムを監視し、アプリケーションへの更新の適用をを必要に応じて計画する。

全般

  • フレームワークにルートキットが潜む可能性を防ぐために、.NET Framework アセンブリの MD5 ハッシュを常に確認する。アセンブリの改ざんは可能であり、簡単にこれを作成できます。MD5 ハッシュを確認することで、改ざんされたアセンブリがサーバー機やクライアント機で使用されないように防止できます。File:Presentation - .NET Framework Rootkits - Backdoors Inside Your Framework.ppt を参照してください。
  • 設定内容をセキュアな状態にする。
    • 使用していない構成の要素をすべて削除する。
    • web.config の機密部分を、aspnet_regiis -pe を使用して暗号化する。

ASP.NET Web フォームのガイダンス

ASP.NET Web フォームは、.NET Framework 対応の最初のブラウザーベースアプリケーション開発用 API で、今でも最も一般的な Web アプリケーション開発用エンタープライズプラットフォームです。

  • 必ず HTTPS を使用する。
  • web.config で、requireSSL を Cookie とフォーム要素に対して有効にし、HttpOnly を Cookie に対して有効にする。
  • customErrors を実装する。
  • トレース がオフになっていることを確認する。
  • ViewState は Web 開発に必ずしも適しているわけではありませんが、ViewState を使用すると CSRF を軽減できます。ViewState で CSRF 攻撃を防御するには、ViewStateUserKey を次のように設定する。


protected override OnInit(EventArgs e) {
    base.OnInit(e); 
    ViewStateUserKey = Session.SessionID;
} 

Viewstate を使用しない場合は、ASP.NET Web フォームの既定のテンプレートの既定のマスターページにある、二重送信 Cookie を使用した手動の CSRF 防止トークンを使用してください。

private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
    // 次のコードは XSRF 攻撃からの防御に役立ちます。
    var requestCookie = Request.Cookies[AntiXsrfTokenKey];
    Guid requestCookieGuidValue;
    if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
    {
       // Cookie の XSRF 防止トークンを使用します。
       _antiXsrfTokenValue = requestCookie.Value;
       Page.ViewStateUserKey = _antiXsrfTokenValue;
    }
    else
    {
       // 新しい XSRF 防止トークンを生成して Cookie に保存します。
       _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
       Page.ViewStateUserKey = _antiXsrfTokenValue;
       var responseCookie = new HttpCookie(AntiXsrfTokenKey)
       {
          HttpOnly = true,
          Value = _antiXsrfTokenValue
       };
       if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
       {
          responseCookie.Secure = true;
       }
       Response.Cookies.Set(responseCookie);
    }
    Page.PreLoad += master_Page_PreLoad;
}

protected void master_Page_PreLoad(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
       // XSRF 防止トークンを設定します。
       ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
       ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
    }
    else
    {
       // XSRF 防止トークンを検証します。
       if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue || 
          (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty))
       {
          throw new InvalidOperationException("Validation of Anti-XSRF token failed.");
       }
    }
}
  • IIS で HSTS の使用を検討する。
    • [接続] ウィンドウで、カスタム HTTP ヘッダーを設定するサイト、アプリケーション、またはディレクトリに移動する。
    • [ホーム] ウィンドウで [HTTP 応答ヘッダー] をダブルクリックする。
    • [HTTP 応答ヘッダー] ウィンドウの操作ウィンドウで [追加] をクリックする。
    • [カスタム HTTP 応答ヘッダーの追加] ダイアログボックスでカスタムヘッダーの名前と値を設定し、[OK] をクリックする。
  • バージョンヘッダーを削除する。
   <httpRuntime enableVersionHeader="false" /> 
  • サーバーヘッダーも削除する。
   HttpContext.Current.Response.Headers.Remove("Server");

HTTP の検証とエンコード

  • web.config またはページ設定で validateRequest を無効にしない。この値は ASP.NET での XSS 対策を有効にします。クロスサイトスクリプティングを部分的に防止できるので、この値はそのままにしておいてください。
  • .NET Framework バージョン 4.5 には AntiXssEncoder ライブラリが含まれており、このライブラリには XSS 防止のための包括的な入力エンコードライブラリが用意されています。これを活用してください。
  • ユーザー入力を受け付けるときに許容する値をホワイトリスト化する。メールアドレスや URI が想定どおりであることを確認するには、regex 名前空間が特に便利です。
  • URI の形式を、Uri.IsWellFormedUriString を使用して検証する。

フォーム認証

  • 永続化にはできる限り Cookie を使用する。Cookie なしの認証の既定値は UseDeviceProfile です。
  • セッションまたは認証の永続化を求めるリクエストの URI を信頼しない。簡単に偽造できます。
  • フォーム認証のタイムアウトを既定の 20 分からアプリケーションに適した最短の時間に短縮する。slidingExpiration を使用した場合、このタイムアウトは各リクエスト後にリセットされるため、アクティブなユーザーには影響しません。
  • HTTPS を使用しない場合は、slidingExpiration を無効にすることをお勧めします。HTTPS を使用する場合でも、slidingExpiration の無効化を検討してください。
  • 必ず適切なアクセス制御を実装する。
    • ユーザーが入力したユーザー名を User.Identity.Name と照合する。
    • ロールを User.Identity.IsInRole と照合する。
  • ASP.NET メンバーシッププロバイダーとロールプロバイダーを使用する。ただし、パスワードの保存について見直してください。既定の保存方法では SHA-1 の 1 回分の繰り返しでパスワードがハッシュ化されますが、これは比較的脆弱です。ASP.NET MVC4 テンプレートでは ASP.NET メンバーシップではなく、ASP.NET Identity が使用され、ASP.NET Identity では既定で PBKDF2 が使用されます。こちらの方が優れています。詳細については、OWASP パスワードの保存に関するチートシートを参照してください。
  • リソースのリクエストを明示的に承認する。
  • User.Identity.IsInRole を使用してロールベースの認証を活用する。

ASP.NET MVC のガイダンス

ASP.NET MVC (モデルビューコントローラー) は、Web フォームポストバックモデルよりもさらに標準化された HTTP 通信を使用する最新の Web アプリケーションフレームワークです。

  • 必ず HTTPS を使用する。
  • 同期トークンパターンを使用する。これは Web フォームでは ViewState で処理されますが、MVC では ValidateAntiForgeryToken を使用する必要があります。
  • バージョンヘッダーを削除する。
   MvcHandler.DisableMvcResponseHeader = true;
  • サーバーヘッダーも削除する。
   HttpContext.Current.Response.Headers.Remove("Server");
  • PrincipalPermission を使用してコントローラーメソッドを修飾することで、無制限の URL アクセスを防止する。
  • ログオンメソッドで IsLocalUrl() を使用する。
   if (MembershipService.ValidateUser(model.UserName, model.Password)) 
   { 
       FormsService.SignIn(model.UserName, model.RememberMe); 
       if (IsLocalUrl(returnUrl)) 
       { 
           return Redirect(returnUrl); 
       } 
       else 
       { 
           return RedirectToAction("Index", "Home"); 
       } 
   } 
  • CSRF 攻撃を防ぐために、フォームのポスト時には常に AntiForgeryToken を使用する。HTML では次のようにします。
   <% using(Html.Form(“Form", "Update")) { %>
       <%= Html.AntiForgeryToken() %>
   <% } %>

さらに、コントローラーメソッドでは次のコードを使用します。


   [ValidateAntiForgeryToken]
   public ViewResult Update()
   {
       // gimmee da codez
   }
  • Web API サービスのセキュリティテストと分析を継続する。Web API サービスは MEV サイト内に隠されていますが、サイトの公開部分であり、攻撃者に発見されます。すべての MVC ガイダンスと WCF ガイダンスの多くが Web API に当てはまります。

XAML のガイダンス

  • アプリケーションのインターネットゾーンセキュリティの制約内で作業する。
  • ClickOnce 配置を使用する。拡張アクセス許可については、実行時にアクセス許可の昇格を使用するか、インストール時に信頼されたアプリケーションの配置を使用する。


Windows フォームのガイダンス

  • できる限り部分信頼を使用する。部分的に信頼された Windows アプリケーションは、アプリケーションの攻撃対象領域が小さくなります。アプリケーションで使用しなければならないアクセス許可と使用してもよいアクセス許可のリストを管理し、実行時にこれらのアクセス許可を宣言的にリクエストする。
  • ClickOnce 配置を使用する。拡張アクセス許可については、実行時にアクセス許可の昇格を使用するか、インストール時に信頼されたアプリケーションの配置を使用する。

WCF のガイダンス

  • RESTful サービスでリクエストを安全に渡す唯一の方法は、TLS を有効にした HTTP POST によるものです。GET はクエリ文字列で見えてしまい、TLS を使用しないと本文が傍受される可能性があります。
  • BasicHttpBinding は使用しない。これには既定のセキュリティ構成がありません。代わりに WSHttpBinding を使用する。
  • バインディングには 2 つ以上のセキュリティモデルを使用する。メッセージセキュリティは、ヘッダーにセキュリティ機構を組み込みます。トランスポートセキュリティは SSL の使用を意味します。TransportWithMessageCredential はこの 2 つを組み合わせます。
  • Zed Attack Proxy のようなファザーを使用して WCF 実装をテストする。

Authors and Primary Editors

Bill Sempf - bill.sempf(at)owasp.org
Troy Hunt - troyhunt(at)hotmail.com
Jeremy Long - jeremy.long(at)owasp.org

Other Cheatsheets

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets