【校招VIP】浅谈前端安全——XSS CSRF

08月24日 收藏 0 评论 0 前端开发

【校招VIP】浅谈前端安全——XSS CSRF

转载声明:文章来源https://zhuanlan.zhihu.com/p/604989542

XSS 攻击(跨站脚本攻击)

一种代码注入方式,为了与 CSS 区分所以被称为 XSS。早期常见于网络论坛,起因是网站没有对用户的输入行严格的限制,使得攻击者可以将脚本上传到帖子让其他啊人在浏览到有恶意脚本的页面。其注入方式很简单,包括但不限于 JavaScript / VBScript / CSS / Flash 等;

XSS分类

根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM型三种。

存储区:恶意代码存放的位置;

插入点:由谁取得恶意代码,并插入到网站。

存储型

原理:攻击者将恶意代码(xss代码)提交(存储)至服务器(不管是数据库、内存还是文件系统),当受害者浏览包含次恶意代码的网页就会执行恶意代码。

攻击步骤:

1.攻击者将恶意代码提交到目标服务器中; 2.用户打开目标网站时,网站服务器取出包含恶意代码的数据,拼接在 HTML 中返回给浏览器; 3.用户浏览器接收到相应后解析执行,混在其中的恶意代码也被执行; 4.恶意代码窃取用户数据并发送到攻击者网站;或冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

常见场景:带有用户保存数据的网站,比如论坛发帖、商品评论、用户私信等。

反射型

原理:反射型 XSS,也叫非持久型 XSS,是指发生请求时,XSS 代码出现在请求 URL 中,作为参数提交到服务器中,服务器解析并响应。响应结果中包含 XSS 代码,最后浏览器解析并执行。

攻击步骤:

1.攻击者构造出特殊的 URL,其中包含恶意代码; 2.用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器; 3.用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行; 4.恶意代码窃取用户数据并发送到攻击者网站;或冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

常用场景:常见于通过 URL 传参的功能,比如网站搜索、跳转等。由于需要用户主动打开恶意的 URL 才能生效,因此攻击者往往会结合多种手段诱导用户点击。

DOM型

原理:同以上反射型XSS 攻击一样。

攻击步骤:

1.攻击者构造出特殊的 URL,其中包含恶意代码; 2.用户打开带有恶意代码的 URL; 3.用户浏览器接收到相应后解析执行,前端 js 取出 URL 中的恶意代码并执行; 4.恶意代码窃取用户数据并发送到攻击者网站;或冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

XSS类型小结

DOM型取出和执行恶意代码由浏览器完成,属于前端自身的安全漏洞;而其他两种则属于服务端的安全漏洞。

存储型,持续有效;其他两种非持续型。

XSS防御

xss攻击的两大要素:

攻击者提交恶意代码;

浏览器执行恶意代码。

常见防御手段:

1.输入过滤

在用户提交时,由前端过滤输入,然后提交到后端,是否可行? 答案是 不可行。一旦攻击者绕过前端过滤,直接构造请求,这样就可以提交恶意代码了。 后端在写入数据库前进行过滤,然后把 安全的 内容返回给前端,是否可行? 答案是 不可行。因为,在写入数据库前进行输入过滤虽然可以过滤掉一部分内容,但是用户的使用场景是很复杂的,我们很难判断出内容会输出到哪里,一旦用户输入的内容经过了转码,客户端就需要进行反转码,而前端不同的位置所需要的编码也是不同的。因此输入侧过滤虽然能够在某些情况下解决 XSS 问题,但是会引入很大的不确定性和乱码问题,所以应当尽量避免使用这种方法。 当然,对于明确的输入类型,例如数字、URL、电话号码、邮件地址等内容,进行输入过滤还是必要的。

2.防止执行恶意代码

存储型和反射型XSS 都是在服务端取出恶意代码后,插入到响应 HTML 中,攻击者可以编写的数据 被内嵌到 代码 中,被浏览器执行。

预防这两种漏洞,有两种常见的做法:

改成纯前端渲染,把代码和数据分隔开;

对 HTML 做充分转义。

前端渲染:目前主流框架采用的 SPA 的方式,我们会明确告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会轻易被欺骗,执行与其外的代码。

但是对于有高性能要求,或者是有 seo 需求的页面,仍然要面对拼接 HTML 的问题。

转义:如果拼接 HTML 是必要的,就需要采用合适的转义库对 HTML 模版的各处插入点进行充分的转义。 常见的模版引擎有 ejs 等,对于 HTML 转义通常只有一个规则,就是把 & < > " ' / 这几个字符转义掉。确实可以起到一定的防护作用,但还不够完善。

3.拒绝危险输入(针对DOM型 XSS 攻击)

在使用 .innerHTML、.outerHTML、document.write() 是要特别小心,不要把不可信的数据作为 HTML 插入到网页,尽量使用 .textContent、.setAttribute() 等。 如果是使用 Vue / React 时,不要使用 v-html / dangerouslySetInnerHTML ,在前端避免 innerHTML、outerHTML 的 XSS 隐患; DOM 中的内联事件监听器,如 location、onclick、onerror、onload,<a> 标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等都能把字符串作为代码运行,如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,务必谨慎使用。#### 4.其他XSS防范措施

1.输入内容长度控制

对于不受信任的输入,都应该先定一个合理的长度。虽然无法完全防止 XSS 的发生,但是可以增加 XSS 攻击的难度。

2.HttpOnly

对敏感的 cookie 设置 HttpOnly,禁止 JavaScript 访问这些信息,攻击者在完成 XSS 攻击后也无法窃取敏感信息。

3.内容安全策略(Content Security Policy,CSP)

CSP 在 XSS 的防范中可以起到以下的作用:

禁止加载外域代码,防止复杂的攻击逻辑;
禁止外域提交,网站被攻击后,用户的数据不会泄漏到外域;
禁止内联脚本执行;
禁止未授权的脚本执行;
合理使用上报可以及时发现 XSS,利于尽快修复问题。

可以使用以下两种方式开启内容安全策略:
HTTP Header 中的 Content-Security-Policy
<meta http-equiv="Content-Security-Policy"

CSRF攻击(跨站请求伪造)

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

CSRF攻击流程

1.受害者登录网站A,保留了登录凭证(cookie); 2.攻击者诱导受害者访问危险网站B; 3.危险网站B向网站A发送一个正常的请求,浏览器会默认携带存放在网站A下的 cookie; 4.网站A在接收到请求后,对请求进行验证,确认是受害者的凭证,误以为是受害者自己发送的请求; 5.网站A以受害者的名义,执行了危险请求中请求的操作。

CSRF分类

GET 类型的 CSRF

GET 类型的 CSRF 实现方式非常简单,只需要一个普通的 HTTP 请求,一般会放在图片等资源里面,受害者在打开危险网站后,危险网站的图片加载就发出了一个危险的 GET 请求,这样就完成了一个 GET 类型的 CSRF 攻击。

POST 类型的 CSRF

这种方式通常会使用一个自动提交的表单。当访问该页面时,表单会自动提交,相当于模拟用户完成了一个 POST 操作。POST 类型的攻击通常会比 GET 类型的更加严格一点,但仍并不复杂,所以后端的接口并不能将安全寄托在仅允许 POST 上面。

链接类型的 CSRF

这种方式并不常见,实现思路和 GET 类型一致,但是需要用户手动点击才能触发,因此攻击者通常会以广告的形式诱导用户中招。

CSRF防御:

CSRF的两个特点:

发生在第三方域名;

攻击者不能获取 cookie 信息,只能使用。

常见防御手段:

1.同源检测

既然大多数 CSRF 都发生在第三方网站,那么我们就直接禁止外域对我们发起的请求:

使用 Origin Header 确定来源域名:在部分与 CSRF 相关的请求中,请求头不会携带 Origin 字段,如果 Origin 字段存在则可以使用它来确定来源域名;

使用 Referer Header 来确定来源域名:根据 HTTP 协议,在请求的头部会有一个 Referer 字段,记录了请求的来源地址。

补充:Origin Header 与 Referer Header的区别:

Origin 指示了请求来自于哪个站点,只有服务器名,不包含路径信息;

Referer 指示了请求来自于哪个具体页面,包含服务器名和路径的详细URL;

2.CSRF Token

CSRF 的另一个特征是攻击者无法直接窃取用户的信息,仅仅是冒用而已。而 CSRF 之所以能成功,是因为服务器误把攻击者发送的请求当成用户自己的请求。那么我们可以要求所有的用户请求都携带一个 CSRF 无法获取到的 Token,服务器判断 Token 是否正确,从而将正常的请求和攻击的请求区分开。

实现步骤:

1.将 CSRF Token 输出到页面; 2.页面提交的请求携带这个 Token; 3.服务器验证 Token 是否正确。

3.双重 Cookie 验证

原理和 Token 相似,在请求接口时,在请求参数中附带上对应的 cookie,服务端在接收到请求时对参数中的 cookie 和 cookie 中的值进行对比判断是否为攻击请求。

4.Samesite Cookie 属性

Google起草了一份草案来改进HTTP协议,那就是为Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie,Samesite 有两个属性值:

Samesite=Strict: 这种称为严格模式,表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie

Samesite=Lax: 这种称为宽松模式,比 Strict 放宽了点限制,假如这个请求是这种请求且同时是个GET请求,则这个Cookie可以作为第三方Cookie。

大白话总结: 总的来说XSS攻击侧重与代码注入,或者窃取cookie等信息去发起攻击;CSRF侧重与盗用用户的登陆状态,因为它无法直接获取只能盗用。

C 0条回复 评论

帖子还没人回复快来抢沙发