n階層システム設計の考慮点

第8回セキュリティ設計について

今回は、各階層での設計についての注意点およびノウハウについて解説していきます。

Microsoft社は開発者向けに下記の「開発者向けセキュリティ ガイダンス」を公開しています。

WebアプリケーションおよびWindowsアプリケーションに関するセキュリティに関してのガイダンスは、こちらにほとんどが記載されています。是非参考にしてください。

今回は上記の内容を踏まえ、私の経験、ノウハウを追加させいて頂きます。そのため、一般に言われている脅威であるとかセキュリティホールなどのすべての項目は記載できません。上記のMicrosoft社の「セキュリティガイダンス」と共に読んで頂ければと思います。

① ホストレベルでの代表的な脅威とその対策について

ホストレベルでの代表的な脅威とその対策について説明します。ここでは、ホストといってもメインフレームのホストではなく、.NETアプリケーションが稼働するサーバPCのことを指します。

表1 ホストレベルへの脅威とその対策
脅威 対策
ウイルス、トロイの木馬、ワーム

オペレーティングシステムに最新のサービスパックおよびソフトウェアの修正プログラムを導入する場合については、やみくもにサービスパック等を適用するのではなく、必要であるもの、使用環境に影響があるものを、使用環境での十分な事前検証を行ったうえで適用します。これらの検証を怠ると、サービスパック等の適用により、想定外のアプリケーションやサービスが導入・稼働され、または必要なサービスが非稼働にされ、アプリケーションに影響を及ぼす場合があります。

オペレーティングシステムに適合したウイルス予防ソフトウェアを導入し、機能を有効にしておきます。この際、ウイルス予防ソフトにファイル操作に関するリアルタイムのウイルス検査機能がある場合はそれらを有効にします。また、定期的にメモリ、ファイル管理領域、ファイルの検査を行います。この際、ウイルスパターンファイルは最新のものを使用します。

フットプリンティング(ポートスキャン、Pingスイープ、NetBIOS列挙等)

サーバ機でワイヤレスネットワークを使用していない場合は、サービスやプロトコル等を無効にします。

Telnet等のサービスに関しても最低限のサービスのみを有効にし、無効のサービスで使用するポートについては塞ぎます。

パスワードクラッキング

パスワードで使用可能とする文字列には、社名や部署名、氏名、年月日等の推測されやすい文字ではなく、最低文字数を8文字以上にし、アルファベット+数字+記号をそれぞれ1~2個ずつ挿入し、推測されないようにします。

パスワードの有効期間を業務に支障のない程度に短くします。また、過去5回以上の変更履歴を取り、再利用を防ぎます。パスワードが切れる少し前からユーザ情報に登録されたメールアドレスに対して返信不可のメールにて事前通知し、パスワードの変更をユーザに促します。

サービス拒否

オペレーティングシステムの状態を監視するソフトウェアを導入し、CPUやメモリの使用量の監視を行い、しきい値を超える値を検知した場合は管理者に通報する仕組みの導入を検討します。

サーバOSにWindows Server 2008を使用する場合、Server Coreの導入を検討します。

② アプリケーションレベルでの代表的な脅威とその対策について

アプリケーションレベルでの代表的な脅威とその対策について説明します。

表2 アプリケーションレベルへの脅威とその対策
カテゴリ
脅威 対策
入力検証
クロスサイトスクリプティング

詳細は「 画面設計での考慮点とノウハウについて」で後述します。

SQLインジェクション

詳細は「 画面設計での考慮点とノウハウについて」で後述します。

正規化

詳細は「 画面設計での考慮点とノウハウについて」で後述します。

認証
ネットワーク盗聴

パスワードをネットワーク経由で転送する必要がある場合は、パスワードを暗号化するか、または暗号化された通信チャネル(SSL/TLSなど)を使用します。

Cookieリプレイ

Cookieドメイン属性を設定し、できるだけ狭い範囲のドメインのみを設定します。これにより、ほかのドメインへの影響を少なくすることができます。

資格情報の盗用

強力なパスワードを使用します。例えば、社名や部署名、氏名、年月日等の推測されやすい文字ではなく、最低文字数を8文字上にし、アルファベット+数字+記号をそれぞれ1~2個ずつ挿入し、推測されないようにします。

セッション管理
セッションハイジャック

SSL/TLSを使用してセキュリティで保護された通信チャネルを作成し、認証Cookieを渡す場合は必ずHTTPS接続を使用します。またこの場合、Cookieのsecure属性を設定します。

セッションIDをHiddenタグで管理している場合、ログイン前に使用したセッションIDはログイン後には使用しないようにします。

