Работа с сессиями и куки в PHP - PullRequest
1 голос
/ 18 января 2012

Во время входа в систему я использую следующую функцию для установки файлов cookie и сеанса

protected function validateUser($userid, $ckey=0, $rememmber=0) {
    session_start();
    session_regenerate_id(true); //this is a security measure
    $_SESSION['user_id'] = $userid;
    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
    if (isset($remember) && $rememmber == 'on') {
        setcookie("user_id", $_SESSION['user_id'], time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/");
        setcookie("user_key", sha1($ckey), time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/");
    }
    return true;
}

Затем на защищенных пользовательских страницах, проверяя наличие user_id, используя user_id для получения всех важных данных о пользователе из db

public function protect() {
        session_start();

        /* Secure against Session Hijacking by checking user agent */
        if (isset($_SESSION['HTTP_USER_AGENT'])) {
            if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) {
                $this->signout();
                exit;
            }
        }

// before we allow sessions, we need to check authentication key - ckey and ctime stored in database

        /* If session not set, check for cookies set by Remember me */
        if (!isset($_SESSION['user_id'])) {
            if (isset($_COOKIE['user_id']) && isset($_COOKIE['user_key'])) {
                /* we double check cookie expiry time against stored in database */

                $cookie_user_id = $_COOKIE['user_id'];
                               $stmt = $this->db->prepare("select `ckey`,`ctime` from `users` where `id` =?") or die($this->db->error);
            $stmt->bind_param("i", $cookie_user_id) or die(htmlspecialchars($stmt->error));
            $stmt->execute() or die(htmlspecialchars($stmt->error));
            $stmt->bind_result($ckey, $ctime) or die($stmt->error);
            $stmt->close() or die(htmlspecialchars($stmt->error));
                // coookie expiry
                if ((time() - $ctime) > 60 * 60 * 24 * COOKIE_TIME_OUT) {
                    $this->signout();
                }
                /* Security check with untrusted cookies - dont trust value stored in cookie.       
                  /* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login */

                if (!empty($ckey) && is_numeric($_COOKIE['user_id']) && $_COOKIE['key'] == sha1($ckey)) {
                    session_regenerate_id(); //against session fixation attacks.

                    $_SESSION['user_id'] = $_COOKIE['user_id'];
                    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
                } else {
                    $this->signout();
                }
            } else {
                if ($page != 'main') {
                    header('Location:' . wsurl);
                    exit();
                }
            }
        }
    }

Интересно, достаточно ли этого для хранения только user_id и user_agent в кокках и сеансах в целях безопасности? Если нет, то что еще?

Ответы [ 2 ]

4 голосов
/ 18 января 2012
$rs_ctime = $this->db->query("select `ckey`,`ctime` from `users` where `id` = -> '$cookie_user_id'<-")

Похоже, здесь SQL-инъекция. Если вы передаете переменную из GET, POST, COOKIE напрямую в sql-запрос, это признак внедрения.

Обычно достаточно хранить user_id и user_agent. Но некоторые платежные сервисы иногда используют проверку по телефону, отправляя смс с некоторым кодом и проверяя его. Но это обычно для очень безопасных услуг

3 голосов
/ 18 января 2012

Сеансы хранятся на сервере, и вы уже выполняете свою часть, регенерируя ключ сеанса сразу после входа в систему, в соответствии с Предотвращением взлома сеансов в Википедии , так что я бы сказал, что вы просто храните пользовательский агент и идентификатор пользователя. Однако я не буду восстанавливать идентификатор сеанса после каждого безопасного просмотра страницы (например, удалять session_regenerate_id() из функции validateUser()). Википедия рекомендует делать это только один раз при входе в систему ... что-то большее, чем-то вроде неконтролируемого. Я также переместил бы session_start() из функций, хотя и на вершину хорошего места в вашем коде.

Удачи в кодировании!

...