PHP会话控制中的安全问题

Session会话

在聊Session之前,先得了解一下CookieCookie是存储在用户客户端上用户识别身份的登陆令牌。最初有很多网站拿它做长期登陆状态,免去用户重复登陆。后来发现存在客户端的这个身份令牌很不安全,很可能被他人获取之后冒牌登陆。而Session是保存在服务器上的,功能和Cookie相似,服务器上的数据不太容易被别人获得,但也仅仅是相对安全。

用户登陆界面

当访问用户登陆页面时,查看浏览器控制台,会发现自动生成了一条cookiePHPSESSID=odpnhnmsf2s5vq4d5n1rqvb656。它是哪里来的呢?原来是因为session_start()函数调用的时候,其实是通过setCookie()函数向cookie中设置了
PHPSESSID这个key,对应的value是一个随机的、唯一的32位字符串!
通过在控制台中输入:document.cookie,可以返回PHPSESSID以及其所对应的值。

假设这个登陆令牌被他人得到了,他可以直接登陆吗?

  • 接下来做一个实验:

在火狐浏览器中登陆成功
还是那个字符串没变,把它复制一下,用另一个浏览器访问登陆页面,调出控制台输入document.cookie,看一下现在的cookie
和之前的不一样。但是,如果之前拿到的cookie赋值给当前页面会怎么样呢?document.cookie='PHPSESSID=43f7139b4af1ba2d93db4db3e74bf000'
这个时候再刷新一下页面,你会发现已经登陆成功了!

HttpOnly

在实际场景中,通过XSS攻击,很容易被他人获取到。(下一篇,准备讲一下如何实现XSS攻击)
那么有什么措施可以防范的呢?先从开启HttpOnly开始。HttpOnly会话支持的浏览器,将仅用于发送HTTP(或HTTPS)请求时,从而限制了其他非HTTP的API(如JavaScript)访问。
开启的方法有两种:
第一种,是通过配置php.ini,添加一行session.cookie_httponly=On。同时你可能已经发现session.name = PHPSESSID,原来就是在php.ini中配置的。个人推荐这种,配置一次,一劳永逸。
如果你没有配置服务器的权限,那么第二种方法就是在session_start()开启之前,添加一行代码:session_set_cookie_params(0, "/", "", false, true);
设置完成后,可以看到,多了一个HttpOnly字样。
再尝试去获取cookie的时候,已经不行了。
设置了HttpOnly是不是就很安全了呢?那可不一定!HttpOnly仅仅能够防止JavaScript不能访问,但是并不能防止对网络频道具有访问权限的攻击者直接访问该 Cookie。针对这种情况,应考虑使用安全套接字层 (SSL) 来提供帮助。

Secure

设置Secure开启,就是之前设置的函数中的session_set_cookie_params(0, "/", "", true, true);,倒数第二个参数设为true。创建的Session会话会以安全的形式向服务器传输,也就是只能在HTTPS连接中被浏览器传递到服务器端进行会话验证,如果是HTTP连接则不会传递该信息,所以不会被盗取到Cookie的具体内容。这个设置也可以在php.ini中配置:session.cookie_secure=On。如果全局配置的话,说明全站只能用https传递数据。
这时再去查看PHPSESSID时,会看到多了安全两个字。

这样感觉已经很安全了,但是查看PHP官方网站,关于会话安全的问题,还有一个重要配置常常被忽视:session.use_strict_mode=On。它有什么作用呢?这里给个链接,有兴趣的可以去看一下。
和会话安全相关的配置项

下一篇文章准备写一下常见的XSS、反射型XSS和CSRF的攻击和防范。

坚持原创技术分享,您的支持将是鼓励我继续创作的动力!