目录
1 Session 理论基础
1.1 问题背景及session解决方案
- 问题背景
用户访问一个网站时往往需要浏览许多网页。Session的使用在不同的语言中的使用方法特点不尽相同。对于一个通过PHP构筑的网站来说,用户在访问的过程中需要执行许多的PHP脚本。然而由于HTTP协议自身的特点,用户每执行一个PHP脚本都需要和Web服务器重新建立连接。
又由于无状态记忆的特点,此次连接无法得到上次连接的状态。这样,用户在一个PHP脚本中对一个变量进行了赋值操作,而在另外一个PHP脚本中却无法得到这个变量的值。例如,用户在负责登录的PHP脚本中设置了 u s e r = " w i n d " , 却 无 法 在 另 一 个 P H P 脚 本 中 通 过 调 用 user="wind",却无法在另一个PHP脚本中通过调用 user="wind",却无法在另一个PHP脚本中通过调用user来获得“wind”这个值。也就是说,在一次HTTP请求中,PHP无法将已经赋值的参数传递给下一次http请求的脚本。因此,每个PHP脚本中所定义的变量都是只在本次HTTP请求内有效,本次HTTP请求结束,PHP就会释放掉这些为这些变量分配的内存。 - Session解决方案
就是要提供在PHP脚本中定义全局变量的方法,使得这个全局变量在同一个Session中对于所有的PHP脚本都有效。Session不是一个简单的时间概念,一个Session中还包括了特定的用户和服务器。因此更详细地讲,在一个Session定义的全局变量的作用范围,是指这个Session所对应的用户所访问的所有PHP。
1.2 Session理论基础
- Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。
- 作用:当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。
- Session与Cookie:
- session依赖于Cookie实现
- cookie数据保存在客户端(登录后服务器发给客户端一个Cookie,客户端携带cookie访问网页无需登录,注销后本地没有保存cookie。别人如果有截获过之前的cookie则仍能继续使用???)
- Session数据保存在服务端(当登录时产生Session文件记录用户信息,访问时浏览器将cookie发给服务器,验证该cookie对应的session,匹配则无需再登录;在注销时删除Session文件数据,利用cookie再次访问页面则匹配失败需要登录。)
1.3 session的工作原理:
- 当一个session第一次被启用时,一个独一的标识被存储于本地的cookie中。
- 首先使用session_start()函数,PHP从session仓库中加载已经存储的session变量。
- 当执行PHP脚本时,通过使用session_register()函数注册session变量。
- 当PHP脚本执行结束时,未被销毁的session变量会被自动保存在本地一定路径下的session库中,这个路径可以通过php.ini文件中的session.save_path指定,下次浏览网页时可以加载使用。
2 Session应用案例
2.1 实验要求
- 编写网站首页。当客户访问首页时,验证请求的Session信息,如果有则显示“欢迎信息”并显示注销按钮(跳转至注销页面),如果没有则要求登录并显示登录按钮(跳转至登录页面)。
- 编写登录页面。假设已有注册用户libai,密码为123456。登录页面启动Session机制,利用HTML表单收集客户端输入信息,利用PHP语句判断账户密码是否正确,正确则设置Session对象并返回首页,错误则要求继续输入账号密码。
- 编写注销页面。注销后返回首页。
2.2 实验环境
- 服务端:本实验基于虚拟机win2008系统的WAMP环境进行,该环境相关配置过程参考文章《win2008R2SP1+WAMP环境部署》。
- 客户端:浏览器通过IP地址访问所编写网页。
- 服务端与客户端处于同一个局域网下。
2.3 案例代码
index.php 首页代码:
<meta charset="utf-8">
<h1>SESSION学习应用示例</h1>
<?php
session_start();//脚本在该命令前不能有输出语句
if (isset($_SESSION['name']))
{
echo "欢迎测试代码,{$_SESSION['name']}<br>";
echo "<a href='./logout.php'>注销</a>";
}
else
{echo "<a href='./login.php'>请登录</a>";}
?>
login.php 代码:
<html>
<meta charset="utf-8">
<?php
session_start();
if (isset($_GET[ 'userSubmit' ]))
{
if (isset($_GET[ 'userName' ]) && $_GET[ 'userName' ] == "libai"
&& isset($_GET[ 'userPass' ]) && $_GET[ 'userPass' ] == "123456")
{
$_SESSION['name']=$_GET['userName'];
if(isset($_SESSION['name']))
{echo "登录成功,<a href='./index.php'>返回首页</a>";}
else {echo "Session设置失败";}
}
else
{echo "用户名或密码错误,请重新登录</a>";}
}
// else
// {echo "Error!<a href=''>请通过表单登录</a>";}
?>
<h1>用户登录<h1>
<form
action = ""
method = "get"
target = "_blank"
>
用户名:<input type = "text" name = "userName"><br>
密码:<input type = "password" name = "userPass"><br>
<input type="submit" name="userSubmit" value="登录">
</form>
</html>
logout.php 代码:
<meta charset="utf-8">
<?php
session_start();
session_destroy();
echo "注销成功,<a href='./index.php'>返回首页</a>";
?>
2.4 实验测试
- 打开浏览器输入网站IP进行范围。
- 点击“请登录”,跳转至登录页面。
- 输入用户名:libai,密码:123456,点击登录按钮。
- 点击返回首页,可以看到新出现了欢迎字样并有注销功能。
- 点击注销跳转至注销界面。
- 点击返回首页则是初始的首页界面。
3 Session攻防
3.1 会话劫持
3.1.1 含义
会话劫持(Session hijacking),这是一种通过获取用户Session ID后,使用该Session ID登录目标账号的攻击方法,此时攻击者实际上是使用了目标账户的有效Session。会话劫持的第一步是取得一个合法的会话标识来伪装成合法用户,因此需要保证会话标识不被泄漏。
3.1.2 攻击步骤
- 目标用户需要先登录站点;
- 登录成功后,该用户会得到站点提供的一个会话标识SessionID;
- 攻击者通过某种攻击手段捕获Session ID;攻击者获取SessionID的方式有多种:
- 暴力破解:尝试各种Session ID,直到破解为止;
- 预测:如果Session ID使用非随机的方式产生,那么就有可能计算出来;
- 窃取:使用网络嗅探,XSS攻击等方法获得。
- 攻击者通过捕获到的Session ID访问站点即可获得目标用户合法会话。
3.1.3 防御方法
- 更改Session名称。PHP中Session的默认名称是PHPSESSID,此变量会保存在Cookie中,如果攻击者不分析站点,就不能猜到Session名称,阻挡部分攻击。
- 关闭透明化Session ID。透明化Session ID指当浏览器中的Http请求没有使用Cookie来存放Session ID时,Session ID则使用URL来传递。
- 设置HttpOnly。通过设置Cookie的HttpOnly为true,可以防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击。
- 关闭所有phpinfo类dump request信息的页面。
- 验证HTTP头部信息。
- 加入Token校验。同样是用于检测请求的一致性,给攻击者制造一些麻烦,使攻击者即使获取了Session ID,也无法进行破坏,能够减少对系统造成的损失。但Token需要存放在客户端,如果攻击者有办法获取到Session ID,那么也同样可以获取到Token。
3.2 会话固定
3.2.1 含义
- 会话固定(Session fixation)是一种诱骗受害者使用攻击者指定的会话标识(SessionID)的攻击手段。这是攻击者获取合法会话标识的最简单的方法。(让合法用户使用黑客预先设置的sessionID进行登录,从而使Web不再进行生成新的sessionID,从而导致黑客设置的sessionId变成了合法桥梁。)
- 会话固定也可以看成是会话劫持的一种类型,原因是会话固定的攻击的主要目的同样是获得目标用户的合法会话,不过会话固定还可以是强迫受害者使用攻击者设定的一个有效会话,以此来获得用户的敏感信息。
3.2.2 攻击步骤
- 攻击者通过某种手段重置目标用户的SessionID,然后监听用户会话状态;
- 目标用户携带攻击者设定的Session ID登录站点;
- 攻击者通过Session ID获得合法会话。
3.2.3 防御方法
- 每当用户登陆的时候就进行重置sessionID;
- sessionID闲置过久时,进行重置sessionID;
- 大部分防止会话劫持的方法对会话固定攻击同样有效。如设置HttpOnly,关闭透明化Session ID,User-Agent验证,Token校验等。
4 总结
- 了解cookie和session的产生背景;
- 初步理解session与cookie的工作原理;
- 掌握Session机制的应用;
- 了解Session的攻击方式和防御手段。
- 结合视频《Cookie、Session、Token究竟区别在哪?如何进行身份认证,保持用户登录状态?》和文章《Cookie基础知识、应用案例代码及攻防》、《BurpSuite密码爆破(暴力破解DVWA high级别下的用户名及密码——带token验证)》,加深对cookie、Session和token三者的理解。
参考文献
- 《Session攻击(会话劫持+固定)与防御 》后续了解里面代码。
- 《session (计算机术语)》