2008/05/22

PHP: use_trans_sidの注意点

まず、そもそもCookieを使わずにリンクにセッションIDをつけるリスクは下記の通り。
  1. セッションIDを誤って外部サイトへ送信してしまうと、第三者にセッションをのっとられる(いわゆるセッション・ハイジャック)。
  2. 明示的に送信しなくても、外部サイトへのリンクがあればReferer(リファラ)からログに残ってしまったり、プログラムによって取得されてしまう。
PHPではsession.use_trans_sidをonに設定すれば全てのリンクにセッションIDを付与してくれるけど、挙動が今いちわからなかったのでちょっと調べてみた。
  1. 一応外部サイトへのリンクにセッションIDは付与されない。
  2. ただし、フォームでは外部サイトであるかどうかの判別はされず、自動的にhiddenで埋め込まれてしまう。挙動の調整には url_rewriter.tags を使う。
  3. 外部サイトへのリンクとは、リンクの文字列に":"(コロン)があるかどうかで判別している。
  4. ようは「外部サイト」という判別はしていなくて、同じホストでもhttpsへのリンクやもちろん「http://」や「javascript:」等のリンクにはセッションIDが付与されない。 かつ、プロトコルの文字列判別してるわけでもないので、foo.php?param:abc=1というリンクでも付与されない。。。パラメータ名にコロンてあまりない気がするけど、使わないように考えておく必要はある。
ちなみに、output_add_rewrite_varも同じ動作をする。実際の動きは下記の通り。
<?php
ini_set('session.use_cookies','off');
ini_set('session.use_trans_sid', '1');
session_start();
output_add_rewrite_var("foo", "bar");
?>
<!-- 普通の内部リンク ○ -->
<a href="./next.php">next</a>
<!-- 普通の内部POST ○ -->
<form method="POST" action="./next.php">
<input type="submit">
</form>
<!-- 外部リンク × -->
<a href="http://www.fork.co.jp/">next</a>
<!-- 外部へPOST ○ -->
<form method="POST" action="http://www.fork.co.jp/">
<input type="submit">
</form>
<!-- 内部リンクだけど:(コロン)付き × -->
<a href="./next.php?param:1=1">next</a>
<a href="javascript:location.href='next.php'">next</a>
実行結果のソースは下記の通り。
<!-- 普通の内部リンク ○ -->
<a href="./next.php?PHPSESSID=9d1ed5529291d7f9ce445e62dc85f8e4&foo=bar">next</a>
<!-- 普通の内部POST ○ -->
<form method="POST" action="./next.php"><input type="hidden" name="PHPSESSID" value="9d1ed5529291d7f9ce445e62dc85f8e4" /><input type="hidden" name="foo" value="bar" />
<input type="submit">
</form>
<!-- 外部リンク × -->
<a href="http://www.fork.co.jp/">next</a>
<!-- 外部へPOST ○ -->
<form method="POST" action="http://www.fork.co.jp/"><input type="hidden" name="PHPSESSID" value="9d1ed5529291d7f9ce445e62dc85f8e4" /><input type="hidden" name="foo" value="bar" />
<input type="submit">
</form>
<!-- 内部リンクだけど:(コロン)付き × -->
<a href="./next.php?param:1=1">next</a>
<a href="javascript:location.href='next.php'">next</a>

0 コメント: