2

(引数のために)'admin-access'がphpで許可された場合:

if (isset($_SESSION['admin']))  // this session would be set
{ // grant access; }            // after a successful login
else { //redirect ;}

セッションの名前(この場合はadmin)がわかっている場合、これはバイパスして偽造するのが特に簡単なことでしょうか?

言い換えると、すべてのスクリプトが要求するすべてのセッションが「設定」されている場合、誰かが$ _SESSIONを簡単に偽造できますか?

4

2 に答える 2

3

使用するisset()ことはセキュリティにとって悪いことではありません。それをどのように使用するかは、ロジックによって異なります。isset()チェックするだけでなく、その価値もチェックしておくといいでしょう。

例えば:

if( isset($_SESSION['admin']) && $_SESSION['admin'] == true ) { 
  // grant access
} else { 
  //redirect 
}

またはこのようなもの:

if( isset($_SESSION['admin']) && $_SESSION['admin'] == '1' ) { 
  // grant access
} else { 
  //redirect 
}
于 2012-05-13T06:54:25.403 に答える
0

以前のアプリケーションで使用したこのクラスのように、より安全な方法を好みます。

class auth {

    protected $userID;
    protected $password;
    protected $username;
    protected $remember;
    protected $userType;

    public function checkAuth($username,$password,$remember=0) {
        global $db;

        $this->password = sha1($password);
        $this->username = strtolower($username);
        $this->remember = $remember;

        $sth = $db->prepare("SELECT `id`,`username`,`password`,`type` FROM `user` WHERE `username` = :username AND `active` = '1' LIMIT 1");
        $sth->execute(array(
            ':username' => $this->username
        ));
        $result = $sth->fetchAll();
        $this->userType = $result[0]['type'];

        if (@$result[0]['password'] == $this->password) {
            $this->userID = $result[0]['id'];
            $this->makeLogin();
            return true;
        } else {
            return false;
            exit;
        }
    }

    private function makeLogin() {
        $securityInformation = $this->username . '|-|' . $this->password . '|-|' . $this->userID . '|-|' . $this->userType;
        $hash = $this->encode($securityInformation);
        if ($this->remember) {
            setcookie('qdata',$hash,time()+604800,'/');
        } else {
            $_SESSION['qdata'] = $hash;
        }
        $this->updateStats();
    }

    public function isLogin() {
        global $db, $ua, $cache;

        $data = $this->getUserInfo();
        if ($data) {

            $sth = $db->prepare('SELECT `password`,`last_login_ip` FROM `user` WHERE `id` = :ID LIMIT 1');
            $sth->execute(array(
                ':ID' => $data['userID']
            ));

            $result = $sth->fetchAll();
            if ( ($result[0]['password'] == $data['password']) AND ($result[0]['last_login_ip'] == $ua->getIP()) ) {
                return true;
            } else {
                return false;
            }

        }
    }

    public function logout() {
        if (@isset($_COOKIE['qdata'])) {
            setcookie('qdata','',time()-200, '/');
        } 
        if (@isset($_SESSION['qdata'])) {
            unset($_SESSION['qdata']);
        }
    }

    private function parseHash($hash) {
        $userData = array();
        list($userData['username'],$userData['password'],$userData['userID'],$userData['userType']) = explode('|-|',$this->decode($hash));
        return $userData;
    }

    public function getUserInfo() {
        if (@isset($_COOKIE['qdata'])) {
            $data = $this->parseHash($_COOKIE['qdata']);
            return $data; 
        } elseif (@isset($_SESSION['qdata'])) {
            $data = $this->parseHash($_SESSION['qdata']);
            return $data;
        } else {
            return false;
        }
    }

    private function encode($str) {
        $chr = '';
        $prt = '';
        for($i=0;$i < strlen($str);$i++) {
            $prt = (chr(ord(substr($str,$i,1)) + 3)) . chr(ord(substr($str,$i,1)) + 2);
            $chr =  $prt . $chr;
        }
        return str_rot13($chr);
    }

    private function decode($str) {
        $chr = '';
        $prt = '';
        $str = str_rot13($str);
        for($i=0;$i < strlen($str);$i++) {
            if($i % 2 == 0) {
                $prt = (chr(ord(substr($str,$i,1)) - 3));
                $chr = $prt . $chr;
            }
        }
        return $chr;    
    }
}

このアプローチが気に入らない場合は、少なくともadminテーブルに特別なキーを保存し、そのキーを値として使用してセッションを使用します。また、ページが読み込まれるたびにログインが検証されることを確認します。

于 2012-05-13T07:00:28.863 に答える