为了保护我的页面会话,我有以下几页.
我的问题是
谢谢社区.
登录表单loginForm.php
$token = md5(uniqid(rand(),TRUE));
<input name="login" type="text" class="textfield" id="login" />
<input name="password" type="password" class="textfield" id="password" />
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<input type="submit" name="Submit" value="Login" />
Run Code Online (Sandbox Code Playgroud)
当用户登录login.php时
$fingerprint = sha1('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_POST['token']);
session_regenerate_id();
$member = mysql_fetch_assoc($result);
$_SESSION['SESS_MEMBER_ID'] = $member['member_id'];
$_SESSION['SESS_TOKEN'] = $_POST['token'];
$_SESSION['SESS_FINGERPRINT'] = $fingerprint;
session_write_close();
header("location: index.php");
exit();
Run Code Online (Sandbox Code Playgroud)
在每个页面上验证auth.php
session_start();
$fingerprint = sha1('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SESSION['SESS_TOKEN']);
if( !isset($_SESSION['SESS_MEMBER_ID']) || (trim($_SESSION['SESS_MEMBER_ID']) == '') || ($_SESSION['SESS_FINGERPRINT'] != $fingerprint) || !isset($_SESSION['SESS_TOKEN']) || (trim($_SESSION['SESS_TOKEN']) == '') ) {
header("location: denied.php");
exit();
}
Run Code Online (Sandbox Code Playgroud)
回答您最关心的 3 个问题:
我对此反应过度吗?
没有。损坏的会话管理在OWASP 十大漏洞列表中排名第三。您的实施存在一些问题,但总的来说这是一个好主意。
我应该将令牌放在login.php而不是loginForm.php中吗?
有点儿。您应该将令牌生成直接放入会话中。然后,将其插入会话中的表单中。这样您就可以验证表单提交是否与请求表单的会话相同(可以防止某些攻击)。它基本上可以防止 CSRF 攻击。
当用户登录时,我将他的 IP 保存在数据库中。我应该在身份验证中使用它吗?
不会。用户经常会从多台计算机登录。不存在真正可能的 IP->用户映射。IP->会话映射可能效果更好,但不要忘记,动态 IP 地址后面有相当数量的用户,因此即使对于会话来说,它也可能不可靠。
以下是对您的代码本身的一些评论:
代币生成。 现在,您正在使用以下算法:
$token = md5(uniqid(rand(),TRUE));
Run Code Online (Sandbox Code Playgroud)
我个人会将其更改为更加随机和安全的内容。例如:
$token = md5(uniqid(mt_rand() . mt_rand(), true);
Run Code Online (Sandbox Code Playgroud)
或者,如果您安装了 mcrypt,我会这样做:
$token = md5(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
Run Code Online (Sandbox Code Playgroud)
原因是这两个函数都具有更多的熵(意味着它们将生成大量唯一值),并且攻击者更难以猜测它们。
指纹。 现在,你正在做:
$fingerprint = sha1(
'SECRET-SALT' .
$_SERVER['HTTP_USER_AGENT'] .
$_SERVER['REMOTE_ADDR'] .
$_POST['token']
);
Run Code Online (Sandbox Code Playgroud)
这有一些问题。首先,动态IP地址会错误地使会话无效。其次,没有真正的理由对这些数据进行哈希处理。将每个字段保留为单独的字段,然后单独验证它们。它可以帮助防止某种理论上的攻击,即具有不同远程 IP 的用户可以创建伪造的令牌和用户代理,从而产生相同的哈希值(因此能够“破解”指纹)。第三,您使用输入的令牌作为识别数据。这可能会导致会话固定式攻击。
我的建议是将每条信息存储在其自己的会话变量中,并单独验证它们。此外,请使用您在上一个请求中生成的会话令牌,并且仅验证发布的令牌是否与您保存的令牌匹配。
会话验证。那里相当不错。我建议将其移至单独的函数中,以便在需要更改算法时可以轻松修改。这样你就可以调用:
require_once 'session.php';
verifySession();
Run Code Online (Sandbox Code Playgroud)
在每个文件的顶部...
您所拥有的显然是程序性的,并且可以从一些设计和抽象中受益,但在大多数情况下它都非常好(撇开上述评论)。
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |