咱们多少应该据说过一些关于web安全
的问题吧,好比http劫持
、xss跨站脚本攻击
、corf跨站请求伪造
。当下好多的网站都没有实现https,web安全也是一个很是重要的话题。javascript
在用户的客户端与其要访问的服务器通过网络协议协调后,两者之间创建了一条专用的数据通道,用户端程序在系统中开放指定网络端口用于接收数据报文,服务器端将所有数据按指定网络协议规则进行分解打包,造成连续数据报文。html
用户端接收到所有报文后,按照协议标准来解包组合得到完整的网络数据。其中传输过程当中的每个数据包都有特定的标签,表示其来源、携带的数据属性以及要到何处,全部的数据包通过网络路径中ISP的路由器传输接力后,最终到达目的地,也就是客户端。前端
HTTP劫持 是在使用者与其目的网络服务所创建的专用数据通道中,监视特定数据信息,提示当知足设定的条件时,就会在正常的数据流中插入精心设计的网络数据报文,目的是让用户端程序解释“错误”的数据,并以弹出新窗口的形式在使用者界面展现宣传性广告或者直接显示某网站的内容。java
DNS 劫持就是经过劫持了 DNS 服务器,经过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,致使对该域名的访问由原IP地址转入到修改后的指定IP,其结果就是对特定的网址不能访问或访问的是假网址,从而实现窃取资料或者破坏原有正常服务的目的。web
DNS 劫持比之 HTTP 劫持 更加过度,简单说就是咱们请求的是 http://www.a.com/index.html
,直接被重定向了 http://www.b.com/index.html
。浏览器
xss就是攻击者利用漏洞,向咱们的页面注入一些攻击性脚本,当用户浏览页面的时候自动触发执行,从而达到攻击的目的。安全
HTTP 劫持 和 XSS 最终都是恶意代码在客户端,一般也就是用户浏览器端执行,咱们应该学会即便咱们被攻击了,咱们应该如何利用 Javascript 进行行之有效的前端防御。bash
页面被嵌入 iframe 中,重定向 iframe服务器
先来讲说咱们的页面被嵌入了 iframe 的状况。也就是,网络运营商为了尽量地减小植入广告对原有网站页面的影响,一般会经过把原有网站页面放置到一个和原页面相同大小的 iframe 里面去,那么就能够经过这个 iframe 来隔离广告代码对原有页面的影响。网络
这种状况还比较好处理,咱们只须要知道咱们的页面是否被嵌套在 iframe 中,若是是,则重定向外层页面到咱们的正常页面便可。
那么有没有方法知道咱们的页面当前存在于 iframe 中呢?有的,就是 window.self 与 window.top 。
window.self
返回一个指向当前 window 对象的引用。
window.top
返回窗口体系中的最顶层窗口的引用。
复制代码
// 咱们能够经过以下判断来区分是否外部被嵌套iframe
if (self != top) {
// 咱们的正常页面
var url = location.href;
// 父级页面重定向
top.location = url;
}
复制代码
内联事件及内联脚本拦截
列出一些比较常见的注入方式:
<a href="javascript:alert(1)" ></a>
<iframe src="javascript:alert(1)" />
<img src='x' onerror="alert(1)" />
<video src='x' onerror="alert(1)" ></video>
<div onclick="alert(1)" onmouseover="alert(2)" ><div>
复制代码
除去一些未列出来的很是少见生僻的注入方式,大部分都是 javascript:...
及内联事件 on*
。
咱们假设注入已经发生,那么有没有办法拦截这些内联事件与内联脚本的执行呢?
对于上面列出的 (1) (5) ,这种须要用户点击或者执行某种事件以后才执行的脚本,咱们是有办法进行防护的。
以拦截 javascript:
为例子。
// 创建关键词黑名单
var keywordBlackList = [
'xss',
'BAIDU_SSP__wrapper',
'BAIDU_DSPUI_FLOWBAR'
];
document.addEventListener('click', function(e) {
var code = "";
// 扫描 <a href="javascript:"> 的脚本
if (elem.tagName == 'A' && elem.protocol == 'javascript:') {
var code = elem.href.substr(11);
if (blackListMatch(keywordBlackList, code)) {
// 注销代码
elem.href = 'javascript:void(0)';
console.log('拦截可疑事件:' + code);
}
}
}, true);
/** * [黑名单匹配] * @param {[Array]} blackList [黑名单] * @param {[String]} value [须要验证的字符串] * @return {[Boolean]} [false -- 验证不经过,true -- 验证经过] */
function blackListMatch(blackList, value) {
var length = blackList.length,
i = 0;
for (; i < length; i++) {
// 创建黑名单正则
var reg = new RegExp(whiteList[i], 'i');
// 存在黑名单中,拦截
if (reg.test(value)) {
return true;
}
}
return false;
}
复制代码
静态脚本拦截
XSS 跨站脚本的精髓不在于“跨站”,在于“脚本”。
一般而言,攻击者或者运营商会向页面中注入一个<script>
脚本,具体操做都在脚本中实现,这种劫持方式只须要注入一次,有改动的话不须要每次都从新注入。 好比:
<div id="wrapper">
111
<script>alert('xss');</script>
</div>
复制代码
页面中若是有这么一段,那么页面会执行alert函数。
若是是:
<div id="wrapper">
<script>alert(1)</script>
</div>
复制代码
页面则不会执行。
因此最广泛的作法是转义输入输出的内容,对于引号,尖括号,斜杠进行转义
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
}
复制代码
咱们通常使用一个现成的工具:
XSS是一个用于对用户输入的内容进行过滤,以免遭受XSS攻击的模块 (什么是XSS攻击?)。主要用于论坛、博客、网上商店等等一些可容许用户录入页面排版、 格式控制相关的HTML的场景,xss模块经过白名单来控制容许的标签及相关的标签属性, 另外还提供了一系列的接口以便用户扩展,比其余同类模块更为灵活。