XSS和XSRF

1,688 阅读4分钟

XSS

XSS(Cross-Site Scripting),跨站点脚本,缩写为css,为了区分CSS层叠样式表,所以缩写为XSS。

XSS攻击的表现形式,通常是在页面注入攻击脚本,来获取用户的Cookie和Session_id等关键信息,达到模拟用户,危害数据安全。

情景模拟:评论系统

前端代码:

<script>
    btn.addEventListener('click',()=>{
        const li=document.createElement('li')
        li.innerHTML=content  //content是用户的评论
        ul.appendChild(li)
    })
</script>

攻击者1号输入的content:

<script>console.log(Cookie)</script>

浏览器并不能区分这是恶意脚本,所以在加载这条评论时,就会执行这行代码。 这就是典型的存储型XSS攻击

攻击者2号输入的content:

http://xxx/input?content=<script>console.log(Cookie)</script>

用户好奇点击了地址,控制台打印出Cookie。 就是典型的用户主动提交型攻击,需要用户操作才会触发攻击,包括DOM型与XSS型,两者的区别就是,DOM型攻击由浏览器提取代码并执行,也就是由前由端负责。

后端防范XSS:

  1. 需要对输出的HTML内容进行充分转译(工作量会很大,转译内容复杂)
  2. 前后端分离,使用纯前端渲染,将数据和代码分离。

前端防范XSS:

  1. 避免将用户输入的数据直接用 .innerHTML、.outerHTML、document.write() 插入到页面,而应尽量使用 .textContent、.setAttribute() 等。

  2. 使用 Vue/React 技术栈,不使用 v-html/dangerouslySetInnerHTML 功能,就可以在前端避免 innerHTML、outerHTML 的 XSS 隐患。

  3. DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover 等,<a>标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,应该避免使用。

CSRF

CSRF(Cross-Site Request Forgery),跨站点请求伪造,也叫XSRF。

表现形式为:用户在登录A网站(正常网站)的同时,去访问了B网站(钓鱼网站),B网站发出请求访问A网站,这样B网站就可以使用到用户在A网站登录的Cookie,模拟用户进行一些列操作。 情景模拟:

  1. GET请求

用户进入第三方网站,然后就加载了下面图片

 <img src="http://a.com/accounts?amount=5200&for=attacker" > 

攻击者顺利的冒充用户完成了请求。

  1. POST请求 get请求是最简单的CSRF攻击,但post请求攻击也不难,只需要在用户进入第三方网站就自动发送一个Form表单提交就行了。
<form action="http://a.com/accounts" method=POST>
    <input name="user" value="dupe"/>
    <input name="amount" value="5200"/>
    <input name="for" value="attacker"/>
</form>
<script>
    document.getElementsByTagName('form')[0].submit()
</script>

就这样发送了一个http://a.com/accounts?user=dupe&amount=5200&for=attacker POST请求

  1. 点击链接 用户在携带Cookie进入第三方网站后,再诱导用户点击某个连接进行某个操作,这种通常不常见的,相比前两种就能成功,用不着需要用户进一步操作。

**总结:**CSRF攻击最明显的就是诱导用户点击第三方网站从而使用用户的Cookie,进行一系列操作,但并不能拿到用户的Cookie。

防范CSRF攻击:

  • 阻止不明外域的访问:

    • 同源检测:HTTP协议规定会在请求头显示Origin和Referer,后台对比发送请求的域名来确认是否为用户操作,对不信任的网址直接拒绝请求访问,但要过滤掉浏览器对网站主页的GET请求,所以主页不要以参数的形式请求。
    • Samesite Cookie:“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie
  • 提交时要求附加本域才能获取的信息:

    • CSRF Token:在用户登录时,服务端就生成一个随机数,一般放在Session里,伴随着用户进入的界面,当用户发送请求时,服务端就验证Session是否正确,来完成或阻止该项请求,目前使用最广的,缺点是每次请求就要进行Session对比,服务器负载大。
    • 双重Cookie验证:利用攻击者不能获取到Cookie的特点,对用户发送请求的子域名都携带上Cookie的其中的一个随机数值(如:_CsrfCookie='wdfyaueyfpio'),并将这段Cookie作为请求参数,这样就完成了统一的自动化拦截,缺点是每个子域名都使用同一个随机数Cookie,当某个子域名存在XSS漏洞,就可以修改Cookie模拟用户进行数据操作。