konekto Inc with PHP , MySQL コネクト株式会社 技術情報コンテンツ


セキュリティ指針

セッションを使おう

説明

たとえば、10万人のユーザを抱えているサイトでユーザ認証を省くために、次のようなコードを書いているサイトはあるとする。

<?php
    $username = $_POST['username'];
    $password = $_POST['password'];
    //ユーザ認証
    if ($_COOKIE['auth'] === true && auth_user($username, $password)){
        $_COOKIE['auth'] = true;
        echo '認証成功';
    }else{
        echo '認証失敗';
    }
?>

たとえば、毎回のユーザ認証を省くために、次のようなコードを書いていることはあるとする。

<?php
    if (isset($_COOKIE['username']) && isset($_COOKIE['password'])) {
        $username = $_COOKIE['username'];
        $password = $_COOKIE['password'];
    }else{
        $username = $_POST['username'];
        $password = $_POST['password'];
    }
    //ユーザ認証
    if (auth_user($username, $password)){
        $_COOKIE['user'] = $username;
        $_COOKIE['password'] = $password;
        echo '認証成功';
    }else{
        echo '認証失敗';
    }
?>

上記2つは、それぞれセキュリティに問題を抱えている。 1つ目は、ユーザが手動でCOOKIEの値のauthにTrueを入れた場合に、パスワード認証を回避できてしまう。 2つ目は、$_COOKIEの値がクロスサイトスクリプティングなどで漏洩した場合には、パスワードとユーザ名がそのまま露呈してしまう。 これらの対策をとるにはセッションが有効である。 セッションは、サーバ側にデータを保持しセッションIDと呼ばれる文字列をクライアントを識別するのに使用する。セッションIDは信頼できる値ではないが、セッションデータはサーバ側に保持されているため改ざんの心配はないと考えることができる。*1

コーディング

上記コードはセッションで次のように記述することができる。

<?php
    $username = $_POST['username'];
    $password = $_POST['password'];
    
    //ユーザ認証
    if (($_SESSION['auth']) === true && auth_user($username, $password)){
        $_SESSION['auth'] = true;
        echo '認証成功';
    }else{
        echo '認証失敗';
    }
?>

ただし、別のアカウントからパスワード等変更した場合は、セッション終了までこのアカウントが有効になってしまうことに注意。

注意点

セッション漏洩には細心の注意を払う必要がある、たとえば、GETの引数にセッション情報を埋め込んだ場合には、プロキシやリファラ情報で、外部にセッション情報が洩れてしまう可能性がある。
また、セッションの有効期限は可能な限り短くしておく必要がある。そうしておくことで、仮にセッションハイジャックが発生したとしても、被害を最小限に抑えることができるからだ。
セッションの漏洩は、ユーザ名、パスワードの漏洩と同程度の危険がある。最大限注意を払うこと。
また、セッションIDとなるキーワードは必ず、意味をなさない文字列とすることが重要である。なぜなら、意味をなす文字列であるとそこからセッションIDが類推されセッションハイジャックが発生する可能性があるからである。


*1 不特定のユーザそれぞれのアクセスできる場合セッションのアクセス権に注意する必要はある。

最終更新のRSS