PHPでのオープンリダイレクト対策方法とサンプルの紹介
オープンリダイレクト対策
アンテナサイトなどリダイレクトで飛ぶサイトでは対策が必須です。
PHPでの対策をいろいろ語りたい。
なお、データベースを使って「ID200=donndonn.com」と照合するのが完璧ではありますが、
毎回データベースを使うのは負荷が大きいのでPHPでどうにかします。
1、URLを難しくする
オープンリダイレクト攻撃も総当たり攻撃されています。
よく使われるだろうGETクエリ「url」「to」なんかはやばい。
手当たり次第に攻撃して、200が返ったドメインはさらに攻撃!と。
毎日とんでもない攻撃が来るので負荷も大きいです。
したがって、GETクエリ文字等は難しくします。
URLは短い方が良いのですが、仕方ない。
「ba0ba98」など適当な文字列にしよう。
実際、「go」は攻撃が来ますが、「go2」は全く来ないことを確認した。
とりあえず、これで総当たり攻撃は防げる。
2、自サイトのリファラのみ許可する
リファラが自分のドメインの場合のみ許可することで少し安全に。
リファラは偽造できますが、普通にWEBサイトに貼ったリンクでは偽造できない。
その場合は何かしらのページを挟む必要があるので不正が面倒になります。
こういった鍵を増やすような対策も大事。
簡単に言えば「直リンク禁止」です。
3、GETクエリを増やす
リダイレクト用以外にもクエリを増やすと少し安全に。
これも総当たり攻撃対策にはなります。
「url」という危ないクエリを使う場合でも、
「baj93b」といった文字列のクエリも入れて判別すると攻撃を防げる。
<こんな感じ>
https://doudonn.com/?url=example.com&baj93b=z
実際、総当たり攻撃のログを確認していますが、
一つの「url」だけ入れて攻撃してきます。
したがって、クエリが二つあるだけでほぼ総当たり攻撃は防げる。
ここまでは自動攻撃対策。
次からは手動攻撃対策です。
4、許可ドメインをまとめたホワイトリストを作る
リダイレクトURLのドメインを判別する。
アンテナサイトの場合はURLがたくさんあるので、
ドメイン名で判別することになります。
登録サイトのドメインを配列にまとめて、それを使います。
可否判別は「^https?://」+「ドメイン/」で照合すれば良い。
URL全体で照合すると、クエリ文字等とサブドメインが引っかかる。
不正なものは削除して、不正なサブドメインは除外する照合にしないといけない。
5、PHPでの判別サンプル
<?php
$redirecturl = urldecode($_GET["url"]);
$whitelist = "#^https?://doudonn\.com/|^https?://blog\.livedoor\.jp/#";
if(preg_match($whitelist,$redirecturl) === 1){
//OK
}else{
//不正ログ
//NG
header("HTTP/1.1 404 Not Found");
exit;
}
?>
負荷を軽くするため、マッチしやすいドメインを最初の方に持って来て下さい。
6、最後に
判別失敗のログは取得すること。
NGにしてはいけないURLまでNGにしてしまっている可能性がある。
どんなものでもミスしてしまうのが人間。
NGとなったURLはログとして残して確認するようにしよう。
処理速度はこうしてPHPでやる方がDBへアクセスして確認するよりも速いです。
ホワイトリストが500件くらいあっても全然問題ない。