個人ブログ

インフラ、アプリケーションまわり

Webの脆弱性についてまとめる

Webの脆弱性について、まとめてみます。 こちらも勉強中のため、随時更新。

クロスサイトスクリプティングXSS脆弱性

  • 主に、エンドユーザーから悪意のある入力値を送信される・悪意のあるスクリプトを実行されるなどの脆弱性
  • 対策としては、フォームからの入力値にエスケープ処理を施すなどが必要。

SQLインジェクション

  • SQL命令に不正なパラメータが渡されることによって、意図しないデータ操作が行われてしまうこと。
  • データ操作はライブラリ経由で行うこと。またそもそも、外部からの入力値をそのまま使ってSQLを構築しないこと。

OSコマンドインジェクション

  • OSコマンドに対して、外部からの入力値などにより、不正な命令などがコマンド上で実行されること。
  • そもそも、スクリプトからコマンド操作を行う命令(関数)を使うべきではない

クロスサイトリクエストフォージェリCSRF

  • 例えばフォーム送信などで、クライアントユーザーが意図しないうちに、入力値が送信されたりする脆弱性
  • 「ユーザーが意図しない操作」

対策

  • ワンタイムトークン方式を用いる
  • あらかじめ、任意のトークン値を作成しておき、これを正規のフォームにhidden属性として埋め込んでおく。
<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