随着互联网的发达,各种WEB应用也变得越来越复杂,满足了用户的各种需求,但是随之而来的就是各种网络安全的问题,这篇文章主要给大家介绍了关于前端常见的安全问题以及防范措施的相关资料,需要的朋友可以参考下
随着互联网的高速发展,信息安全问题已经成为行业最为关注的焦点之一。总的来说安全是很复杂的一个领域,在移动互联网时代,前端人员除了传统的 XSS、CSRF 等安全问题之外,还时常遭遇网络劫持、非法调用 Hybrid API 等新型安全问题。这篇文章会介绍一些常见的安全问题及如何防范的内容,在当下其实安全问题越来越重要,已经逐渐成为前端开发必备的技能了。
Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
为了和 CSS 区分,这里把攻击的第一个字母改成了 X,于是叫做 XSS。
一般可以通过三种方式来注入恶意脚本:
顾名思义,恶意 JavaScript 脚本属于用户发送给网站请求中的一部分,随后网站又将这部分返回给用户,恶意脚本在页面中被执行。一般发生在前后端一体的应用中,服务端逻辑会改变最终的网页代码。
反射型 XSS 的攻击步骤:
目前更流行前后端分离的项目,反射型 XSS 无用武之地。 但这种攻击不需要经过服务器,我们知道,网页本身的 JavaScript 也是可以改变 HTML 的,黑客正是利用这一点来实现插入恶意脚本。
基于DOM 的 XSS 攻击步骤:
反射型 XSS 的攻击步骤:
又叫持久型 XSS,顾名思义,黑客将恶意 JavaScript 脚本长期保存在服务端数据库中,用户一旦访问相关页面数据,恶意脚本就会被执行。常见于搜索、微博、社区贴吧评论等。
存储型 XSS 的攻击步骤:
三者的区别:
反射型的 XSS 的恶意脚本存在 URL 里,存储型 XSS 的恶意代码存在数据库里。
反射型 XSS 攻击常见于通过 URL 传递参数的功能,如网站搜索、跳转等。
存储型XSS攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
而基于DOM的XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,其他两种 XSS 都属于服务端的安全漏洞。
XSS的攻击方式就是想办法“教唆”用户的浏览器去执行一些这个网页中原本不存在的前端代码。我们常用的留言板就可以产生XSS攻击(持久性),我们知道留言板通常的任务就是把用户留言的内容展示出来。正常情况下,用户的留言都是正常的语言文字,留言板显示的内容也就没毛病。然而这个时候如果有人不按套路出牌,在留言内容中丢进去一行:
那么留言板界面的网页代码就会变成形如以下:
那么这个时候问题就来了,当浏览器解析到用户输入的代码那一行时会发生什么呢?
答案很显然,浏览器并不知道这些代码改变了原本程序的意图,会照做弹出一个信息框。就像这样:
留言板
alert(“这是一个攻击”)
非持久 XSS攻击:攻击者注入的数据反映在响应中,一个典型的非持久性XSS攻击包含一个带XSS攻击向量的链接(每次攻击需要用户点击)
比如: 正常发送消息:
1.//www.test.com/message.php?send=Hello,World!
非正常发送消息: 接收者接收消息显示的时候将会弹出警告窗口
1.http://www.test.com/message.php?send=!
由上面对XSS攻击的介绍我们知道,XSS攻击主要有两大步骤:
所以我们可以针对这两点来制定防范措施:
(1)、输入过滤
在用户提交时,由前端过滤输入,然后提交到后端,这种方法不可行,因为攻击者可能绕过前端过滤,直接构造请求,提交恶意代码。一般在写入数据库前,后端对输入数据进行过滤。虽然输入侧过滤能够在某些情况下解决特定的 XSS 问题,但会引入很大的不确定性和乱码问题。在防范 XSS 攻击时应避免此类方法。
(2)、预防存储型和反射型 XSS 攻击
(3)、预防 DOM 型 XSS 攻击
DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。
在使用 .innerHTML、.outerHTML、document.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用.textContent、.setAttribute() 等。
如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患。
DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover 等,< a> 标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。
1
(4)、Content Security Policy
严格的 CSP 在 XSS 的防范中可以起到以下的作用:
使用 W3C 提出的 CSP (Content Security Policy,内容安全策略),定义域名白名单
(5)、其它措施
SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
1.寻找到SQL注入的位置
2.判断服务器类型和后台数据库类型
3.针对不同的服务器和数据库特点进行SQL注入攻击
比如,在一个登录界面,要求输入用户名和密码,可以这样输入实现免帐号登录:
用户名: ‘or 1 = 1 - -
密 码:
用户一旦点击登录,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了。这是为什么呢?
下面我们分析一下:从理论上说,后台认证程序中会有如下的SQL语句:
String sql = “select * from user_table where username=’ “+userName+” ’ and password=’ “+password+” ‘”;
因此,当输入了上面的用户名和密码,上面的SQL语句变成:
SELECT * FROM user_table WHERE username=‘‘or 1 = 1 –- and password=’’
分析上述SQL语句我们知道,username=‘ or 1=1 这个语句一定会成功;然后后面加两个 -,这意味着注释,它将后面的语句注释,让他们不起作用。这样,上述语句永远都能正确执行,用户轻易骗过系统,获取合法身份。
(1)、参数绑定
使用预编译手段,绑定参数是最好的防SQL注入的方法。目前许多的ORM框架及JDBC等都实现了SQL预编译和参数绑定功能,攻击者的恶意SQL会被当做SQL的参数而不是SQL命令被执行。在mybatis的mapper文件中,对于传递的参数我们一般是使用 # 和$来获取参数值。 当使用#时,变量是占位符 ,就是一般我们使用javajdbc的PrepareStatement时的占位符,所有可以防止sql注入;当使用 $ 时,变量就是直接追加在sql中,一般会有sql注入问题。
(2)、使用正则表达式过滤传入的参数
(3)、过滤的特殊字符及字符串
需要过滤的特殊字符及字符串有:
xp_cmdshell
/add
exec master.dbo.xp_cmdshell
net localgroup administrators
select
count
Asc
char
mid
‘’‘’
:
"
insert
delete from
drop table
update
truncate
from
%
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
典型的CSRF攻击是这样的:
1、GET类型的CSRF
GET类型的CSRF利用非常简单,只需要一个HTTP请求,一般会这样利用:
在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。
2、POST类型的CSRF
这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
POST类型的攻击通常比GET要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许POST上面。
3、链接类型的CSRF
链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击
重磅消息!!
CSRF的特点
由上面对CSRF的介绍我们知道了,CSRF通常发生在第三方域名,并且CSRF攻击者不能获取到受害者的cookie等信息,只是借用他们的登录状态来伪造请求。所以我们可以针对这两点来制定防范措施:
1、同源检测
既然CSRF大多来自第三方网站,那么我们就直接禁止第三方域名(或者不受信任的域名)对我们发起请求。
在HTTP协议中,每一个异步请求都会携带两个Header,用于标记来源域名:
- Origin Header
- Referer Header
这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。 服务器可以通过解析这两个Header中的域名,确定请求的来源域。同时服务器应该优先检测 Origin。为了安全考虑,相比于 Referer,Origin 只包含了域名而不带路径。
2、CSRF Token
(1).在浏览器向服务器发起请求时,服务器生成一个 CSRF Token。CSRF Token 其实就是服务器生成的随机字符串,然后将该字符串植入到返回的页面中,通常是放到表单的隐藏输入框中,这样能够很好的保护 CSRF Token 不被泄漏;
(2).当浏览器再次发送请求的时候,就需要携带这个 CSRF Token 值一起提交;
(3).服务器验证 CSRF Token 是否一致;从第三方网站发出的请求是无法获取用户页面中的 CSRF Token 值的。
3、给 Cookie 设置合适的 SameSite
当从 A 网站登录后,会从响应头中返回服务器设置的 Cookie 信息,而如果 Cookie 携带了 SameSite=strict 则表示完全禁用第三方站点请求头携带 Cookie,比如当从 B 网站请求 A 网站接口的时候,浏览器的请求头将不会携带该 Cookie。
(1).Samesite=Strict,这种称为严格模式,表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie
(2).Samesite=Lax,这种称为宽松模式,比 Strict 放宽了点限制:假如这个请求是这种请求(改变了当前页面或者打开了新页面)且同时是个GET请求,则这个Cookie可以作为第三方Cookie。(默认)
(3).None 任何情况下都会携带;