Web开发安全的XSS和CSRF问题以及解决方案|青训营笔记

118 阅读5分钟

Web开发安全的XSS和CSRF问题以及解决方案 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第2天

一、XSS

1. 什么是XSS?

跨站脚本攻击(Cross-Site-Scripting)但是缩写是css,重名,所以改为XSS。XSS是跨站脚本攻击,恶意攻击者在web页面中插入恶意的script代码,当用户访问该页面时,恶意的script会执行,达到恶意攻击的目的。

不需要用户做任何的登录认证,它会通过合法的操作(比如在url中输入,在评论框中输入),向用户的页面注入脚本(可能是html,js代码),原理与SQL注入攻击类似。

2. 攻击方式

反射型

发出请求时,XSS代码出现在url中,作为输入提交到服务器端,当用户打开带有恶意代码的url链接的时候,网站的服务器将恶意代码从url中取出,然后拼接到html中返回给浏览器端,用户浏览器接受到后相应并解析代码,其中的恶意代码也会被执行到,攻击是一次性的。

例如:

 host/path/?param=<script>alert('123456')</script>

存储型

存储型XSS和反射型的XSS的区别在于,提交的代码会存储到服务器端(数据库,内存,文件系统等),对全部用户可见,攻击是持久的。

  • 攻击者将恶意代码存放到目标网站的数据库中
  • 用户浏览目标网站的时候,网站服务器从数据库中把恶意代码取出,然后拼接到html后返回给浏览器
  • 浏览器接受到响应后解析并执行,其中恶意代码也会被执行

DOM-based型

基于文档对象模型,不需要服务器的参与,恶意攻击的发起+执行,全在浏览器完成。

  • 攻击者构造出特殊的url,其中url中含有恶意代码
  • 用户打开含有恶意代码的url
  • 用户浏览器响应解析并执行,前端使用js取出url中恶意代码并执行
 host/path/?param=<script>alert('123456')</script>  //相同的URL
 ​
 const content=new URL(location.href).searchParams.get("param");
 const div=document.createElement("div");
 //恶意脚本注入
 div.innerHTML=content;
 document.body.append(div);

3.特点

  • 通常难以从UI上感知(暗地里执行脚本)
  • 窃取用户信息(cookie/token)
  • 绘制UI(例如弹窗等,诱骗用户点击或者填写表单)

4. 危害

  • 窃取网页浏览中的cookie值,document.cookie 获取 Cookie 信息后,在其他电脑上模拟用户登录,然后进行转账等行为;
  • 劫持流量实现恶意跳转
  • 配合CSRF攻击完成恶意请求
  • 监听用户行为:使用 addEventListener 监听用户键盘行为,获取用户账号密码信息;
  • 修改 DOM 伪造登录窗口,欺骗用户输入用户名和密码;

5.如何阻止?

  1. cookie安全策略。Cookie 设置 HttpOnly 属性: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
  2. XSS防御HTML编码。即转义转义 HTML。
  3. XSS防御之javascript编码
  4. XSS 防御之 URL 编码
  5. 开启CSP网页安全政策防止XSS攻击(CSP(Content Security Policy)是一种内容安全策略,通过配置可以告诉浏览器那些内容可以被加载执行,而那些又不可以)
  6. 服务器对输入内容进行过滤或转码

二、CSRF

1. 什么是CSRF ?

CSRF(Cross-Site Request Forgery):“跨站请求伪造”。攻击者盗用了用户的身份,以用户的名义发送恶意请求。

2. 攻击方式

登录受信任的网站A,并且在本地生成cookie 在不登出网站A的情况下,访问恶意网站B。

与 XSS 攻击不同的是:XSS 是攻击者直接对我们的网站 A 进行注入攻击,CSRF 是通过网站 B 对我们的网站 A 进行伪造请求。

例如:登录购物网站 A 之后点击一个恶意链接 B,B 请求了网站 A 的下单接口,结果是在网站 A 的帐号生成一个订单。其背后的原理是:网站 B 通过表单、get 请求来伪造网站 A 的请求,这时候请求会带上网站 A 的 cookies,若登录态是保存在 cookies 中,则实现了伪造攻击。

跨站请求可以用各种方式:图片 URL、超链接、CORS、Form 提交等等。

GET 类型的 CSRF

浏览器自动发起获取图片资源时,如果浏览器未做判断会认为这是一个转账请求。

 <!DOCTYPE html>
 <html>
   <body>
     <h1>黑客的站点:CSRF攻击演示</h1>
     <img src="https://time.geekbang.org/sendcoin?user=hacker&number=100">
   </body>
 </html>
 复制代码

POST 类型的 CSRF

构建一个自动提交转账请求的隐藏表单,当用户打开该站点时自动执行表单提交转账请求。

 <!DOCTYPE html>
 <html>
 <body>
   <h1>CSRF攻击</h1>
   <form id='hacker-form' action="https://123.com" method=POST>
     <input type="hidden" name="user" value="hacker" />
     <input type="hidden" name="number" value="100" />
   </form>
   <script> document.getElementById('hacker-form').submit(); </script>
 </body>
 </html>
 复制代码

链接类型的 CSRF

引诱用户点击图片下方的链接,发起请求。

 <div>
   <img width=150 src=http://123.com/123456.jpg> </img> </div> <div>
   <a href="https://123.com/getInfo?user=hacker&number=100" taget="_blank">
     点击下载
   </a>
 </div>

3. 特点

  • 在用户不知情的前提下
  • 利用用户权限(cookie)
  • 构造HTTP请求,窃取或修改用户的敏感信息

4. 危害

  • 用户的登录状态态被盗用
  • 冒充用户完成操作或修改数据

5. 如何阻止

  1. 尽量使用POST请求,限制GET
  2. cookie设置SameSite,设置 cookie 的 SameSite 值为 strict,这样只有同源网站的请求才会带上 cookie。这样 cookies 就不能被其他域名网站使用,达到了防御的目的。
  3. 增加token,用于向服务端确认身份
  4. 通过referer进行识别,在 HTTP 协议中,头部有个 Referer 字段,他记录了该 HTTP 请求的来源地址,在服务端设置该字段的检验,通过检查该字段,就可以知道该请求是否合法,不过请求头也容易伪造。

三、XSS和CSRF的区别

1.CSRF需要用户进行登录,XSS不需要

2.CSRF是利用网站本身的漏洞,去请求网站,XSS是向网站中注入JS代码,然后执行代码,篡改网站的内容


在平时基本的页面开发中,我们很注意一些基本的注入攻击,包括html代码,以及SQL注入攻击。其次,在我们的请求中,不仅仅增加了token,也会有签名sign来保证参数的一致,防止请求中有恶意的参数。