PHP 表单令牌的使用和处理

2022-08-30 23:08:49

我是一个在PHP中处理登录脚本的初学者。这是我到目前为止拥有的表单令牌语句:

$_SESSION["form_token"] = md5(rand(time (), true)) ;

该语句是在用户指示他/她想要登录后立即发出的。

我的有限理解是,令牌的目的是在唯一时间点标识唯一用户并伪装令牌信息形式。

然后一切都变得模糊。以下是我的3个开放问题:

  1. 出于安全目的,何时是“检查”表单令牌的最佳时间?

  2. 我该如何检查它?

  3. 我什么时候(如果有的话)“销毁”表单令牌?(IOW,表单令牌在用户注销之前是否会保持“活动”状态?


答案 1

这是为了防止CSRF攻击

http://en.wikipedia.org/wiki/Cross-site_request_forgery

从理论上讲,恶意站点可能会显示发布到应用程序的表单。表单可能包含导致数据泄露或某些不需要的操作的说明。用户可能会被欺骗而提交应用程序会接受的表单,因为用户已经登录。表单令牌可确保表单是由您的网站而不是其他网站创建的。

检查HTTP_REFERER通常足够好,但不是完整的解决方案(例如,https不会发送引荐来源网址字符串)。

如果你真的想用一个令牌来保护所有表单,你可以创建一些方便的函数,如emitToken()和checkToken(),这将使它在站点范围内工作。

一些例子:

http://phpsec.org/projects/guide/2.html

http://www.rodsdot.com/php/CSRF_Form_Protection.php


答案 2

没有必要做你正在尝试的事情。当您使用session_start()在 PHP 中启动会话时,已经为您生成了唯一的 SESSIONID。你不应该把它放在表格上。默认情况下,它通过 Cookie 进行处理。也无需检查会话ID,这再次为您处理。

您负责对用户进行身份验证并存储其经过身份验证的身份(例如,$_SESSION['user_id'] = 会话中的$userId。如果用户注销,则使用session_destroy销毁其会话。

您应该确保session_start()是您网站中所有页面的首要任务之一。

下面是一个基本示例:

<?php
session_start(); // starts new or resumes existing session
session_regenerate_id(true); // regenerates SESSIONID to prevent hijacking

function login($username, $password)
{
    $user = new User();
    if ($user->login($username, $password)) {
        $_SESSION['user_id'] = $user->getId();
        return true;
    }
    return false;
}

function logout()
{
    session_destroy();
}

function isLoggedIn()
{
    return isset($_SESSION['user_id']);
}

function generateFormHash($salt)
{
    $hash = md5(mt_rand(1,1000000) . $salt);
    $_SESSION['csrf_hash'] = $hash
    return $hash;
}

function isValidFormHash($hash)
{
    return $_SESSION['csrf_hash'] === $hash;
}

编辑:我误解了原来的问题。我添加了上面用于生成和验证表单哈希的相关方法;

请参阅以下资源:


推荐