セッションIDにはGUIDなど、長くてランダムな値を使用し、この中にユーザID等の情報は含めないようにします。これにより、セッションIDの推測による攻撃を防ぐ可能性が高くなります。

Cookieドメイン属性を設定し、できるだけ狭い範囲のドメインのみを設定します。これにより、ほかのドメインへの影響を少なくすることができます。

セッションリプレイ

重要な機能を実行するときは再認証します。たとえば、銀行取引アプリケーションで送金する前には、ユーザに再びアカウントパスワードを要求します。

Microsoft Internet Explorerでは「暗号化されたページをディスクに保存しない⁠⁠、⁠ブラウザを閉じた時、[Temporary Internet Files]フォルダを空にする」の詳細オプションを使用します。

Cookieドメイン属性を設定し、できるだけ狭い範囲のドメインのみを設定します。これにより、ほかのドメインへの影響を少なくすることができます。

例外管理
攻撃者による実装の詳細情報の開示

System. Exceptionのルートクラスは非常にCUP、メモリなどの資産を使用します。そのため、例外処理ではできるだけスコープの狭い例外処理を使用します。

アプリケーション境界に伝達できる例外を処理してログに記録します。この際、例外発生場所やエラー情報などが分かるように途中で無駄なスローをしないようにします。また、必要がない限り例外情報はアプリケーション境界を超えないように設計します。

IISや.NET Framework等実行環境が表示するエラーメッセージは表示しないようにし、必ず、カスタムエラーメッセージを返します。

サービス拒否

すべての入力データをサーバで徹底的に検証します。詳しくは後述しますが、入力データのチェックやサニタイジング等を行います。

③ Web Formアプリケーションでの代表的な脅威とその対策について

Web FormアプリケーションではWindows Formアプリケーションで想定される脅威以上に以下の表に示すような脅威について対策を検討する必要があります。

表3 Web Formアプリケーションへの脅威とその対策
脅威 対策
ユーザ識別情報のなりすまし

強力な認証を使用します。Microsoft NTLMや第三者の認証機関の電子署名等を使用した認証方式を検討します。

認証Cookieは、SSL/TLSで保護します。

データの改ざん

強力な承認を使用します。Microsoft NTLMや第三者の認証機関の電子署名等を使用した認証方式を検討します。

④ 画面設計での考慮点とノウハウについて

画面設計を行う際に気を付けなければならない考慮点とノウハウについて説明します。

A) ソースコードからの情報漏洩

Webアプリケーションの場合、通常の操作ではソースコードは見ることはできませんが、サーバの脆弱性などによりソースコードの一部が流出することが考えられます。そのため、ソースコード内には内部で使用するユーザ名やパスワード等を記述せずに、安全な場所に格納されたファイルやConfigファイル内に外部ファイルとして記述するようにします。

しかし、Webアプリケーションの稼働中にはこれらのファイルの変更をしないようにします。

B) 画面からの情報漏洩

個人ごとに登録されたクレジットカード番号や口座番号を画面上に表示する場合、全桁を表示するのではなく、一部のみを表示するようにします。これにより、盗み見や不正アクセスなどにより攻撃者に知られても使用することができないようにします。

C) フィッシング詐欺

Webアプリケーションの場合、本物の画面とよく似た画面をもつサイトに移動させてクレジットカード番号などの個人情報を盗み取ろうとするフィッシング詐欺があります。さらに、フレームを使用して画面を設計している場合、サブフレームがフィッシング詐欺用の別のサイトに移動してもアドレスバーにはメインフレームのURLが表示されているため、見抜くことは難しいです。これを見抜くためには、アドレスバーに表示されているURLを確認したり、右クリックでサイトのプロパティを確認できるようにします。

D) ユーザによる表示ページの保護状態の確認不可

Webアプリケーションの場合、JavaScriptやブラウザの設定により、アドレスバーやステータスバーを非表示にすることができます。これにより、表示されているページがSSL/TLSによって保護されているか確認ができない場合があります。また、フレームを使用して画面を設計している場合、メインフレームがSSL/TLS対応になっていてもサブフレームがSSL/TLS対応になっていない可能性があります。この場合はステータスバーには保護マークが表示されたままになります。またこの逆の場合、つまりメインフレームがSSL/TLS非対応でサブフレームがSSL/TLS対応の場合ではステータスバーには保護マークが表示されません。これらを防ぐためには、以下の点を考慮して設計します。

  • アドレスバーを非表示にしない
  • ステータスバーを非表示にしない
  • フレームを使用して画面を構成するのではなく、CSSを使用する設計とする
  • 右クリックを禁止しない
  • SSL/TLS対応コンテンツとSSL/TLS非対応のコンテンツを混在させない

