Webの脆弱性についてまとめる
Webの脆弱性について、まとめてみます。 こちらも勉強中のため、随時更新。
クロスサイトスクリプティング(XSS脆弱性)
SQLインジェクション
- SQL命令に不正なパラメータが渡されることによって、意図しないデータ操作が行われてしまうこと。
- データ操作はライブラリ経由で行うこと。またそもそも、外部からの入力値をそのまま使ってSQLを構築しないこと。
OSコマンドインジェクション
- OSコマンドに対して、外部からの入力値などにより、不正な命令などがコマンド上で実行されること。
- そもそも、スクリプトからコマンド操作を行う命令(関数)を使うべきではない
クロスサイトリクエストフォージェリ(CSRF)
- 例えばフォーム送信などで、クライアントユーザーが意図しないうちに、入力値が送信されたりする脆弱性。
- 「ユーザーが意図しない操作」
対策
<input type="hidden" name="token" value="{{ トークン値 }}">
- 一方、上記のトークン値をセッション値としても持たせておく。
- フォーム送信時、送信先において「トークンが送信されているか」「送信されたトークン値は正しいか」を判定し、これらに該当しない場合は不正な送信として、403とかで弾く。
<?php session_start(); $token = $_POST['token']; if (! isset($token)) { http_response_code(403); } if ($token !== $_SESSION['token']) { http_response_code(403); } ?>
パストラバーサル脆弱性
メールヘッダインジェクション
対策
- 特にメールの(送受信先の)アドレス部分に関しては、入力値をそのまま使わないこと
- 必ず、正規表現などによって、意図するアドレスの場合にのみ送信されるようにする。
- その他、inputタグの隠しフィールドとして、アドレス情報を持たせておくのも避けるべき(inputタグは簡単に書き換えられるから)
ファイルアップロード攻撃
- 不正なファイルがアップロードされ、実行されてしまう脆弱性
- 対策としては、ファイルアップロード時に、アップロードできるファイルの種類を限定的にするなど。
全体感
全体として、リクエスト情報全般について、妥当性を検証する必要がある。 リクエスト情報というと、フォームからの入力値などを想像しやすいが、それだけではない。 セッション情報やサーバー情報、HTTPリクエストヘッダなどからも、不正な値が送信されないかチェックする必要がある。
要は「バリデーションを強める」ということなのだが、下記などはおろそかになりやすい。
- 文字エンコーディングは意図したものか(XSS脆弱性の原因となる)
- nullバイトはチェックされているか
- 必須検証は適切か(isset()は空文字列であってもtrueを返すので不適切)
- 数値検証は適切か(is_int()だと、スーパーグローバル変数を適切にバリデートできない)
以下、コード例にて検証してみる(PHP)