前端安全
XSS(Cross Site Scripting)跨站脚本攻击
跨网站指令码(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程式的安全漏洞攻击,是代码注入的一种。它允许恶意使用者将程式码注入到网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了 HTML 以及使用者端脚本语言。
XSS 分为三种:反射型,存储型和 DOM-based
攻击方式
XSS 通过修改 HTML 节点或者执行 JS 代码来攻击网站。
例如:某个搜索功能,通过 URL 获取某些参数
<!-- http://www.domain.com?name=<script>alert(1)</script> -->
<div>{{name}}</div>
2
当执行搜素操作时,URL 中的 JS 代码会被执行,这样,页面中就会凭空多出了一弹框。
那如果是获取 cookie 然后发给黑客服务器呢?是不是就有很大的安全隐患了。
根据攻击来源,XSS 攻击可以分为:
- 存储型
- 反射型
- DOM 型
储存型
储存型 XSS 的攻击步骤:
- 攻击者将恶意代码提交到目标网站的数据库中
- 当用户打开目标网站时,网站服务端将恶意代码取出后,然后返回给浏览器。
- 浏览器执行恶意代码
这种攻击常见于保存用户数据的网站,如论坛发帖,商品评论等。
反射型
反射型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL 请求,其中包含恶意代码。
- 用户打开带有恶意代码的 URL,浏览器执行恶意代码。
反射型和储存型的区别:
- 储存型 XSS 的恶意代码放在数据里,反射型 XSS 的恶意代码放在 URL 里。
- 反射型 XSS 漏洞常见于 URL 传递参数的功能,如搜索,跳转
- 储存型 XSS 常见于通过用户提交的内容,如论坛留言,评论等
DOM 型 XSS
DOM 型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL,其中包含恶意代码
- 用户打开带有恶意代码的 URL
- 用户浏览器接受到响应后解析执行,前端 JavaScript 去除 URL 中的恶意代码并执行
- 恶意代码窃取用户数据并且发送到攻击者的网站,或者冒充用户行为完成恶意操作。
DOM 型 XSS 与前两种 XSS 的区别:
DOM 型 XSS 攻击中,取出和执行恶意代码都由浏览器端完成,是 JavaScript 自身的安全漏铜,而其他两种 XSS 都是服务端的漏铜。
防御方式
通过前面的介绍,看到 XSS 攻击的两大因素:
- 攻击者提交恶意代码
- 浏览器执行恶意代码
针对第一个要素,在用户输入的内容时进行过滤掉恶意代码。
针对第二个,则应该是在后端写入数据库时,对数据进行过滤。
前端处理的方式可以使用字符串替换的方法,例如:
function escape(str) {
str = str.replace(/&/g, "&");
str = str.replace(/</g, "<");
str = str.replace(/>/g, ">");
str = str.replace(/"/g, "&quto;");
str = str.replace(/'/g, "'");
str = str.replace(/`/g, "`");
str = str.replace(/\//g, "/");
return str;
}
2
3
4
5
6
7
8
9
10
上面的函数就可以将恶意代码进行转译。
也可以借助js-xssopen in new window来实现。
通过以上我们可以得出,用户输入不可信,所以使用一些 API 时需要各位的注意,比如.innerHTML、outerHTML、document.write,还有一些框架的 API,比如 Vue 的 v-html 等,使用时都需要谨慎一些。
CSRF(Cross-site request forgery)跨站请求伪造
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求
简单来说,CSRF 就是利用用户的登录态发起恶意请求。
攻击方式
CSRF 攻击流程:
- 受害者登录 a.com,并保留了登录凭证(cookie)’
- 攻击者引诱受害者访问 b.com
- b.com 向 a.com 发送一个请求:a.com?act=xx,会默认携带 a.com 的 cookie
- a.com 收到请求后,会执行相应的操作。
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作。
POST 攻击
<form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>
2
3
4
5
6
这是一个自动提交表单的 POST 请求,当用户访问该页面时,表单会自动提交,然后模拟用户完成一个 POST 操作。
GET 攻击
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
重磅消息!!
<a/>
// 也可以使用img的url
2
3
4
这种需要用户点击某个链接,然后自动请求某个网站模拟用户的操作。
CSRF 的特点
- 攻击一般发生在第三方网站,而不是被攻击的网站,被共计的网站无法防止攻击发生。
- 攻击利用受害者在被攻击网站的登录凭证(cookie),冒充受害者进行各种操作,而不是窃取数据。
- 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”
- 跨站请求可以用各种方式:如图片 URL、超链接、CORS、Form 表单提交等。
CSRF 的防御
CSRF 通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对 CSRF 的防护能力来提升安全性。
防止 CSRF 的常用方式如下:
阻止不明外域的访问
- 同源检测:通过 Http header Referer 判断是否是第三方网站发起的请求
SameSite:可以对 Cookie 设置 SameSite 属性,该设置 Cookie 不随着跨域请求发送,该属性可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。
token
- CSRF 攻击的基础是受害者在被攻击网站的登录态(coolie),而是用 token 可以防止这个问题,因为 token 不会自动携带,而是需要手动设置 header。
SQL 注入攻击
Sql 注入攻击,是通过将恶意的 SQL 语句插入到应用的输入参数中,在后台的服务器将 SQL 服务器上解析并执行的攻击。
攻击流程
- 找出 SQL 漏洞的注入点
- 判断数据库的类型和版本
- 猜解用户名和密码以及 web 后台管理入口
- 入侵和破坏
预防方式如下
- 严格检查输入变量的类型和格式
- 将 SQL 语句进行转译和过滤处理
- 对访问数据库的应用采用防火墙
密码安全
对于需要储存密码的地方,需要对密码进行加密。
加盐
对于密码储存来说,必然是不能使用明文密码储存在数据库中的。否则一旦泄露,会对用户造成极大的损失。
并且不建议只对密码单纯的通过加密算法加密,因为存在彩虹表的关系。
// 加盐也就是给原密码添加字符串,增加原密码长度
sha256(sha1(md5(salt + password + salt)));
2
但是加盐也不能阻止被人盗号,只能确保不会暴露用户的真实密码,一旦攻击者得到用户的账号,就可以通过暴露方式破解密码。
对于暴力破解(穷举)这种情况,通常使用验证码、增加延迟验证时间、限制验证次数来制止。
并且一旦用户输入了错误的密码,也不能直接提示输错密码,而是提示账号或密码错误。