一、XSS攻击

1.漏洞描述

XSS是跨站脚本攻击(Cross Site Scripting)的简称,之所以叫XSS而不是CSS那就是为了跟层叠样式表(Cascading Style Sheets,CSS)区别

恶意攻击者往web页面中插入恶意HTML代码,当用户浏览该web页面时,嵌入到该web页面的恶意HTML代码就会被执行,从而达到恶意攻击用户的特殊目的。其危害主要优窃取cookie、放蠕虫、网站钓鱼 …

2.防御策略

白名单控制允许的HTML标签及各标签的属性,通过自定义处理函数,可对任意标签及其属性进行处理,使用js-xss

js-xss库地址:https://jsxss.com/zh/index.html

js-xss使用方法:
Nodejs
1
$ npm install xss --save
1
2
var xss = require('xss');
console.log(xss('<a href="#" onclick="alert(/xss/)">click me</a>'));
在浏览器上使用
1
引入https://raw.github.com/leizongmin/js-xss/master/dist/xss.js
1
console.log(filterXSS('<a href="#" onclick="alert(/xss/)">click me</a>'));

二、CSRF跨站点请求伪造

1.漏洞描述

CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:

攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

2.防御策略

a)使用验证码

b)验证http Referer

c)在请求地址中添加 token 并验证

三、弱口令

1.漏洞描述

弱口令(weak password) 没有严格和准确的定义,通常认为容易被别人(他们有可能对你很了解)猜测到或被破解工具破解的口令均为弱口令。弱口令指的是仅包含简单数字和字母的口令,例如“123”、“abc”等,因为这样的口令很容易被别人破解,从而使用户的计算机面临风险,因此不推荐用户使用。

2.防御策略

a)设置密码长度8-32位,须包含数字、字母、符号至少两种或以上元素,正则表达式写法:

1
2
var reg = new RegExp('^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$).{8,32}')
reg.test('!@#abc123')

b)对关键密码或者关键数据使用crypto-js进行加密的处理:crypto-js加密配置

四、警惕iframe带来的风险

1.漏洞描述

前端页面需要用到第三方提供的页面组件,通常会以iframe的方式引入。典型的例子是使用iframe在页面上添加第三方提供的广告、天气预报、社交分享插件等等。

iframe在给我们的页面带来更多丰富的内容和能力的同时,也带来了不少的安全隐患。因为iframe中的内容是由第三方来提供的,默认情况下他们不受我们的控制,他们可以在iframe中运行JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端用户体验。

如果说iframe只是有可能会给用户体验带来影响,看似风险不大,那么如果iframe中的域名因为过期而被恶意攻击者抢注,或者第三方被黑客攻破,iframe中的内容被替换掉了,从而利用用户浏览器中的安全漏洞下载安装木马、恶意勒索软件等等,这问题可就大了。

2.防御策略

HTML5中,iframe有了一个叫做sandbox的安全属性,通过它可以对iframe的行为进行各种限制,充分实现“最小权限“原则。使用sandbox的最简单的方式就是只在iframe元素中添加上这个关键词就好,就像下面这样:

1
<iframe sandbox src="..."> ... </iframe>

sandbox还忠实的实现了“Secure By Default”原则,也就是说,如果你只是添加上这个属性而保持属性值为空,那么浏览器将会对iframe实施史上最严厉的调控限制,基本上来讲就是除了允许显示静态资源以外,其他什么都做不了。比如不准提交表单、不准弹窗、不准执行脚本等等,连Origin都会被强制重新分配一个唯一的值,换句话讲就是iframe中的页面访问它自己的服务器都会被算作跨域请求。

另外,sandbox也提供了丰富的配置参数,我们可以进行较为细粒度的控制。一些典型的参数如下:(设置为空时上面所有允许全部禁止)

参数 说明
allow-forms 允许iframe中提交form表单
allow-popups 允许iframe中弹出新的窗口或者标签页(例如,window.open(),showModalDialog(),target=”_blank”等等)
allow-scripts 允许iframe中执行JavaScript
allow-same-origin 允许iframe中的网页开启同源策略

五、点击劫持

1.漏洞描述

点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击在iframe页面的一些功能性按钮上。

2.防御策略

防御点击劫持:X-Frame-Options

X-Frame-Options HTTP响应头是用来给浏览器指示允许一个页面能否在<frame>、<iframe>、<object>中展现的标记

有三个可选的值

DENY:浏览器会拒绝当前页面加载任何frame页面(即使是相同域名的页面也不允许)
SAMEORIGIN:允许加载frame页面,但是frame页面的地址只能为同源域名下的页面
ALLOW-FROM:可以加载指定来源的frame页面(可以定义frame页面的地址)

浏览器兼容性

六、opener

1.漏洞描述

如果,你的网站上有一个链接,使用了 target=”_blank”,那么一旦用户点击这个链接并进入一个新的标签,新标签中的页面如果存在恶意代码,就可以将你的网站直接导航到一个虚假网站。此时,如果用户回到你的标签页,看到的就是被替换过的页面了。

比如:

1
2
// 1) HTML -> <a target='_blank' href='http://www.baidu.com'>
// 2) JS -> window.open('http://www.baidu.com')
  • 这两种方式看起来没有问题,但是存在漏洞。
  • 通过这两种方式打开的页面可以使用 window.opener 来访问源页面的 window 对象。
  • 场景:A 页面通过<a>或 window.open 方式,打开 B 页面。但是 B 页面存在恶意代码如下:
  • window.opener.location.replace('https://www.baidu.com') 【此代码仅针对打开新标签有效】
  • 此时,用户正在浏览新标签页,但是原来网站的标签页已经被导航到了百度页面。
  • 恶意网站可以伪造一个足以欺骗用户的页面,使得进行恶意破坏。
  • 即使在跨域状态下 opener 仍可以调用 location.replace 方法。

2.防御策略

a)<a target="_blank" href="">

1
2
3
4
5
6
7
8
<a target="_blank" href="" rel="noopener noreferrer nofollow">a标签跳转url</a>

<!--
通过 rel 属性进行控制:
noopener:会将 window.opener 置空,从而源标签页不会进行跳转(存在浏览器兼容问题)
noreferrer:兼容老浏览器/火狐。禁用HTTP头部Referer属性(后端方式)。
nofollow:SEO权重优化,详情见 https://blog.csdn.net/qq_33981438/article/details/80909881
-->

b)window.open()

1
2
3
4
5
6
7
 <button onclick='openurl("http://www.baidu.com")'>click跳转</button>

function openurl(url) {
var newTab = window.open();
newTab.opener = null;
newTab.location = url;
}

七、CDN劫持

1.漏洞描述

出于性能考虑,前端应用通常会把一些静态资源存放到CDN(Content Delivery Networks)上面,例如 js 脚本和 style 文件。这么做可以显著提高前端应用的访问速度,但与此同时却也隐含了一个新的安全风险。如果攻击者劫持了CDN,或者对CDN中的资源进行了污染,攻击者可以肆意篡改我们的前端页面,对用户实施攻击。

2.防御策略

现在的CDN以支持SRI为荣,script 和 link 标签有了新的属性 integrity,这个属性是为了防止校验资源完整性来判断是否被篡改。它通过 验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。
使用 SRI 需要两个条件:一是要保证 资源同域 或开启跨域,二是在<script>中 提供签名以供校验。

integrity 属性分为两个部分,第一部分是指定哈希值的生成算法(例:sha384),第二部分是经过编码的实际哈希值,两者之前用一个短横(-)来分隔

这个属性也存在兼容问题