随着互联网的快速发展和前端的多样性,浏览器已经成一种十分重要的上网工具,也是要有越来越多的交互操作需要浏览器来支持,所以针对浏览器的安全问题也越来越重要。
浏览器安全 其实是受 同源策略(同域名、同端口、同协议名)保护的,但是 <script>、<img>、<iframe>、<link> 等标签都可以跨域加载资源,而不受同源策略的限制。
1》这些带 ”src” 属性的标签每次加载时,浏览器会发起一次 GET 请求。
2》通过 src 属性加载的资源,浏览器限制了 javascript 的权限,使其不能读、写返回的内容。
常见的 六大安全问题有:XSS、CSRF、点击劫持、URL 跳转漏洞、SQL 注入、OS 命令注入攻击
===1.XSS===
XSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS 重叠,所以只能叫 XSS。
XSS 的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览该页之时,嵌入其中 Web 里面的脚本代码会被执行,从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的。
1. 非持久型 XSS(反射型 XSS)
一般是通过给别人发送 带有恶意脚本代码参数的 URL,当 URL 地址被打开时,特有的恶意代码参数被 HTML 解析、执行。
非持久型 XSS 漏洞攻击有以下几点特征:
1> 即时性,不经过服务器存储,直接通过 HTTP 的 GET 和 POST 请求就能完成一次攻击,拿到用户隐私数据。
2> 攻击者需要诱骗点击, 必须要通过用户点击链接才能发起
3> 反馈率低,所以较难发现和响应修复
4> 盗取用户敏感保密信息
2. 持久型 XSS(存储型 XSS)
持久型 XSS 漏洞,一般存在于 Form 表单提交等交互功能 ,如文章留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入 数据库持久保存 ,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。
持久型 XSS 有以下几个特点:
1. 持久性,植入在数据库中
2. 盗取用户敏感私密信息
3. 危害面广
如何防御?
1》设置白名单 CSP
通常可以通过两种方式来开启 CSP:
设置 HTTP Header 中的 Content-Security-Policy
设置 meta 标签的方式 <meta http-equiv=”Content-Security-Policy”>
Content-Security-Policy: default-src ‘self’ // 只允许加载本站资源
Content-Security-Policy: img-src https://* // 只允许加载 HTTPS 协议图片
Content-Security-Policy: child-src ‘none’ // 允许加载任何来源框架
2》用户的输入永远不可信任的,最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义
3》HttpOnly Cookie。
这是预防 XSS 攻击窃取用户 cookie 最有效的防御手段。Web 应用程序在设置 cookie 时,将其属性设为 HttpOnly,就可以避免该网页的 cookie 被客户端恶意 JavaScript 窃取,保护用户 cookie 信息。
===2.CSRF===
CSRF(Cross Site Request Forgery),即跨站请求伪造,是一种常见的 Web 攻击,它利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作。
如何防御?
1》可以对 Cookie 设置 SameSite 属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都 兼容。
2》通过 Referer 限制!Referer 信息告诉服务器是 从哪个页面链接 过来的
3》目前比较完善的解决方案是加入Anti-CSRF-Token, 即发送请求时在 HTTP 请求中以参数的形式加入一个随机产生的 token,服务器读取浏览器当前域 cookie 中这个 token 值,进行比较校验。
4》验证码操作,体验上不是很好
===3. 点击劫持 ===
通过 iframe 透明化,漏出来一个按钮,诱惑用户点击。
如何防御?
1》X-FRAME-OPTIONS 是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击。X-FRAME-OPTIONS 有 3 个值可选:
DENY,表示页面不允许通过 iframe 的方式展示
SAMEORIGIN,表示页面可以在相同域名下通过 iframe 的方式展示
ALLOW-FROM,表示页面可以在指定来源的 iframe 中展示
2》通过 js 的方法判断,来隐藏 iframe 显示的页面。
<script>
if (self == top) {var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {top.location = self.location}
</script>
===4.url 跳转漏洞 ===
借助未验证的 URL 跳转,将应用程序引导到不安全的第三方区域,从而导致的安全问题。
1》referer 的限制
如果确定传递 URL 参数进入的来源,我们可以通过该方式实现安全限制,保证该 URL 的有效性,避免恶意用户自己生成跳转链接
2》加入有效性验证 Token
我们保证所有生成的链接都是来自于我们可信域的,通过在生成的链接里加入用户不可控的 Token 对生成的链接进行校验,可以避免用户生成自己的恶意链接从而被利用,但是如果功能本身要求比较开放,可能导致有一定的限制。
===5.SQL 注入 ===
SQL 注入的本质: 数据和代码未分离,即数据当做了代码来执行。
有可能会造成 获取数据库信息 、 管理员后台用户名和密码 、 读取服务器敏感文件 等问题,甚至修改数据库内容。
如何防御?
1》严格限制 Web 应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害
2》后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。
3》对进入数据库的特殊字符(’,”,,<,>,&,,; 等)进行转义处理,或编码转换 *。基本上所有的后端语言都有对字符串进行转义处理的方法,比如 lodash 的 lodash._escapehtmlchar 库。
4》所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。例如 Node.js 中的 mysqljs 库的 query 方法中的 ? 占位参数。
===6.OS 命令注入攻击 ===
OS 命令注入攻击指通过 Web 应用,执行非法的操作系统命令达到攻击的目的。
如何防御?
1》后端对前端提交内容进行规则限制(比如正则表达式)。
2》在调用系统命令前对所有传入参数进行命令行参数转义过滤。
3》不要直接拼接命令语句,借助一些工具做拼接、转义预处理,例如 Node.js 的 shell-escape npm 包