E) JavaScriptやActiveXのセキュリティレベルを変更しない

サイトによってJavaScriptやActiveXのセキュリティレベルを変更していると、変更し忘れで思わぬ攻撃を受ける場合があります。そのため、これらの設定は社内で決められた設定を使用し、変更しないようにします。

F) 入力チェック

入力チェックについては第3回に記載していますのでそちらをご参照ください。

G) サニタイジング

サニタイジングでは入力時のチェックだけと考えられがちですが、エラーの表示方法やメッセージについても考慮する必要があります。攻撃者がログイン画面などで「ユーザID⁠⁠、⁠パスワード」を総当たり攻撃をしてきた場合、⁠パスワードが間違っています。」といったメッセージを表示した場合、暗に「ユーザID」が存在していることを知らせていまいます。そのため、例えば「ユーザID、パスワードが間違っています。」とメッセージを変更するだけで保護性は高まります。

Webアプリケーションでは、存在しないページへの直接アクセス、ブックマークアクセス(セッション有効期限切れ等も含む)等のエラーメッセージも同一のカスタムエラーページとすることで、サーバ環境の情報や攻撃対象となるページの特定を防ぐことができます。

入力時のチェックとしては「SQLインジェクション⁠⁠、⁠OSコマンドインジェクション⁠⁠、⁠各プログラム言語の外部コマンドインジェクション⁠⁠、⁠SSI(Server Side Include)インジェクション⁠⁠、⁠LDAPインジェクション⁠⁠、⁠XPathインジェクション⁠⁠、⁠クロスサイトスクリプティング⁠⁠、⁠URLリクエストへの無効文字挿入⁠⁠、⁠メールヘッダ改ざん」等があります。これらの問題点と対策について説明します。

表4 サニタイジングでの入力時チェック
問題点 考慮点とノウハウ
SQLインジェクション

ほとんどの RDBMS が準拠している「SQL92」での特殊文字のほかにも、各RDBMSが個別に拡張している文字もあるので、それらの特殊文字の確認も必要となります。主な「SQL92」での特殊文字の例は以下のものがあります。

  • 「空白、( )」⁠文字列やコマンドの区切り)
  • 「⁠⁠、⁠、,」⁠文字列の区切り)
  • 「-」⁠負の数を表すため)
  • 「.」⁠フィールドの指定)
  • 「&、+、/、|」⁠演算子)
  • 「:」⁠変数の設定)
  • 「;」⁠コマンドの区切り)
  • 「<、=、>」⁠演算子)
  • 「%、?、*、_」⁠正規表現)
OSコマンドインジェクション

.NET Frameworkが稼働する環境でのOSコマンドの例は以下のものがあります。

  • 「;、|、&」⁠コマンドの実行など)
  • 「x00」⁠NULL 文字 文字列やファイル名の中断など)
  • 「x20」⁠空白文字 パラメータの区切りなど)
  • 「x04」⁠EOT 文字 ファイルの終わりなど)
  • 「x0A、x0D」⁠改行文字 追加コマンドの実行、メールの偽造、ファイルの変更など)
  • 「x1b」⁠エスケープ文字)
  • 「x08」⁠バックスペース文字 ログファイルの偽造、ファイルの変更など)
  • 「x7f」⁠削除文字)
  • 「⁠⁠」⁠文字列の区切りなど)
  • 「/、-」⁠パラメータの指定など)
  • 「*、?」⁠正規表現など)
  • 「.、\」⁠ディレクトリ指定など)
  • 「<、>」⁠ファイル操作など)
  • 「%」⁠環境変数の参照など)
クロスサイトスクリプティング

クロスサイトスクリプティング脆弱性対策においても入力データの無効化(サニタイジング)を行います。主なサニタイジング対象文字とサニタイジング後の文字の例は以下のものがあります。

  • 「<⁠⁠→⁠&lt;」
  • 「>⁠⁠→⁠ &gt;」
  • 「&⁠⁠→⁠&amp;」
  • 「⁠⁠→⁠&quot;」
  • 「⁠⁠→⁠&#39」
URLリクエストへの無効文字挿入

URL 内に「%00」が含まれていた場合、⁠%00」をNULL 文字と解釈されないようにするため、⁠%00」についても入力データチェックを行うようにします。

メールヘッダ改ざん

メールヘッダの改竄を防止するため、メール送信を行う際のメールヘッダへの入力データ埋め込みは避けるようにします。メールヘッダはできるだけ固定化し、ユーザからの入力データはメール本文に埋め込む方式を採用します。

運用上の特徴や問題などから、メールヘッダを固定化できずメールヘッダへ入力データを埋め込む必要がある場合は、ユーザからの入力データに対して不適切な文字列が含まれていないか、メールヘッダとして適切な文字列となっているかチェックを行います。また、特殊文字に対して、無効化(サニタイジング)を行います。

おもな特殊文字の例は以下のものがあります。

「%」+ 16 進数文字列を使用して文字列を操作することができるためチェックするもの

  • 「%20」⁠スペース)
  • 「%25」⁠パーセント)
  • 「%0A」⁠改行)
  • 「%2520」⁠スペース)など

別プログラムの動作や、プログラム、OSコマンドの挿入、ファイル名の取扱時などに不適切なパラメータの挿入を防ぐためチェックするもの

  • 「!」⁠感嘆符)
  • 「&」⁠アンド)
  • 「|」⁠パイプ)
  • 「`」⁠バッククオート)
  • 「;」⁠セミコロン)
  • 「:」⁠コロン)
  • 「*」⁠アスタリスク)
  • 「,」⁠カンマ)
  • 「?」⁠疑問符)
  • 「/」⁠スラッシュ)
  • 「\」⁠バックスラッシュ)
  • 「-」⁠マイナス)
  • 「.」⁠ドット)
  • NULL(x00)
  • 「⁠⁠、⁠、{}、[]など」⁠各種括弧文字)など

HTMLタグの埋め込みや、クロスサイトスクリプティングなどを防ぐためチェックするもの

  • 「<」
  • 「>」
  • 「⁠⁠」
  • 「⁠⁠」
  • 「&」など

H) ディレクトリトラバーサル

ディレクトリトラバーサルとは、相対パス記法(../~、../../~)などを利用して、本来アクセスできない(アクセス権を与えていない)はずのWebページやファイルへのアクセスを許してしまう脆弱性のことです。

これを防ぐには各ディレクトリに適切なアクセス権を与えるとともに、できる限り絶対パスを外部ファイルなどで指定し、相対パスでのアクセスを使用しないように設計します。

入力文字に「../」が含まれていないかチェックするとともに相対パスを使用するする必要がある場合にはパス名を正規化して使用します。また、指定されたパス名の存在チェックおよび対象ファイルが予約デバイス名などを含んでおらず一般ファイルであるかどうかのチェックを行います。パス名を正規化した例は以下のものがあります。

「//」を含むパス名の場合:
「/apphome//user/data⁠⁠→⁠/apphome/user/data」
「/./」を含むパス名:
「/apphome/./user⁠⁠→⁠/apphome/user」
「/../」を含むパス名:
「/apphome/user/../xml/⁠⁠→⁠/apphome/xml」

I) 不要なデコードの防止

WebアプリケーションのURL文字列中に、URLエンコーディングされた文字列「%252e%25e」が含まれていると複数回デコードすると「..」となります。これにより、意図しない階層のディレクトリやファイルへアクセスされる危険性があります。

これを防ぐためには不要なデコードはしないように設計します。また、アプリケーションで公開したくないディレクトリへのアクセス権を適切に設定します。

J) 予約デバイス名

Windows OSでは以下の文字列が予約語として使用されています。これらを入力された場合、指定されたデバイスが開かれ、最悪の場合、処理が中止される場合があります。そのため、これらの文字列を使用したディレクトリやファイル名を使用しないこととともに、入力チェックでエラーとする必要があります。

「AUX⁠⁠、⁠CON⁠⁠、⁠NUL⁠⁠、⁠PRN⁠⁠、⁠CLOCK$⁠⁠、⁠COM1~9⁠⁠、⁠LPT1~9」

K) レースコンディション

マルチスレッドアプリケーションにおいて発生する可能性があります。複数のスレッド間で同期が図られていないときに、共通のグローバル変数やファイルに対して参照・更新を行っていることにより、意図しない変数やファイル内容の更新が行われ、データの破壊やデータの正確性が損なわれる可能性があります。

そのため、これらの共通変数、データ類の操作にはスレッド同期や業務排他の仕組みを利用し、設計時に細心の注意が必要です。

しかし、スレッド同期は多用すると必要以上にオブジェクトをロックするため処理性能が落ちる可能性があります。このようなことも意識した上で、必要最小限の部分のみにスレッド同期を使用するように設計を行う必要があります。

おすすめ記事

記事・ニュース一覧