具体而言,这与使用客户端会话cookie来识别服务器上的会话有关.
对整个网站使用SSL/HTTPS加密是最好的答案,并且您可以最好地保证中间人攻击中没有人能够嗅探现有的客户端会话cookie吗?
也许第二最好对存储在会话cookie中的会话值本身使用某种加密?
如果恶意用户具有对计算机的物理访问权限,他们仍然可以查看文件系统以检索有效的会话cookie并使用它来劫持会话?
加密会话值将不会产生任何影响.会话cookie已经是一个任意值,加密它只会生成另一个可以被嗅探的任意值.
唯一真正的解决方案是HTTPS.如果您不想在整个站点上执行SSL(可能存在性能问题),那么您可能只能使用SSL来保护敏感区域.为此,请首先确保您的登录页面是HTTPS.当用户登录时,除常规会话cookie外,还设置安全cookie(意味着浏览器仅通过SSL链接传输).然后,当用户访问您的某个"敏感"区域时,将其重定向到HTTPS,并检查是否存在该安全Cookie.真正的用户会拥有它,会话劫持者不会.
编辑:这个答案最初写于2008年.现在是2016年,并没有理由不在整个网站上使用SSL.没有更多的纯文本HTTP!
SSL仅对嗅探攻击有帮助.如果攻击者可以访问您的计算机,我会认为他们也可以复制您的安全cookie.
至少,确保旧饼干在一段时间后失去价值.当cookie停止工作时,即使是成功的hijaking攻击也会被挫败.如果用户拥有一个多月前登录的会话中的cookie,请让他们重新输入密码.确保每当用户点击您网站的"注销"链接时,旧会话UUID永远不会再次使用.
我不确定这个想法是否会起作用但是这里有:在你的会话cookie中添加一个序列号,也许是这样的字符串:
SessionUUID,序列号,当前日期/时间
加密此字符串并将其用作会话cookie.定期更改序列号 - 可能是当cookie为5分钟时,然后重新发出cookie.如果您愿意,您甚至可以在每个页面视图上重新发布它.在服务器端,记录您为该会话发出的最后一个序列号.如果有人发送带有错误序列号的cookie,则意味着攻击者可能正在使用他们之前截获的cookie,因此使会话UUID无效并要求用户重新输入其密码,然后重新发出新cookie.
请记住,您的用户可能有多台计算机,因此他们可能有多个活动会话.每次在计算机之间切换时,都不要强制他们再次登录.
您是否考虑过阅读有关PHP安全性的书籍?强烈推荐.
对于非SSL认证站点,我在以下方法上取得了很大成功.
禁止在同一帐户下进行多个会话,确保不要仅通过IP地址进行检查.而是通过登录时生成的令牌进行检查,该令牌与数据库中的用户会话一起存储,以及IP地址,HTTP_USER_AGENT等等
使用基于关系的超链接生成链接(例如http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8)链接附加了x-BYTE(首选大小)随机盐渍MD5字符串,页面重定向随机生成令牌对应于请求的页面.
重新加载后,会进行几次检查.
始发IP地址
HTTP_USER_AGENT
会话令牌
你明白了.
短寿命会话身份验证cookie.如上所述,包含安全字符串的cookie,这是对会话有效性的直接引用之一是一个好主意.使其每x分钟到期,重新发出该令牌,并将会话与新数据重新同步.如果数据中存在任何不匹配,请将用户注销,或让他们重新验证其会话.
我不是这方面的专家,我在这个特定的主题上有一点经验,希望其中一些可以帮助那里的任何人.
// Collect this information on every request $aip = $_SERVER['REMOTE_ADDR']; $bip = $_SERVER['HTTP_X_FORWARDED_FOR']; $agent = $_SERVER['HTTP_USER_AGENT']; session_start(); // Do this each time the user successfully logs in. $_SESSION['ident'] = hash("sha256", $aip . $bip . $agent); // Do this every time the client makes a request to the server, after authenticating $ident = hash("sha256", $aip . $bip . $agent); if ($ident != $_SESSION['ident']) { end_session(); header("Location: login.php"); // add some fancy pants GET/POST var headers for login.php, that lets you // know in the login page to notify the user of why they're being challenged // for login again, etc. }
这样做可以捕获有关用户会话的"上下文"信息,这些信息在单个会话期间不应发生变化.用户不会同时在美国和中国的计算机上,对吧?因此,如果IP地址在强烈意味着会话劫持尝试的同一会话中突然发生变化,那么您可以通过结束会话并强制用户重新进行身份验证来保护会话.这阻止了黑客攻击,攻击者也被迫登录而不是获得对会话的访问权限.通知用户尝试(ajax it up)和vola,稍微烦恼+知情用户并且他们的会话/信息受到保护.
我们引入用户代理和X-FORWARDED-FOR尽力捕获代理/网络背后系统的会话唯一性.您可以使用更多信息,随意创造.
这不是100%,但它非常有效.
您可以采取更多措施来保护会话,使其过期,当用户离开网站并返回时强制他们再次登录.您可以通过捕获空白的HTTP_REFERER(在URL栏中键入域)来检测用户离开和返回,或检查HTTP_REFERER中的值是否等于您的域(用户单击外部/制作的链接以获取您的现场).
过期会话,不要让它们无限期保持有效.
不要依赖cookie,它们可能被盗,它是会话劫持攻击的载体之一.
尝试中所描述的安全cookie协议本文件由刘,科瓦奇,黄,和豪达:
如文件所述:
在客户端和服务器之间运行的安全cookie协议需要提供以下四种服务:身份验证,机密性,完整性和反重放.
至于易于部署:
在效率方面,我们的协议不涉及任何数据库查找或公钥加密.在可部署性方面,我们的协议可以轻松部署在现有的Web服务器上,并且不需要对Internet cookie规范进行任何更改.
简而言之:它既安全又轻巧,对我来说非常棒.
没有办法阻止会话100%被阻止,但通过某种方法,我们可以减少攻击者隐藏会话的时间.
防止会话hijaking的方法:
1 - 始终使用ssl证书会话;
2 - 仅在httponly设置为true的情况下发送会话cookie(阻止javascript访问会话cookie)
2 - 在登录和注销时使用会话重新生成id(注意:不要在每个请求中使用会话重新生成,因为如果你有连续的ajax请求,那么你有机会创建多个会话.)
3 - 设置会话超时
4 - 在$ _SESSION变量中存储浏览器用户代理,并在每次请求时与$ _SERVER ['HTTP_USER_AGENT']进行比较
5 - 设置令牌cookie,并将该cookie的到期时间设置为0(直到浏览器关闭).为每个请求重新生成cookie值.(对于ajax请求,不要重新生成令牌cookie).EX:
//set a token cookie if one not exist if(!isset($_COOKIE['user_token'])){ //generate a random string for cookie value $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM)); //set a session variable with that random string $_SESSION['user_token'] = $cookie_token; //set cookie with rand value setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true); } //set a sesison variable with request of www.example.com if(!isset($_SESSION['request'])){ $_SESSION['request'] = -1; } //increment $_SESSION['request'] with 1 for each request at www.example.com $_SESSION['request']++; //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0 if($_SESSION['request'] > 0){ // if it's equal then regenerete value of token cookie if not then destroy_session if($_SESSION['user_token'] === $_COOKIE['user_token']){ $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM)); $_SESSION['user_token'] = $cookie_token; setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true); }else{ //code for session_destroy } } //prevent session hijaking with browser user agent if(!isset($_SESSION['user_agent'])){ $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT']; } if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){ die('session hijaking - user agent'); }
注意:不要使用ajax请求注释重新生成令牌cookie:上面的代码就是一个例子.注意:如果用户注销,则必须销毁cookie令牌以及会话
6 - 使用用户IP来阻止会话hijaking并不是一个好方法,因为有些用户ip会随着每个请求而改变.这会影响有效的用户
7 - 我个人将会话数据存储在数据库中,这取决于您采用的方法
如果您发现我的方法有误,请纠正我.如果你有更多的方法来防止会话hyjaking请告诉我.