2

如果(为了论证)在 php 中授予了“admin-access”:

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

如果您知道会话的名称是什么(在本例中是管理员),这会是一件特别容易绕过和伪造的事情吗?

换句话说,如果所有脚本都要求“设置”会话,那么有人可以轻松伪造 $_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;    
    }
}

如果您不喜欢这种方法,请至少在管理表中存储一个特殊键并使用带有该键值的会话,每次加载页面时还要检查登录是否验证。

于 2012-05-13T07:00:28.863 回答