跨站脚本攻击(XSS)和CSRF攻击:为什么Cookie中有HttpOnly属性?

什么是XSS

XSS全称是Cross Site Scripting,为了与“CSS”区分开来,故简称XSS,翻译过来就是“跨站脚本”。

XSS 攻击是指⿊客往HTML⽂件中或者DOM中注⼊恶意脚本,从⽽在⽤⼾浏览⻚⾯时利⽤注⼊的恶意脚本对⽤⼾ 实施攻击的⼀种⼿段。

恶意脚本做哪些事情

  • 可以窃取Cookie信息。恶意JavaScript可以通过“document.cookie”获取Cookie信息,然后通过 XMLHttpRequest或者Fetch加上CORS功能将数据发送给恶意服务器;恶意服务器拿到⽤⼾的Cookie信息 之后,就可以在其他电脑上模拟⽤⼾的登录,然后进⾏转账等操作。
  • 可以监听用户行为,通过addEventListener接口来监听键盘等事件。
  • 可以通过修改DOM伪造假的登录窗口,来欺骗用户输入从而获取信息
  • 还有浮窗广告

恶意脚本如何注入

常见的主要有存储型XSS攻击、反射型XSS攻击和基于DOM的XSS攻击三种⽅式来注⼊恶意脚本

存储型XSS攻击

image-20210908141204562

主要是能提交内容的部分没有对内容进行过滤,导致JS代码被带进数据库


反射型XSS攻击

在⼀个反射型XSS攻击过程中,恶意JavaScript脚本属于⽤⼾发送给⽹站请求中的⼀部分,随后⽹站⼜把恶 意JavaScript脚本返回给⽤⼾。当恶意JavaScript脚本在⽤⼾⻚⾯中被执⾏时,⿊客就可以利⽤该脚本做⼀ 些恶意操作。

Web服务器不会存储反射型XSS攻击的恶意脚本,这是和存储型XSS攻击不同的地⽅。


基于DOM的XSS攻击

基于DOM的XSS攻击是不牵涉到⻚⾯Web服务器的。

⿊客通过各种⼿段将恶意脚本注⼊⽤⼾的⻚ ⾯中,⽐如通过⽹络劫持在⻚⾯传输过程中修改HTML⻚⾯的内容,这种劫持类型很多,有通过WiFi路由器 劫持的,有通过本地恶意软件来劫持的,它们的共同点是在Web资源传输过程或者在⽤⼾使⽤⻚⾯的过程中 修改Web⻚⾯的数据。


如何阻止XSS攻击

存储型XSS攻击反射型XSS攻击都是需要经过Web服务器来处理的,因此可以认为这两种类型的漏洞是服务端的安全漏洞

⽽基于DOM的XSS攻击全部都是在浏览器端完成的,因此基于DOM的XSS攻击是 属于前端的安全漏洞。


服务器对输入内容进行过滤或者转码

<script>alert('你被xss攻击了')</script>进行过滤或者转码,使其失去功能,类似<script>alert('你被xss攻击了')</script>


充分利用CSP

CSP的功能

  • 限制加载其他域下的资源⽂件,这样即使⿊客插⼊了⼀个JavaScript⽂件,这个JavaScript⽂件也是⽆法被加载的;
  • 禁⽌向第三⽅域提交数据,这样⽤⼾数据也不会外泄;
  • 禁⽌执⾏内联脚本和未授权的脚本;
  • 提供了上报机制,这样可以帮助我们尽快发现有哪些XSS攻击,以便尽快修复问题。

使⽤HttpOnly属性

由于很多XSS攻击都是来盗⽤cookie的,因此还可以通过使⽤HttpOnly属性来保护我们Cookie的安全。

通常服务器可以将某些cookie设置为HttpOnly标志

被设置为HttpOnly的cookie只能使用在HTTP请求中,无法被JS读取。


什么是CSRF攻击

CSRF英⽂全称是Cross-site request forgery,所以⼜称为“跨站请求伪造”

