Security.levelがlowでも慎重を期してセッションIDくらいは新調しとく?

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
あー、これはCakephpのバージョンが1.3の話なんですけど……。

セッションの管理に関して、core.phpでSecurity.levelってのを設定するじゃないですか。するんですよ。

んでまあ、こいつが「high」「medium」「low」の三段階に設定できるんですけど、何となく字面的にhighが良さそうですよね。セキュリティレベル高そうですよね。ALSOK並みにやってくれそうですよね。

僕もよく分かってないんですけど、実はこのhighという設定があまり良くない結果を招くことがあるみたいで、だからみんな、特に1.3を使っている人はSecurity.levelをhighにしたがらないようなんですな。

そうなると、ちょびっと妥協してmediumにするのがよろしいのか。ALSOKはあきらめて、頼れる番犬を飼おうくらいの感じが良いのか。

たぶん良いんだと思いますけど、mediumはmediumで全く問題がないってわけでもないらしい。これまた実はよく分かってないんですけど、highやmediumuはページを移動するたびにリファラのチェクをしているんですね。そのリファラしだいではセッションIDが無効になるっていう処理が実装されている。

つまり、場合によっては切れてほしくないところでいきなりログインが切れちゃうことがあるかもしれないってことですね。

じゃあ仕方ない。自宅警備員くらいの頼りなさだけどlowにするのが良いのか。

ダメではない。自宅警備員だってやるときはやるよ。彼らが普段あまり動かないで部屋にこもっているのは、いざってときのために常にエネルギーを溜めているからなんだよ。

でもまあ、やっぱりlowはlowで問題があって……今日はちょっとその辺を探ってみましょう。



あなたのセッションを守ります!!

僕も最近まで気づいてなかった……というか気にしてなかったんですけど、先日仕事でお客さんからうちのウェブサービスに関して、セキュリティの調査的なことをやられましてね。情報処理推進機構っていうサイトにある「安全なウェブサイトの作り方」っていうPDFと一緒にチェックシート的なものが送られて来ましてね。

「ここに書いてあることを全部守ってんだろーなぁ? セキュリティ対策怠っとったらあかんぞ。ほんまに大丈夫なんやな? 今夜おんどれのサイトにインジェクション攻撃かけたるけぇ、守り抜いてみーや。セキュリティに穴があったらしばくどわれぇ!!」

という脅しの文句は言われませんでしたが、お宅はどれくらいセキュリティ対策しとんのか教えておくんなましってな感じで一通りのセキュリティに関する項目が載ったチェックシートが来ました。分かんないところは同梱したPDFを見て勉強しなよ坊やってな感じで。

んでさっそくPDFを読んでみたんですが、その中に、セッション管理の不備っていう項目がありまして、ログインしたら常に新しいセッションIDを発行するようにしてセキュリティを高めようってなことが書いてあるんですね。ワンタイムパスワードみたいなもんですかね。ログインし直したら前のセッションIDはもう使えないよー、だから君が前に盗んだそれはもう意味がないよーってな具合ですかね。

さあ、そこでCakephpのSecurity.levelがlowだった場合だ。

lowにしておくと、このセッションIDが新しく発行されないんですね。ログインしてもページを移動しても、前のセッションIDのまんまっぽい。一回ログアウトしてもっかいログインしても変わらない。mediumでもそうみたいなんだけど。

highのときはリクエストごとにセッションIDを書き換えてます。つまりページを移動するたびにセッションIDが新しくなるから、まさにワンタイムパスワードのごとく、その点のセキュリティ度は高いと言えますね。でもhighはあまり使い勝手が良くないらしいって話は前述の通りでして……あっちを立てればこっちが立たず。ヒソカがイルミ兄に助けを求めたくなる気持ちも分かるいややっぱり分からない。

じゃあそこでどうしようかってことなんですけど、とりあえずSecurity.levelはlowのままで行くとして、その代わりに、せめてログインしたときくらい新しいセッションIDを発行してくれるようにしてみようじゃないかってことで、我が家の自宅警備員に打診してみました。

実は僕も仕事で運用してるサイト、Security.levelがlowなんだよね……その前にCakephpのバージョン上げろっつー話なんだけどww



オッス! オラAuth

やり方は簡単。Authコンポーネントの中身をちょちょいと書き換えるだけ。

まずはappフォルダの方にauth.phpを持って来よう。そしたらidentify()っていうファンクションがあるはずだから、そこの最後の方を書き換える。

//auth.php(変更前)
function identify($user = null, $conditions = null) {

  ~中略~

  if (!empty($data)) {
    if (!empty($data[$model->alias][$this->fields['password']])) {
      unset($data[$model->alias][$this->fields['password']]);
    }

    return $data[$model->alias];
  }
  return null;
}

//auth.php(変更後)
function identify($user = null, $conditions = null) {

  ~中略~

  if (!empty($data)) {
    if (!empty($data[$model->alias][$this->fields['password']])) {
      unset($data[$model->alias][$this->fields['password']]);
    }

    //ここでセッションIDを新しいものに書き換えてみる
    if(Configure::read('Security.level') == 'low') {
      $this->Session->renew();
    }

    return $data[$model->alias];
  }
  return null;
}

とりあえずこんな感じにしてみたんだけどどうだろう? mediumのときもやりたいなら『Configure::read(‘Security.level’) != ‘high’』とかにすれば良いね。もしあれならログアウト時も書き換えた方が良いのかしら?

Cakephp2.0だとこんなことしなくても良いんですけどね。やってみた感じ、2.0の場合はmediumだろうがlowだろうがログインすると新しいセッションIDになってました。

若干めんどいけど、コアライブラリにあるcake_session.phpとかの中身を見てみると、セッションID発行に関する処理とかが載ってるっぽいです。ただし1.3と2.0でこのファイルを置いてある場所が違うから注意ね。俺も2.0の方でCakeSession.phpがなかなか見つけられなくて困ったよ。あんなとこにあるんだもん。

//1.3の場合
/cake/libs/cake_session.php

//2.0の場合
/Cake/Model/Datasource/CakeSession.php

何で2.0の方はモデルの下にあるんだろうね……?





もしかしたら「え~今さら~?」的なことなのかもしれないけど、ようは今まであまりセキュリティを意識しなかった人は、今までより少しだけ気にしてみましょうってことですよ。僕とか、僕とか、僕とかね。

上記にある情報何ちゃらってところのPDFは、説明も丁寧だし、個人的には分かりやすかったです。読んだことない方は、一度読んでみると良いと思います。いろいろ勉強になるですよ。
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください