目前,当用户登录时,我创建了2个会话.
$_SESSION['logged_in'] = 1; $_SESSION['username'] = $username; // user's name
那么,那些需要登录的页面,我只是这样做:
if(isset($_SESSION['logged_id'])){ // Do whatever I want }
有没有安全漏洞?我的意思是,攻击我的会话容易吗?人们如何破解会话?以及如何防止它?
编辑:
刚发现这个:
http://www.xrvel.com/post/353/programming/make-a-secure-session-login-script
http://net.tutsplus.com/tutorials/php/secure-your-forms-with-form-keys/
刚发现链接,这些方法是否足够好?请提出你的意见.我还没有得到最好的答案.
用户:访客.
客户端:安装在特定计算机上的特定Web功能的软件.
为了了解如何确保会话安全,您必须首先了解会话的工作方式.
让我们看看这段代码:
session_start();
一旦你调用它,PHP就会寻找一个名为PHPSESSID
(默认情况下)的cookie .如果找不到,它将创建一个:
PHPSESSID=h8p6eoh3djplmnum2f696e4vq3
如果找到,则取值,PHPSESSID
然后加载相应的会话.该值称为a session_id
.
这是客户唯一知道的事情.无论您添加到会话变量中的是什么,都会保留在服务器上,并且永远不会转移到客户端.如果更改内容,该变量不会更改$_SESSION
.它会一直保持不变,直到你摧毁它或它超时.因此,$_SESSION
当客户端从未接收或发送该信息时,试图通过散列或其他方式来混淆内容是没有用的.
然后,在新会话的情况下,您将设置变量:
$_SESSION['user'] = 'someuser';
客户永远不会看到这些信息.
当恶意用户窃取session_id
其他用户时,可能会出现安全问题.如果没有某种检查,他就可以自由地冒充该用户.我们需要找到一种方法来唯一地识别客户端(而不是用户).
一种策略(最有效)涉及检查启动会话的客户端的IP是否与使用会话的人员的IP相同.
if(logging_in()) { $_SESSION['user'] = 'someuser'; $_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; } // The Check on subsequent load if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) { die('Session MAY have been hijacked'); }
该策略的问题在于,如果客户端使用负载均衡器,或者(在长持续时间会话中)用户具有动态IP,则会触发错误警报.
另一个策略涉及检查客户端的用户代理:
if(logging_in()) { $_SESSION['user'] = 'someuser'; $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT']; } // The Check on subsequent load if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) { die('Session MAY have been hijacked'); }
该策略的缺点是,如果客户端升级它的浏览器或安装一个插件(一些添加到用户代理),用户代理字符串将更改,它将触发虚假警报.
另一个策略是旋转session_id
每5个请求.这样,从session_id
理论上讲,它不会长时间被劫持.
if(logging_in()) { $_SESSION['user'] = 'someuser'; $_SESSION['count'] = 5; } // The Check on subsequent load if(($_SESSION['count'] -= 1) == 0) { session_regenerate_id(); $_SESSION['count'] = 5; }
您可以根据需要组合这些策略中的每一个,但您也会将缺点结合起来.
不幸的是,没有任何解决方案是万无一失的.如果您session_id
受到了损害,那么您已经完成了很多工作.上述策略只是权宜之计.
这是荒唐的.
会话劫持发生在(通常通过跨站点脚本攻击)某人拦截您的sessionId(这是一个由浏览器自动发送到Web服务器的cookie)时.
有人发布了这个例子:
所以当用户登录时:
//不是最安全的哈希!$ _SESSION ['checksum'] = md5($ _ SESSION ['username'].$ salt);
在进入敏感区域之前:
if(md5($ _ SESSION ['username'].$ salt)!= $ _SESSION ['checksum']){
handleSessionError(); }
让我们来解决这个问题
盐 - 没错,但没有意义.没有人会破坏你该死的md5,谁在乎它是否被盐腌
将SESSION变量的md5与存储在SESSION中的同一变量的md5进行比较 - 您将会话与会话进行比较.如果东西被劫持,这将无济于事.
$_SESSION['logged_in'] = 1; $_SESSION['username'] = $username; // user's name $_SESSION['hash'] = md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT']);//用户名称哈希以避免操纵
避免被谁操纵?神奇的会议精灵?除非服务器受到损害,否则不会修改会话变量.哈希只是将你的字符串很好地压缩成一个48个字符的字符串(用户代理可以有点长).
至少我们现在检查一些客户端数据而不是检查SESSION到SESSION数据,他们检查了HTTP_USER_AGENT(这是一个识别浏览器的字符串),这可能足以保护你但你必须意识到如果这个人已经在某个时候已经开始使用你的sessionId,你很可能也会向坏人服务器发送一个请求并给你的用户代理坏人,所以一个聪明的黑客会欺骗你的用户代理并破坏这种保护.
你是谁得到了可悲的事实.
一旦您的会话ID被泄露,您就会离开.您可以检查请求的远程地址,并确保在所有请求中保持相同(正如我所做的那样),这对于99%的客户群来说都是完美的.然后有一天你会接到一个使用带有负载平衡代理服务器的网络的用户的电话,请求将通过一组不同的IP(有时甚至在错误的网络上)从这里发出,他将会失去他的会话左右中心.