CSRF攻击就是⿊客利⽤了⽤ ⼾的登录状态,并通过第三⽅的站点来做⼀些坏事。

和XSS不同的是,CSRF攻击不需要将恶意代码注⼊⽤⼾的⻚ ⾯,仅仅是利⽤服务器的漏洞和⽤⼾的登录状态来实施攻击。

类似链接点击这种

<div>
    <img width=150 src=http://images.xuejuzi.cn/1612/1_161230185104_1.jpg> </img> </div> <div>
    <a href="http://139.196.87.221/getallcarjoin?isdone=0" taget="_blank">
    点击下载美⼥照⽚
    </a>
</div>


如何阻止CSRF攻击

发起CSRF攻击的三个必要条件:

  • 目标站点有CSRF的漏洞
  • ⽤⼾要登录过⽬标站点,并且在浏览器上保持有该站点的登录状态;
  • 需要⽤⼾打开⼀个第三⽅站点,可以是⿊客的站点,也可以是⼀些论坛。

对于CSRF攻击主要的防护⼿段是提升服务器的安全性


充分利⽤好Cookie 的 SameSite 属性

⿊客会利⽤⽤⼾的登录状态来发起CSRF攻击,⽽Cookie正是浏览器和 服务器之间维护登录状态的⼀个关键数据,因此要阻⽌CSRF攻击,⾸先就要考虑在Cookie上来做⽂章。

通常CSRF攻击都是从第三⽅站点发起的,要防⽌CSRF攻击,我们最好能实现从第三⽅站点发送请求时禁⽌ Cookie的发送,因此在浏览器通过不同来源发送HTTP请求时,有如下区别:

  • 如果是从第三⽅站点发起的请求,那么需要浏览器禁⽌发送某些关键Cookie数据到服务器;
  • 如果是同⼀个站点发起的请求,那么就需要保证Cookie数据正常发送。

Cookie 中的SameSite属性可以有效地降低 CSRF攻击的⻛险

在HTTP响应头中,通过set-cookie字段设置Cookie时,可以带上SameSite选项

set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none

SameSite选项通常有Strict、Lax和None三个值。

  • 如果SameSite的值是Strict,那么浏览器会完全禁⽌第三⽅ Cookie。
  • Lax相对宽松⼀点。从第三⽅站点的链接打开和从第三⽅站点提交Get⽅式的表单这 两种⽅式都会携带Cookie。但如果在第三⽅站点中使⽤Post⽅法,或者通过img、iframe等标签加载的 URL,这些场景都不会携带Cookie。
  • ⽽如果使⽤None的话,在任何情况下都会发送Cookie数据。

验证请求的来源站点

另外⼀种防⽌CSRF攻击的策略,那就是在服务器端验证请求来源的站点。

由于CSRF攻击 ⼤多来⾃于第三⽅站点,因此服务器可以禁⽌来⾃第三⽅站点的请求。

HTTP请求头中的 Referer和Origin 属性

Referer是HTTP请求头中的⼀个字段,记录了该HTTP请求的来源地址。

虽然可以通过Referer告诉服务器HTTP请求的来源,但是有⼀些场景是不适合将来源URL暴露给服务器的

在⼀些重要的 场合,⽐如通过XMLHttpRequest、Fecth发起跨站请求或者通过Post⽅法发送请求时,都会带上Origin属 性

Origin属性只包含了域名信息,并没有包含具体的URL路径,这是Origin和Referer的⼀个 主要区别。

因此,服务器的策略是优先判断Origin,如果请求头中没有包含Origin属性,再根据实际情况判断是否使⽤ Referer值。


CSRF Token

第⼀步,在浏览器向服务器发起请求时,服务器⽣成⼀个CSRF Token。CSRF Token其实就是服务器⽣成的 字符串,然后将该字符串植⼊到返回的⻚⾯中

对于浏览器发出的请求都会携带token,第三方页面无法获取token就没办法完成请求