Webエンジニアの雄大です。
とある脆弱性のあるサイトの問題を作ってみました。
とある上司に、こんなサイトを作れと命令された、Aさん、新卒。
サイトは、リンクを入力する。
例えば,オススメのリンクhttp://ameblo.jp/q2e2d2/とかを入力すると、それを受け取り、表示がされるというもの。
また、上司から、最近、Webセキュリティの問題になっている、クロスサイトスクリプティングに対応しろ!!と言われたので、Aさんは調べて、下記の対策を施しました。
function html_escape($name){
$name = str_replace(‘<’, ‘<’, $name); $name = str_replace(‘>’, ‘>’, $name);
$name = str_replace(‘&’, ‘&’, $name);
$name = str_replace(‘"’, ‘"’, $name);
return $name;
}
上司に見せたところ、セクハラのごとく、簡単に攻撃されてしまいました。
問題1.上司はどのようなリンクを入力したでしょうか。
問題2.上司への攻撃への、対策はどうすればいいでしょうか。
下記がAさんが作成したサイト。
<html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <title>脆弱性のあるサイト</title> </head> <body> <?php if(isset($_POST["name"])){ $name = html_escape($_POST["name"]); echo "<a href=".$name.">素敵なサイトへGo!!</a>"; } function html_escape($name){ $name = str_replace('<', '<', $name); $name = str_replace('>', '>', $name); $name = str_replace('&', '&', $name); $name = str_replace('"', '"', $name); return $name; } ?> <br /> <br /> <リンク先の入力> <form action ="./abunai.php" method="POST"> <input type="text" name="name" value=""> <input type="submit" value="送信"> </form> </body> </html>
問題1の答えの例は
javascript:alert(‘test’)
でした。実は’シングルクォーテーションもXSS対策しなければなりません。
問題2の答えの例は
$name = str_replace('\'', ''', $name);
シングルクォーテーションも適切に変換しましょう。
補足で、PHPではhtmlspecialcharsという関数もありますが、オプションでENT_QUOTESというのをつけないと、シングルクォーテーションは変換されません。
あとは、URLを出力する作業なので、httpかhttpsと始まる事をホワイトリストチェック方式でチェックしてあげましょう。
preg_match('/^https?/',$name)
最終的にこんなソースになりました。
<html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <title>脆弱性のあるサイト</title> </head> <body> <?php if(isset($_POST["name"])){ $name = html_escape($_POST["name"]); if(preg_match('/^https?/',$name)){ echo "<a href=".$name.">素敵なサイトへGo!!</a>"; } else{ echo "http or https からはじめたURLを入力してください。"; } } function html_escape($name){ $name = str_replace('<', '<', $name); $name = str_replace('>', '>', $name); $name = str_replace('&', '&', $name); $name = str_replace('"', '"', $name); $name = str_replace('\'', ''', $name); return $name; } ?> <br /> <br /> <リンク先の入力> <form action ="./abunai.php" method="POST"> <input type="text" name="name" value=""> <input type="submit" value="送信"> </form> </body> </html>
コメント