セマンティックURL攻撃

自分の勉強用まとめです。解釈に間違いがあるかもしれないのでその時はご指摘していただけると助かります><

今回はセマンティックURL攻撃についてです。

セマンティックURL攻撃とは

セマンティックURL攻撃は、ユーザがURLを任意に変更して(ようするにGETパラメータを変更して)意図していない動作を引き起こす攻撃です。

CTFなどでたまに見かけます。

例をあげて解説していきます。

<form action="reset.php" method="get">
      <input type="hidden" name="user" value="palloc" />
      <p>メールアドレスを入力してください。</p>
      <input type="text" name="email" /><br />
      <input type="submit" value="Send Password" />
</form>

このようなコードを考えます。

reset.phpとこのコードは、

1.hiddenで隠されたユーザ名でユーザを識別

2.メールアドレスをreset.phpに送る

3.reset.phpでパスワードの再設定をし、そのメールアドレスに送信する

という動作をするとします。

その時、submitしたあとのurlは

http://hogehoge.co.jp/reset.php?user=palloc&email=palloc%40gmail.com

となります。

この時、セキュリティを特に知らない人でも、urlのuser=pallocは自分のユーザ名をさしていることに気づくはずです。

これを変えたらほかの人のパスワードをリセットできるんじゃないか?というのがもちろん現れてくると思います。

そして、次のようなURLを入力するとおもいます。

http://hogehoge.co.jp/reset.php?user=tino&email=palloc%40gmail.com

もしも、reset.phpが送られてきた情報をそのまま信用し処理を行うと、pallocくんがtinoちゃんのアカウントを乗っ取ることができてしまいます。

これが、セマンティックURL攻撃です。

対策

セッションを追跡していれば生まれない脆弱性です、以下に対策の一例を示します。

<?php
/*セッション生成*/
session_start();
$clean = array();
$email_pattern = '/^[^@\s<&>]+@([-a-z0-9]+\.)+[a-z]{2,}$/i';
/*emailのパターンチェック*/
if (preg_match($email_pattern, $_POST['email']))
{
    $clean['email'] = $_POST['email'];  
    $user = $_SESSION['user'];  /*セッション情報の保持*/
    $new_password = md5(uniqid(rand(), TRUE));  /*新パスワード作成*/

    if ($_SESSION['verified'])
    {
        mail($clean['email'], 'new password', $new_password);  /*パスワードを送信*/
    }
}
?>

このようにすれば、セッションを追跡しているため攻撃が成立することはありません。(あくまでセマンティックURL攻撃の話なので、他の攻撃が防げているかどうかは議論しないものとします)

参考文献:Essential PHP Security / Cbris Sbiflett著