做了这么久的PHP开发,真的没有注意安全问题。每次集中精力完成项目,最近就在网上看到一篇关于安全的文章。看完之后发现我之前的项目有很大的安全漏洞,于是选择了一个项目进行测试,发现很容易就能拿下。这里我将分享一个我自己编写的测试示例,来说明PHP中的session是如何不安全的,以及如何在项目中加强它的安全性。网上有很多关于会话原理和机制的好文章,我们可以自己参考。让我们直接在下面分享测试示例。这个测试的例子主要是一个登录页面,登录成功后可以更改密码,就是这么简单的功能。界面如下
首先,使用函数session_start()在项目入口打开会话。这样,当客户端发起请求时,它将生成一个标识,即SessionID。cookie存储在客户机中,客户机和服务器之间的每次通信都由这个SessionID标识。成功登录后,用户id和用户名将存储在会话中。
$ _ session ['userid']=用户id $ _ session ['uname']=用户名后,所有操作都是通过判断$ _ session ['userid']是否存在来检查用户是否登录。代码如下:
if(isset($_SESSION['userid'])返回true修改密码接口的调用通过ajax post将数据传输到服务器。
$.post ('interface * * * * * * ',{ old pass : old pass 3360 newpass,userid:uid,},function(data){ data=eval('(' data ')'));$('.grant _ info’)。html(infos[data.info])。show();});请注意,我已经在这里的html页面中编写了这段代码,所以如果我看到html代码,我将知道接口地址。修改密码的界面是这样实现的:首先判断用户是否登录,如果是,则进行修改密码操作。测试示例的实现思想可能如上所述。用SessionID攻击。1.第一步是获取SessionID。当然,攻击者有很多方法可以获得这个id。由于我的水平有限,这里就不介绍如何获取了。我们可以模拟一下,先正常访问这个项目,然后通过浏览器查看SessionID,从而得到一个合法的用户ID。您可以在请求标题中看到该标识。
Accept: text/html,application/xhtml xml,application/XML;q=0.9,*/*;q=0.8Accept-Encoding: gzip,pinlaceaccept-language : zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 connection : keep-alivecookie : Hm _ lvt _ BF 1154 EC 41057869 ceed 66 e 9 B3 af 5 e 7=1450428827,1450678226,1450851291,1450851486;PHPSESSID=2 eiq 9 hcpu 3 ksri 4 r 587 CKT 9 JT 7;host : * * * * * * refer : * * * * * * User-agent : Mozilla/5.0(Windows NT 6.1;RV :41.0)gecko/20100101 Firefox/41.0,获取sessionID后,如果这个用户登录成功,那么这个用户的信息就会在服务器的会话中。2.获取SessionID后,如果攻击者已经知道修改密码的界面,他可以直接修改这个用户的密码。如果攻击者没有得到接口地址,他可以通过查看页面代码找到接口地址。您可以使用以下命令。
# curl-cookie ' phpsessid=2eiq 9 hcpu 3k Sri 4 r 587 CKT 9 JT 7 '页面地址如上所述,在本例中,ajax代码是在一个html页面中编写的,因此在这里可以看到html代码的接口地址部分如下。
html xmlns=' http://www . w3 . org/1999/XHTML ' head……var uid=$('。userid ')。val();$.post('/User/User/modifypass_do ',{ oldpass:oldpass,newpass:newpass,userid:uid,},function(data){ data=eval('(' data ')'));$('.grant _ info’)。html(infos[data.info])。show();} );span输入类型=' password ' name=' old password ' id=' textfield _ o '占位符='原始密码'/Spapaninput类型=' password ' name=' new pass ' id=' textfield _ n '占位符=' new password '/spanputtype=' password ' name=' confirm pass ' id=' textfield _ c '占位符='确认密码'/spanputtype=' button ' class=' BTN _ ok ' value='确认修改'/3。拿到界面后,可以通过curl模拟发帖发送数据修改密码。命令如下。
# curl-cookie ' phpsessid=2 eiq 9 hcpu 3 ksri 4 r 587 CKT 9 jt7 '-dold pass=11111-d new pass=00000-d userid=用户id接口地址。如果该用户已经登录,攻击者可以通过执行上述命令来修改用户的密码。方法为了解决上述攻击,我们可以通过使验证方法复杂化来提高安全性。一种方法是使用请求头中的用户代理项来加强其安全性。
Accept: text/html,application/xhtml xml,application/XML;q=0.9,*/*;q=0.8Accept-Encoding: gzip,pinlaceaccept-language : zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 connection : keep-alivecookie : Hm _ lvt _ BF 1154 EC 41057869 ceed 66 e 9 B3 af 5 e 7=1450428827,1450678226,1450851291,1450851486;PHPSESSID=2 eiq 9 hcpu 3 ksri 4 r 587 CKT 9 JT 7;host : * * * * * * refer : * * * * * * User-agent : Mozilla/5.0(Windows NT 6.1;RV :41.0)gecko/20100101 Firefox/41.0在项目开始时,我们只是使用了session_start()函数来打开会话。现在我们可以在session_start()下添加这段代码。
$ _ SESSION[' User _ AGENT ']=MD5($ _ SERVER[' HTTP _ USER _ AGENT ']);然后,在判断是否登录时,增加以下判断条件。
if(isset($ _ SESSION[' userid '])$ _ SESSION[' User _ AGENT ']==MD5($ _ SERVER[' HTTP _ USER _ AGENT ']){ return true;}这样就可以避免上面简单的攻击。总结:当然,实际情况中的攻击远不简单。首先很难获得SessionID,然后尽可能对与服务器交互的代码进行加密,可以避免上述情况。在我们第二次修改代码后,我们可以增加攻击的复杂性,但不能消除攻击。攻击的方式有很多种,但这只是一种简单的方式,只提供一种思路,但原理是一样的。在实际情况中,我们可以根据实际情况增强代码的安全性。
我只想在这里分享一下我在工作中遇到的问题。希望你能学得更深。