spring security系列(二)

防止固定会话攻击

HttpSession

HttpSession 是一个服务端的概念,服务端生成的 HttpSession 都会有一个对应的 sessionid,这个 sessionid 会通过 cookie 传递给前端,前端以后发送请求的时候,就带上这个 sessionid 参数,服务端看到这个 sessionid 就会把这个前端请求和服务端的某一个 HttpSession 对应起来,形成“会话”的感觉。

浏览器关闭并不会导致服务端的 HttpSession 失效,想让服务端的 HttpSession 失效,要么手动调用 HttpSession#invalidate 方法;要么等到 session 自动过期;要么重启服务端。

但是为什么有的人会感觉浏览器关闭之后 session 就失效了呢?这是因为浏览器关闭之后,保存在浏览器里边的 sessionid 就丢了(默认情况下),所以当浏览器再次访问服务端的时候,服务端会给浏览器重新分配一个 sessionid ,这个 sessionid 和之前的 HttpSession 对应不上,所以用户就会感觉 session 失效。

注意前面我用了一个默认情况下,也就是说,我们可以通过手动配置,让浏览器重启之后 sessionid 不丢失,但是这样会带来安全隐患,所以一般不建议。

以 Spring Boot 为例,服务端生成 sessionid 之后,返回给前端的响应头是这样的:
在这里插入图片描述
在服务端的响应头中有一个 Set-Cookie 字段,该字段指示浏览器更新 sessionid,同时大家注意还有一个 HttpOnly 属性,这个表示通过 JS 脚本无法读取到 Cookie 信息,这样能有效的防止 XSS 攻击。

下一次浏览器再去发送请求的时候,就会自觉的携带上这个 jsessionid 了:
在这里插入图片描述

会话固定攻击

什么是会话固定攻击?英文叫做 session fixation attack。

正常来说,只要你不关闭浏览器,并且服务端的 HttpSession 也没有过期,那么维系服务端和浏览器的 sessionid 是不会发生变化的,而会话固定攻击,则是利用这一机制,借助受害者用相同的会话 ID 获取认证和授权,然后利用该会话 ID 劫持受害者的会话以成功冒充受害者,造成会话固定攻击。

如何防御

这个问题的根源在 sessionid 不变,如果用户在未登录时拿到的是一个 sessionid,登录之后服务端给用户重新换一个 sessionid,就可以防止会话固定攻击了。

如果你使用了 Spring Security ,其实是不用担心这个问题的,因为 Spring Security 中默认已经做了防御工作了。

Spring Security 中的防御主要体现在三个方面:

首先就是StrictHttpFirewall,请求地址中有 ; 请求会被直接拒绝。

另一方面就是响应的 Set-Cookie 字段中有 HttpOnly 属性,这种方式避免了通过 XSS 攻击来获取 Cookie 中的会话信息进而达成会话固定攻击。

第三点则是让 sessionid 变一下。既然问题是由于 sessionid 不变导致的,那我就让 sessionid 变一下。
在这里插入图片描述
可以看到,在这里,我们有四个选项:

migrateSession 表示在登录成功之后,创建一个新的会话,然后讲旧的 session 中的信息复制到新的 session 中,默认即此。
none 表示不做任何事情,继续使用旧的 session。
changeSessionId 表示 session 不变,但是会修改 sessionid,这实际上用到了 Servlet 容器提供的防御会话固定攻击。
newSession 表示登录后创建一个新的 session。
默认的 migrateSession ,在用户匿名访问的时候是一个 sessionid,当用户成功登录之后,又是另外一个 sessionid,这样就可以有效避免会话固定攻击。

这三种方案,可以让我们有效避免会话固定攻击!

Spring Security 防止csrf攻击

1、什么是csrf

CSRF 就是跨域请求伪造,英文全称是 Cross Site Request Forgery。

这是一种非常常见的 Web 攻击方式,其实是很好防御的,但是由于经常被很多开发者忽略,进而导致很多网站实际上都存在 CSRF 攻击的安全隐患。

2、原理

原理
其实这个流程很简单:

假设用户打开了招商银行网上银行网站,并且登录。
登录成功后,网上银行会返回 Cookie 给前端,浏览器将 Cookie 保存下来。
用户在没有登出网上银行的情况下,在浏览器里边打开了一个新的选项卡,然后又去访问了一个危险网站。
这个危险网站上有一个超链接,超链接的地址指向了招商银行网上银行。
用户点击了这个超链接,由于这个超链接会自动携带上浏览器中保存的 Cookie,所以用户不知不觉中就访问了网上银行,进而可能给自己造成了损失。

3、CSRF防御

CSRF 防御,一个核心思路就是在前端请求中,添加一个随机数。

因为在 CSRF 攻击中,黑客网站其实是不知道用户的 Cookie 具体是什么的,他是让用户自己发送请求到网上银行这个网站的,因为这个过程会自动携带上 Cookie 中的信息。

所以我们的防御思路是这样:用户在访问网上银行时,除了携带 Cookie 中的信息之外,还需要携带一个随机数,如果用户没有携带这个随机数,则网上银行网站会拒绝该请求。黑客网站诱导用户点击超链接时,会自动携带上 Cookie 中的信息,但是却不会自动携带随机数,这样就成功的避免掉 CSRF 攻击了。

3.1、默认方案(前后端不分离)

前端页面添加一个

<body>
<form action="/hello" method="post">
    <input type="hidden" th:value="${_csrf.token}" th:name="${_csrf.parameterName}">
    <input type="submit" value="hello">
</form>
</body>

启动项目,我们访问 hello 页面,在访问时候,需要先登录,登录成功之后,我们可以看到登录请求中也多了一个参数,如下:
在这里插入图片描述
可以看到,这里也多了 _csrf 参数。

这里我们用了 Spring Security 的默认登录页面,如果大家使用自定义登录页面,可以参考上面 hello.html 的写法,通过一个隐藏域传递 _csrf 参数。

访问到 hello 页面之后,再去点击按钮,就可以访问到 hello 接口了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值