Php 会话劫持的对抗方法
很明显,我们大多数PHP程序员都不希望我们发表的作品被黑客攻击或以我们不希望的方式被利用。因此,在询问如何应对会话劫持时,我会格外小心。我知道session_regenate_id()函数可以部分阻止会话劫持,但我更好奇的是我遇到的另一种方法: 当用户登录到网站时,您将其用户id(或另一个更秘密的预定义加密字符串)(普通用户不知道)作为字符串,并使用随机预定义符号对其进行加密,md5()将该字符串设置为$_会话['user_code']=$该字符串;每当这个用户进入一个页面时,你都要重复这个过程,如果不匹配,就将它与$u SESSION['user\u code']匹配;销毁会话 所以在代码中,它看起来像这样(例如): 然后在每个可用页面的开头检查这是否正确:Php 会话劫持的对抗方法,php,security,session,session-hijacking,Php,Security,Session,Session Hijacking,很明显,我们大多数PHP程序员都不希望我们发表的作品被黑客攻击或以我们不希望的方式被利用。因此,在询问如何应对会话劫持时,我会格外小心。我知道session_regenate_id()函数可以部分阻止会话劫持,但我更好奇的是我遇到的另一种方法: 当用户登录到网站时,您将其用户id(或另一个更秘密的预定义加密字符串)(普通用户不知道)作为字符串,并使用随机预定义符号对其进行加密,md5()将该字符串设置为$_会话['user_code']=$该字符串;每当这个用户进入一个页面时,你都要重复这个过程
//fetch user credentials from db again
//$row4 is the user_id
if($_SESSION['user_code'] != md5($salt1 . $row[4] . $salt2){
session_destroy();
}
我不认为使用用户id作为加密的一部分是最佳的,但这只是一个例子。我最好使用创建用户时的时间戳的md5字符串。但如果我不清楚,我的主要问题是,这种方法对会话劫持是否有效,为什么/为什么不?始终检查任何表单是否存在跨站点伪造令牌,例如,在登录时创建令牌:
Session:set('token', md5(uniqid());
然后在每个表单上放置一个带有所述令牌的隐藏表单输入
<input type="hidden" name="crsf" value="<?php echo System::escape(Session::get('token'));">
无论提交是否成功,请确保在每个表单上重新生成一个新令牌
我很抱歉为此使用了方法,但您已经了解了如何处理表单的要点。请引用您的来源
您在这里描述的内容对会话劫持没有任何影响。无论使用多少会话值、多少盐和多少轮加密,结果都将始终匹配。如果会话被破坏,您不能依靠它来验证会话。session_regenate_id()函数确实增加了一点价值,但只减少了利用现有漏洞的窗口。花时间防止会话泄露-使用https、HST、仅http+安全cookie标志、严格的CSP、过期时的会话销毁
如果您确实觉得需要进一步增强安全性,那么可以在正常的交换中使用令牌,例如使用本地存储或设备指纹的质询响应。您不需要一个具有多个端口的奇特方案 此外,如果我可以窃取用户的会话cookie,那么您的方案将根本无法工作
Alien13没有询问CSRF,如果用户打开第二个窗口,您所描述的内容就会中断。我对会话劫持不太熟悉,这可能是一个奇怪的问题,但这种方法可能有效,因为$user_代码仅在成功的合法登录时生成并存储为会话值($user_代码与数据库中存储的数据一起生成,该数据库仅在合法登录时获取)。外部会话劫持者永远无法猜出秘密字符串(对所有用户来说都是唯一的)从数据库中获取,因此具有无效/空的$user\u代码并销毁会话?这两个事实仍然保留在服务器端并链接到会话。即使仅在合法、成功登录后才生成并链接到会话,这是否仍然适用?
<input type="hidden" name="crsf" value="<?php echo System::escape(Session::get('token'));">
if(Request::post('crsf') == Session::get('token'):
//do what you gotta do