ASP.NETでWebアプリを作るわけですが、セキュリティ対策っていったい何をしないといけないのかさっぱりわかりません。しかし、対策をしないといけないことだけは知っています。
せっかくなので、本などを買いつつ勉強してみましたので自分なりにまとめてみます。
素人が調べつつまとめた内容ですから、間違っている可能性や、情報が古かったり、最適な対策ではない可能性がありますので、参考にする場合にはご注意ください。
基本的な注意点
HTTPリクエストのGETとPOSTの使い分け
GET
・短いデータ
・データの参照
・秘匿性のない情報
POST
・長いデータ
・データの更新
・秘匿性の高い情報
GETの注意点
・URLにパラメータが表示される
・Refererにパラメータが表示される
※Referer:HTTPリクエストのヘッダに付与される情報のひとつで、前のページのURLがそのまま格納されている。URLに秘匿性の高い情報が付与されたまま、外部サイトへ遷移した場合、外部サイトにその情報が漏洩する。
hidden属性による値の保持
・hidden属性の値は利用者が改変可能
・利用者の端末から書き換えは出来るが、利用者以外からの書き換えや漏洩には強い
・ログイン機能があるサイトにおいて、ログイン前に扱われるデータはhiddenパラメータを使うことで、漏洩に対して堅牢になる
データの保持に利用される値の改変について
改変可能な値
・クッキー
・hidden属性の値
・GET/POSTの値
改変不可能な値
・セッション変数
クッキーとセッション
データの実体
クッキーは利用者のPC上にファイルとして保存される。
一方で、セッションはセッションIDをクッキーとして保存し、対になる情報をWebサーバーのメモリやファイル、データベースなどに保存されている。
クッキーの設定
Domain属性 |
Domain属性を指定しないデフォルトでは、自ドメインのみで有効となっているため、デフォルトが最もセキュリティレベルが高い。 複数ドメインでクッキーを共有したい場合に設定するが、設定しないのが原則。 |
Path属性 |
クッキーはDomain属性を指定しない場合、自ドメイン内で共有されるが、これをディレクトリごとに分割したい場合にはPath属性を設定する。「Path=/shopping」と指定すると、shoppingフォルダ内のWebページのみに有効なクッキーが発行される。 通常では指定しない。未指定の場合「Path=/」となる。 |
Expires属性 |
クッキーの寿命を設定することができる。指定しない場合には、ブラウザの終了と同時に削除されるが、次回から自動ログインにしたい場合などには設定が必要となる。 |
HttpOnly属性 |
HttpOnly属性を設定することで、JavaScriptからクッキーを参照することができなくなる。通常はJavaScriptからクッキーを参照することはなく、脆弱性を増やす要因になるため設定することが望ましい。 |
Secure属性 |
HTTPS通信時にのみクッキーの送信を有効にする。 |
クッキーとセッションの比較表
|
クッキー |
セッション |
使いやすさ |
APIにより設定・取得 |
変数と同じように使用 |
配列やオブジェクトの格納 |
文字列に変換する必要がある |
変換せず代入することができる |
サイズ制限 |
少量のデータに限る |
無制限 |
利用者による情報の参照 |
容易 |
不可能 |
情報漏洩しやすさ |
クッキーが漏洩すると情報も漏洩する |
クッキーが漏洩しても漏洩しにくい(制御可能) |
利用者による改変 |
容易 |
不可能 |
第三者による改変 |
XSSやHTTPヘッダインジェクションなどにより可能 |
セッション変数の改変は不可能 |
情報の寿命 |
設定可能 |
セッション限り |
他サーバーとの情報共有 |
ドメインが同じであれば可能 |
原則として不可能 |
攻撃の種類と概要
SQLインジェクション
データベースアクセスに利用される入力値にデータの終端文字を混入し、命令を埋め込む。SQLクエリにおけるデータの終端文字としては「’」などがあげられる。
データベース内の情報が盗まれたり、内容が書き換えられたりする可能性があるほか、ログイン認証の回避にも悪用される可能性がある。
原因:リテラルの検証不足
対策:
・プレースホルダーを使う
・エラー画面でエラーの詳細(メソッド名やデータベースのテーブル名など)を表示しない
・入力値には、最低限文字数制限を必ず付与する。
・アプリが利用するDBユーザーに対しては、アプリに求められる最小限の権限のみを与える。
XSS(クロスサイトスクリプティング)
HTML(HTTPレスポンスのボディ部))にデータの終端文字を混入し、JavaScriptなどの命令を埋め込む。HTMLにおけるデータの終端文字としては「<」「”」などがあげられる。ブラウザ上でJavaScriptや偽情報が表示され、クッキーのセッションIDを盗まれ、利用者がなりすまし被害にあったり、ページの改ざんにあったりする恐れがある。
原因:動的にHTMLを生成する際に、特殊記号(メタ文字)を正しく処理していない
対策:
・動的生成する項目の特殊記号をエスケープする
・文字エンコーディングを統一する
・可能であれば、JavaScriptの自動生成は避ける。
・JavaScriptの文字列リテラル部から英数字以外を除去する。
・エラー画面でエラーの詳細(メソッド名やデータベースのテーブル名など)を表示しないようにする
・入力値には、最低限文字数制限を必ず付与する。
セッションハイジャック
攻撃者が何らかの方法により、正規の利用者のセッションIDを知り、それを悪用して正規の利用者になりすましてWebサイトを利用する。
被害にあった利用者が可能なあらゆる操作を行うことができる。
原因:
・セッションIDの推測
・セッションIDの盗み出し
・セッションIDの強制
対策:
・セッションIDの生成はJavaやASPの標準機能を使う
・セッションIDはクッキーに保存する
・ログイン認証時にセッションIDを変更する
・XSSやその他インジェクション系への対策を行う
CSRF(クロスサイトリクエストフォージェリ)
攻撃者が用意した悪意のあるWebサイトを閲覧した利用者の認証情報を利用して攻撃用のHTTPリクエストを送信する。基本的に、1度のHTTPリクエストで完了する処理が攻撃対象となる。
被害にあった利用者が可能な多くの操作を行うことができる。
原因:
・<form action ="">には自ドメイン以外も指定できる
・セッションIDは自動的に対象サイトに送信される
対策:
・重要な処理の前に、再度パスワードを要求する
・重要な処理の前画面でhidden属性に乱数やセッションIDなどを埋め込み、重要な処理の画面で正しい値が届いているか確認する
オープンリダイレクタの脆弱性
外部からの入力によってリダイレクト先を動的に生成している個所がある場合、攻撃者が用意した悪意あるWebサイトにリダイレクトされてしまう。利用者は信頼できるWebサイトを閲覧しているつもりで、実際には悪意あるWebサイトに誘導されてしまい、重要な情報などを盗み出されるおそれがある。
悪意のあるWebサイトに誘導したり、マルウェア被害にあう。
原因:リダイレクト先を自動生成したり、入力値を使用している
対策:
・リダイレクト先のURLを固定するか、DBやリストなどの一覧から取得する
・リダイレクト先のドメインをチェックする
・リダイレクトする旨を表示するクッションページを用意する
HTTPヘッダインジェクション
HTTPレスポンスのヘッダ部に改行文字を挿入することで、悪意ある記述が追加されたり、レスポンスのボディ部を改変されたりしてしまう。
悪意あるURLへリダイレクトされたり、表示内容を改変されたり、任意のスクリプトを実行される。
原因:レスポンスヘッダに改行文字(ヘッダにおける終端文字)が含まれる
対策:
・外部からの入力値をレスポンスに埋め込まない
・レスポンス生成はJavaやASPの標準機能を利用する
・ヘッダを生成する時に改行文字を除去する
OSコマンドインジェクション
WebアプリケーションからOSコマンドを実行する処理がある場合、悪意あるコマンドを実行されてしまう。
最悪の場合、攻撃者がサーバーの管理者権限を取得しWebサーバーを自由に操作される。その他、ファイルの閲覧・改ざん・削除や攻撃の踏台に利用される恐れがある。
メールヘッダインジェクション
メールヘッダに改行文字を挿入することで、メールヘッダに悪意あるヘッダ情報を混入し、メールの内容を改変されてしまう。改変可能なのは本文のみに留まらず、件名、送信先、本文を改変・追加したり、添付ファイルをつけられたりするケースもある。
メールの件名や送信先、本文を改変されたり、迷惑メール送信に悪用されたりする。
つづく