ikepyonのだめ人間日記

セキュリティに関することを書いていく予定。

携帯電話の個体識別番号をセッションIDとして使う方法

ワッサーでつぶやいていて、PHPで個体識別番号をセッションIDとして使う方法を教えてもらった。http://wassr.jp/user/nihen/statuses/skctoRFZ3G
目からうろこが落ちた。

<?php

session_id(get_mobile_id());
session_start();

if (!isset($_SESSION['count'])) {
    $_SESSION['count'] = 0;
} else {
    $_SESSION['count']++;
}
echo $_SESSION['count'];
?>

http://pastebin.com/m74eb934f
ここで、get_mobile_id()で個体識別番号を取得するらしい。
で、それをセッションIDとして、session_idで認識させる。すると、CookieやHiddenを使えなくてもOK

自分が詰まっていた所を書いておこう。
session_id()でセッションIDを設定すると、Cookieやパラメータの値にセットされる様になるだけだと思っていた(ようするにPHPSESSIDが設定した値になるだけ)。Cookieやパラメータに設定されたセッションIDとPHP内部のセッション情報を結びつける必要があるってのをすっかり失念していた。sessiion_id()によって、PHP内部のセッション情報が書き換わるので、これがうまくいくんだと言う理解でよいのかな?

いろいろ指摘頂きid:nihenさんありがとうございました。

ちなみにキャリアのIPアドレスからのみアクセスした場合だけヘッダーやUser-Agentで個体識別番号が渡されることが前提となる。キャリアのIPアドレス以外から個体識別番号が渡された場合、エラーとするか、渡された個体識別番号を無視して、別途ランダムなセッションIDを付与するようにしないと、セッションフィクサーションの脆弱性があるので注意。

なお、これがキャリアのIPアドレスからのリクエストのみ安全というのは、携帯電話では個体識別番号が改ざんできないという前提に立っている。これが出来る場合、安全ではない。
ちなみに、CSRF対策としてセッションIDをhiddenに埋め込むという対策は意味がないので気を付けること。別途セッション変数にランダムな値を格納し、その値をhiddenに埋め込み、渡された値とセッション変数を比較することで、対策すること。当然のことながら、処理が行われたら、セッション変数の方は破棄しないと。

あ、後、ログインしているか、ログアウトしたかは別途セッション変数で管理する必要があるかな?

(追記)
確証は取れていないが、こういう話もあるらしいので、実際この手法を実装するのは危険かもしれない。
http://bakera.jp/ebi/topic/3874/comment