这个来自之前做的培训,删减了一些业务相关的,参考了很多资料(参考资料列表),谢谢前辈们,么么哒 :kissing_heart:
Web前端安全方面涵盖的内容较多,也是前端项目开发中必须要关注的一个重要部分。在Web站点开发中,如果没有很好的安全防护措施,不仅可能因为攻击者的恶意行为影响站点页面功能、泄露用户投权隐私,甚至还可能会直接带来用户经济上的损失。
安全当然不只是前端的事情,这里主要介绍和前端相关的一些安全知识。
XSS跨站脚本攻击(Cross Site Script,XSS攻击),通常指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。
XSS的本质是一种“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而产生了新的语义。
根据攻击脚本引入的位置,XSS可以分为三类:
反射型XSS非持久化,将用户输入的数据反射给浏览器,经过后端,不经过数据库。黑客需要诱使用户“点击”一个恶意链接,才能攻击成功。
存储型XSS
持久化,代码储存在数据库中,经过后端,经过数据库。如在个人信息或发表文章等地方,假如代码,如果没有过滤或过滤不严,那么这些代码将储存到数据库中,用户访问该页面的时候触发代码执行。
比如一个表单,输入用户签名,前端直接把签名内容展示在页面上,如果没有进行XSS处理,假设输入:
<script>alert(1)</script>复制代码浏览器显示用户签名的时候,可能就会触发弹框。注意这里的脚本只是演示,在攻击时,脚本可能会执行各种动作,比如获取Cookie或所有本地存储并发送到某处,打开一个非法网址等等。
DOM Based XSS通过修改页面的DOM节点形成的XSS,不经过后端。
比如前端直接通过获取URL参数渲染页面DOM:
http://localhost:8080/dvwa/vulnerabilities/xss_d/?default=English<script>alert(1)</script>
页面弹窗:
XSS攻击挑战:xss-game.appspot.com
解法: gist.github.com/pbssubhash/…
点击预览
防御方式一般使用对HTML字符编码转义来防范XSS,比如:
function HTMLEncode(str) { let s; if (str.length === 0) return ""; s = str.replace(/&/g, ">"); s = s.replace(/</g, "<"); s = s.replace(/>/g, ">"); s = s.replace(/ /g, " "); s = s.replace(/'/g, "'"); s = s.replace(/"/g, """); s = s.replace(/\n/g, "<br>"); return s; } function HTMLDecode(str) { let s; if (str.length === 0) return ""; s = str.replace(/>/g, "&"); s = s.replace(/</g, "<"); s = s.replace(/>/g, ">"); s = s.replace(/ /g, " "); s = s.replace(/'/g, "'"); s = s.replace(/"/g, "\""); s = s.replace(/<br>/g, "\n"); return s; }复制代码但是绕过过滤的方式有很多,比如:
data协议执行javascript:
<a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>复制代码Jsfuck:
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()复制代码深入游戏:prompt.ml/
建议使用成熟的库来防范,比如: github.com/leizongmin/…
保护好用户的Cookie,加上HttpOnly属性,加上了这个属性的Cookie字段,js是无法进行读写的。
前后端一定都要过滤,在界面显示用户输入的内容时要谨慎。
SQL注入SQL 注入就是指在输入的字符串中注入 SQL 语句,如果应用相信用户的输入而对输入的字符串没进行任何的过滤处理,那么这些注入进去的 SQL 语句就会被数据库误认为是正常的 SQL 语句而被执行。
比如后端代码:
$un = @$_POST['un']; $pw = @$_POST['pw']; // ... $sql = "select * from user where un='$un' and pw='$pw'";复制代码前端输入时,我们将un赋为admin,pw赋为' or '1'='1。则整个 SQL 语句会变为:
select * from user where un='admin' and pw='' or '1'='1'复制代码就成功绕过了身份验证。
SQL注入太知名,大家比较熟悉,这里不做过多介绍。
CSRFCSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
例如:
一个银行站点存在一个CSRF漏洞,用户A转账给B用户2000元,执行转账操作后会对银行发送一次请求: www.bank.com/money?use..… ,然后A用户就会把自己的2000元转到B的账户下。在发送这个请求给银行服务器时,服务器首先会验证这个请求是否为一个合法的session,并且用户A确认登陆才可以验证通过。
如果此时有一个恶意用户C想把A用户的钱转到自己的账户下,那么他可以构造 www.bank.com/money?use..… 这个请求,但是这个请求必须有A用户发出才可以生效,此时恶意用户C可以搭建一个自己的网站,在网站中写入如下代码: <img src="http://www.bank.com/money?user=A&num=2000&transfer=C">之后诱导A用户访问自己的网站,当A访问这个网站时,这个网站就会把img标签里的URL发给银行服务器,而此时除了这个请求以外,还会把A用户的cookie一起发到服务器,如果此时A用户的浏览器与银行的session没有过期,那么就会在A用户毫不知情的情况下执行转账给C的操作。
CSRF一般会用于以下场景:
1、对网站管理员进行攻击:诱骗管理员点击存在漏洞的链接,执行增加删除网站管理账户的操作,从而进行下一步渗透得到网站shell权限。
Discuz! X2.5 / X3 / X3.1 可CSRF删管理员账号
发帖插入 Discuz! 代码,其中修改uidarray可以删除多个指定用户:
php?frame=no&action=members&operation=clean&submit=1&uidarray=1&confirmed=yes" alt="前端技术演进(三):前端安全" />
复制代码
2、修改受害网站上的用户账户和数据:对账户密码进行重置,改邮箱绑定,修改个人资料、个人设置,删除用户发布的文章帖子等。
美丽说网CSRF重置任意用户帐号密码(已经拿到商家帐号证明)
3、账户劫持:修改密码处没有验证原有密码,无token验证,发送一个修改密码的链接即可。或者发送一个修改绑定邮箱的链接,再进行密码重置。
微信公众平台CSRF可导致公众账号被劫持
4、传播CSRF蠕虫进行大规模攻击:此类攻击发生的场景一般在SNS站点,批量关注、发微博、改个人资料处。
新浪微博CSRF之点我链接发微博(可蠕虫)
5、利用csrf进行拖库。
Discuz可CSRF脱裤
6、利用其他漏洞进行组合拳攻击。
防御方式1、使用验证码:
CSRF攻击一般都是在受害者不知情的情况下进行发起的,使用验证码可以有效的防止攻击,但是每次请求都要输入验证码会影响用户体验,所以通常只在用户登录注册,还有一些特定业务场景下使用,比如银行转账。如何使用验证码要根据业务和场景来决定。
2、验证http Referer:
http头中的referer字段记录了请求来源地址,比如从www.test.com 点击链接到m.test.com 之后,那么referer就是www.test.com 这个地址。攻击者在对受害者进行攻击的时候,是在攻击者自己的服务器上构建自己的恶意脚本,诱骗受害者点击,所以此时的referer值就是攻击者自己的URL地址。通过以上可知,CSRF攻击都是跨域发起的,所以在服务端针对referer字段验证是否属于安全可靠的域名,可在一定程度上有效防御此类攻击。
但是此类方法并非万无一失,在低版本存在漏洞的浏览器中,黑客可以篡改referer值。另一种情况是CSRF结合XSS进行攻击,此时就不需要跨域发起,也可以绕过referer验证。
3、使用token
当用户第一次进行登录的时候,客户端会通过用户名和密码去请求服务器登录,服务端在收到请求后会验证客户端传来的用户名和密码,如果验证通过,服务器就会签发一个token发给客户端,并且将token放到session或者报文中,客户端收到token后存储到本地,以后客户端只要每次请求服务器就要带上token,经过服务器验证通过后才会返回响应数据,否则报错。
CSRF攻击成功的前提条件是攻击者可以完全伪造出受害者的所有请求,而且请求中的验证信息都在cookie中,黑客只要使用用户的cookie通过安全验证就可以完成攻击。了解了这些之后,想要防止CSRF攻击,就要在http请求中放置黑客不可以伪造的信息,而且该信息不可以存在于cookie中,否则就无效。而token令牌最大的特点就是随机性,不可预测,并且不存在于cookie当中。
最后注意一点,如果在同域下存在XSS漏洞,那么这种使用toke