什么是防止会话劫持的最好方法?
具体来说,这是关于何时使用客户端会话cookie来识别服务器上的会话。
是对整个网站使用SSL / HTTPSencryption的最佳答案,并且您有最好的保证,在中间的攻击中没有人能够嗅探现有的客户端会话cookie?
也许是第二好的使用会话cookie中存储的会话值本身的某种encryption?
如果恶意用户能够物理访问机器,他们仍然可以查看文件系统来检索有效的会话cookie并使用它来劫持会话?
encryption会话值将没有任何效果。 会话cookie已经是一个任意的值,encryption它只会产生另一个可以被嗅探的任意值。
唯一真正的解决scheme是HTTPS。 如果您不想在整个网站上进行SSL(也许您有性能方面的担忧),那么您可能只能通过SSL保护敏感区域。 为此,首先确保您的login页面是HTTPS。 当用户login时,除了常规的会话cookie之外,还要设置一个安全cookie(意味着浏览器只能通过SSL链接传输)。 然后,当用户访问您的某个“敏感”区域时,将其redirect到HTTPS,并检查是否存在该安全cookie。 真正的用户会拥有它,会话劫持者不会。
编辑 :这个答案最初是在2008年编写的。现在是2016年,没有理由不在整个网站上使用SSL。 没有更多的纯文本HTTP!
SSL只能帮助嗅探攻击。 如果攻击者可以访问你的机器,我会假设他们也可以复制你的安全cookie。
至less,确保旧cookies在一段时间后失去价值。 当cookie停止工作时,即使成功的hijaking攻击也会受到阻碍。 如果用户从一个多月前login的会话中获取cookie,请重新input密码。 确保每当用户点击您的网站的“注销”链接,旧的会话UUID永远不能再次使用。
我不确定这个想法是否会起作用,但在这里:在会话cookie中添加一个序列号,或许是这样一个string:
SessionUUID,序列号,当前date/时间
encryption此string并将其用作会话cookie。 定期更改序列号 – 也许当cookie是5分钟,然后重新发布cookie。 如果您愿意,甚至可以在每个页面视图上重新发布。 在服务器端,logging您为该会话发布的最后一个序列号。 如果有人用错误的序列号发送cookie,则意味着攻击者可能正在使用他们先前拦截的cookie,从而使会话UUID无效,并要求用户重新input密码,然后重新发布新的cookie。
请记住,您的用户可能有多台计算机,因此他们可能有多个活动会话。 不要做任何事情,迫使他们每次在计算机之间切换时再次login。
你有没有考虑读一本关于PHP安全性的书? 强烈推荐。
对于非SSLauthentication的网站,我已经使用以下方法取得了很大成功。
-
禁止在同一帐户下进行多个会话,确保您没有单独通过IP地址进行检查。 而是通过login时生成的与数据库中的用户会话一起存储的令牌以及IP地址,HTTP_USER_AGENT等等进行检查
-
使用基于关系的超链接生成一个链接(例如http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 )该链接附加了一个x-BYTE(首选大小)随机腌制的MD5string,在页面redirect时随机生成令牌对应于请求的页面。
- 重新加载后,将进行几次检查。
- 始发IP地址
- HTTP_USER_AGENT
- 会话令牌
- 你明白了。
-
短寿命会话身份validationCookie。 如上所述,包含安全string的cookie是直接引用会话有效性的一个好主意。 使其每x分钟过期,重新发出该令牌,并将会话与新数据重新同步。 如果数据中有任何不匹配,请将用户注销,或让他们重新validation其会话。
我绝不是这个问题的专家,我在这个专题上有一些经验,希望有一些帮助那里的人。
// 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地址在同一会话中突然发生变化,强烈暗示会话劫持尝试,则通过结束会话并强制用户重新进行身份validation来保护会话。 这阻止了黑客攻击,攻击者也被迫login而不是获得访问权限。 通知用户该尝试(阿贾克斯了一点),并挥发,轻微恼火+通知用户及其会话/信息受到保护。
我们引入用户代理和X-FORWARDED-FOR,尽最大努力为代理/networking背后的系统捕获会话的唯一性。 您可能可以使用更多的信息,然后自由地创造性。
这不是100%,但它是非常有效的。
还有更多的事情可以做,以保护会话,到期,当用户离开一个网站,并回来强制他们再次login也许。 您可以通过捕获空白的HTTP_REFERER(在URL栏中键入域)来检测用户离开和返回,或者检查HTTP_REFERER中的值是否等于您的域(用户单击外部/制作的链接以获得您的现场)。
到期会议,不要让他们无限期地保持有效。
不要依靠cookies,他们可以被盗,这是会话劫持的攻击媒介之一。
试用Liu,Kovacs,Huang和Gouda在本文中描述的Secure Cookie协议:
如文件所述:
在客户端和服务器之间运行的安全cookie协议需要提供以下四种服务:authentication,机密性,完整性和防重放。
至于易于部署:
就效率而言,我们的协议不涉及任何数据库查询或公钥密码学。 就可部署性而言,我们的协议可以很容易地部署到现有的Web服务器上,而且不需要对Internet Cookie规范进行任何更改。
简而言之:它是安全的,轻量级的,对我来说很好。
首先,我的英语不好。
没有办法阻止100%的会话劫持,但是有些事情可以减less攻击者劫持会话的时间。
阻止会话劫持的方法:
1 – 始终使用会话与SSL证书;
2 – 发送会话cookie只与httponly设置为true(防止JavaScript访问会话cookie)
2 – 在login和注销时使用会话重新生成ID(注意:不要在每次请求时使用会话重新生成,因为如果你有连续的Ajax请求,那么你有机会创build多个会话。
3 – 设置会话超时
4 – 将浏览器用户代理存储在$ _SESSIONvariables中,并在每个请求中与$ _SERVER ['HTTP_USER_AGENT']进行比较
5 – 设置一个令牌cookie,并将该cookie的到期时间设置为0(直到浏览器closures)。 重新生成每个请求的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来防止会话劫持是不好的,因为有些用户的IP会随着每个请求而改变。 影响有效的用户
7 – personaly我将会话数据存储在数据库中,这取决于你采用什么方法
如果你发现我的错误,请纠正我。 如果你有更多的方法来防止会话喧闹告诉我。
确保您不会使用递增的整数作为会话ID。 更好地使用GUID,或其他一些长随机生成的string。
有很多方法可以防止会话劫持,但是所有这些方法都会降低用户满意度或者不安全。
-
IP和/或X-FORWARDED-FOR检查。 这些工作,是相当安全的…但想象用户的痛苦。 他们来到一个办公室与WiFi,他们得到新的IP地址,失去了会议。 需要再次login。
-
用户代理检查。 和上面一样,新版本的浏览器已经不存在了,你将失去一个会话。 另外,这些很容易“破解”。 黑客发送假UAstring是微不足道的。
-
localStorage标记。 login时生成一个令牌,将其存储在浏览器存储中,并将其存储到encryption的cookie(在服务器端encryption)。 这对用户没有副作用(localStorage通过浏览器升级持续存在)。 这不是安全的 – 因为它只是通过默默无闻的安全。 此外,你可以添加一些逻辑(encryption/解密)JS以进一步掩盖它。
-
Cookie重新发行。 这可能是正确的做法。 窍门是一次只允许一个客户使用一个cookie。 所以,积极的用户将每小时或更less的时间重新发布cookie。 如果发行新的cookie,旧的cookie将失效。 黑客仍然是可能的,但要做的更难 – 黑客或有效的用户将被拒绝访问。
让我们考虑一下,在login阶段,客户端和服务器可以达成一个秘密盐值。 此后,服务器提供每个更新的计数值,并期望客户端使用(秘密盐值+计数)的散列进行响应。 潜在的劫机者没有办法获得这个秘密盐值,因此不能产生下一个散列。
为了降低风险,您还可以将原始IP与会话相关联。 这样攻击者必须在同一个专用networking内才能使用会话。
检查引用标题也可以是一个选项,但更容易被欺骗。
保护:
$ip=$_SERVER['REMOTE_ADDER']; $_SESSEION['ip']=$ip;