PHP安全:session劫持的防御

点击蓝色小字关注

session 数据暴露

会话数据常会包含一些个人信息和其它敏感数据。基于这个原因,会话数据的暴露是被普遍关心的问题。一般来说,暴露的范围不会很大,因为会话数据是保存在服务器环境中的,而不是在数据库或文件系统中。因此,会话数据自然不会公开暴露。

使用SSL是一种特别有效的手段,它可以使数据在服务器和客户端之间传送时暴露的可能性降到最低。这对于传送敏感数据的应用来说非常重要。SSL在HTTP之上提供了一个保护层,以使所有在HTTP请求和应答中的数据都得到了保护。

如果你关心的是会话数据保存区本身的安全,你可以对会话数据进行加密,这样没有正确的密钥就无法读取它的内容。这在PHP中非常容易做到,你只要使用session_set_save_handler( )并写上你自己的session加密存储和解密读取的处理函数即可。

session 劫持

最常见的针对会话的攻击手段是会话劫持。它是所有攻击者可以用来访问其它人的会话的手段的总称。所有这些手段的第一步都是取得一个合法的会话标识来伪装成合法用户,因此保证会话标识不被泄露非常重要。前面关于会话暴露和固定的知识能帮助你保证会话标识只有服务器及合法用户才能知道。

深度防范原则可以用在会话上,当会话标识不幸被攻击者知道的情况下,一些不起眼的安全措施也会提供一些保护。作为一个关心安全的开发者,你的目标应该是使前述的伪装过程变得更复杂。记住无论多小的障碍,都会以你的应用提供保护。

把伪装过程变得更复杂的关键是加强验证。会话标识是验证的首要方法,同时你可以用其它数据来补充它。你可以用的所有数据只是在每个HTTP请求中的数据:

GET / HTTP/1.1
Host: example.org
User-Agent: Firefox/1.0
Accept: text/html, image/png, image/jpeg, image/gif, */*
Cookie: PHPSESSID=1234

http://www.nowamagic.net/librarys/veda/detail/2041

<?php
session_start();

if (isset($_SESSION['HTTP_USER_AGENT']))
{
	if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
	{
  		/* Prompt for password */
  		exit;
	}
}
else
{
	$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
 
?>

我观察过,在某些版本的IE浏览器中,用户正常访问一个网页和刷新一个网页时发出的Accept头部信息不同,因此Accept头部不能用来判断一致性。

确保User-Agent头部信息一致的确是有效的,但如果会话标识通过cookie传递(推荐方式),有道理认为,如果攻击者能取得会话标识,他同时也能取得其它HTTP头部。由于cookie暴露与浏览器漏洞或跨站脚本漏洞相关,受害者需要访问攻击者的网站并暴露所有头部信息。所有攻击者要做的只是重建头部以防止任何对头部信息一致性的检查。

比较好的方法是产生在URL中传递一个标记,可以认为这是第二种验证的形式(虽然更弱)。使用这个方法需要进行一些编程工作,PHP中没有相应的功能。例如,假设标记保存在$token中,你需要把它包含在所有你的应用的内部链接中:

<?php

$url = array();
$html = array();

$url['token'] = rawurlencode($token);
$html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8');

?>
 
<a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>

为了更方便地管理这个传递过程,你可能会把整个请求串放在一个变量中。你可以把这个变量附加到所有链接后面,这样即便你一开始没有使用该技巧,今后还是可以很方便地对你的代码作出变化。

该标记需要包含不可预测的内容,即便是在攻击者知道了受害者浏览器发出的HTTP头部的全部信息也不行。一种方法是生成一个随机串作为标记:

<?php

$string = $_SERVER['HTTP_USER_AGENT'];
$string .= 'SHIFLETT';

$token = md5($string);
$_SESSION['token'] = $token;

?>

当你使用随机串时(如SHIFLETT),对它进行预测是不现实的。此时,捕获标记将比预测标记更为方便,通过在URL中传递标记和在cookie中传递会话标识,攻击时需要同时抓取它们二者。这样除非攻击者能够察看受害者发往你的应用所有的HTTP请求原始信息才可以,因为在这种情况下所有内容都暴露了。这种攻击方式实现起来非常困难(所以很罕见),要防止它需要使用SSL。

有专家警告不要依赖于检查User-Agent的一致性。这是因为服务器群集中的HTTP代理服务器会对User-Agent进行编辑,而本群集中的多个代理服务器在编辑该值时可能会不一致。如果你不希望依赖于检查User-Agent的一致性。你可以生成一个随机的标记:

<?php

$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;

?>

这一方法的安全性虽然是弱一些,但它更可靠。上面的两个方法都对防止会话劫持提供了强有力的手段。你需要做的是在安全性和可靠性之间作出平衡。

原文发布于微信公众号 - php(phpdaily)

原文发表时间:2015-07-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端架构与工程

Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案

文件的hash指纹通常作为前端静态资源实现增量更新的方案之一,Webpack是目前最流行的开源编译工具之一,其强大的功能也带来很多坑(当然,大部分麻烦其实都可以...

3267
来自专栏烙馅饼喽的技术分享

我的CMS开发记-4 介绍一下DotNetNuke的系统执行流程

       有朋友说应该写个大致结构出来。想想也有道理,那么我就来介绍一下Dotnetnuke的执行流程。基本上我这个就是照搬他的 基本思路     一个站点...

2618
来自专栏重庆的技术分享区

TensorFlow版本-如何更新?(踩坑版)

8194
来自专栏FreeBuf

图解Meterpreter实现网络穿透的方法

纵向防御也被被称为为“多层防御”,这样的概念被运用于“信息安全”上。以多层电脑安全技术去减轻其风险,在其中有些电脑被入侵或是泄密时,风险可大大降低。 举例说明,...

1876
来自专栏月色的自留地

在龙芯小本上安装Debain8.10

1596
来自专栏醉程序

造了个轮子 XML 2 JSON

641
来自专栏企鹅号快讯

Spring boot+LayIM+t-io 好友申请通知的实现

摘要: 本文包含内容:用户主页面信息加载,绑定。好友申请,t-io服务端主动推送,layim消息盒子的数据绑定。 前言 在上一篇Spring boot + La...

1910
来自专栏24K纯开源

给你的博客加上“Fork me on Github”彩带

起         如今,随着Git的大热以及Github的优越性,许多知名开源项目都将源代码托管到Github上了。在Github上不仅可以托管自己的开源项目...

18210
来自专栏深度学习那些事儿

深度学习-在ubuntu16.04安装CUDA9.1-总结(问题完全解决方案)

深度学习大火,为了赶上AI的班车,许多研究生本科生们都在搞深度学习。然而深度学习环境搭建必不可少,这篇文章是我多次为实验室搭建环境所积累起来的经验总结,希望所有...

4855
来自专栏Laoqi's Linux运维专列

Linux防火墙-netfilter应用

iptables filter表小案例 : nat表应用 A机器两块网卡ens33(192.168.133.130)、ens37(192.168.100.1),...

3026

扫描关注云+社区