一、简介
跨站脚本(cross site script)为了避免与样式css混淆,所以简称为XSS。
XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
XSS是一种经常出现在web应用中的计算机安全漏洞,也是web中最主流的攻击方式。
二、原因解析
主要原因:过于信任客户端提交的数据!
解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。
进一步分析细节:
客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了。那么攻击者就可以肆无忌惮地展开攻击啦。
因此我们绝不可以信任任何客户端提交的数据!!!
三、XSS攻击分类
1、反射型xss攻击
又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。
2、存贮型xss攻击
又称为持久型跨站点脚本,它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,因为每当用户打开页面,查看内容时脚本将自动执行。
3、DOMBasedXSS(基于dom的跨站点脚本攻击)
基于DOM的XSS有时也称为type0XSS。当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。
通过修改页面的DOM节点形成的XSS,称之为DOMBasedXSS
前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location 或document.URL 或 document.referrer获取数据(或者任何其他攻击者可以修改的对象)。
四、XSS漏洞修复
XSS漏洞的起因就是没有对用户提交的数据进行严格的过滤处理。因此在思考解决XSS漏洞的时候,我们应该重点把握如何才能更好的将用户提交的数据进行安全过滤。
1、html实体
在html中有些字符,像(<)这类的,对HTML(标准通用标记语言下的一个应用)来说是有特殊意义的,所以这些字符是不允许在文本中使用的。要在HTML中显示(<)这个字符,我们就必须使用实体字符。
html实体的存在是导致XSS漏洞的主要原因之一。
因此我们需要将这些实体全部转换为相应的实体编号。
2、HTML Encode
用户将数据提交上来的时候进行HTML编码,将相应的符号转换为实体名称再进行下一步的处理。
3、修复漏洞方针1、将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.
2、表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。
4、对数据进行Html Encode 处理
5、过滤或移除特殊的Html标签, 例如: <script>, <iframe> , < for <, > for >, " for
6、过滤JavaScript 事件的标签。例如 “onclick=”, “onfocus” 等等。
【特别注意:】
在有些应用中是允许html标签出现的,甚至是javascript代码出现。因此我们在过滤数据的时候需要仔细分析哪些数据是有特殊要求(例如输出需要html代码、javascript代码拼接、或者此表单直接允许使用等等),然后区别处理!
// HTML和实体相互转换
String.prototype.convertEntity=(function(){
// 字符实体表
let entity = {
quot : ‘”‘,
lt : ‘<‘,
gt : ‘>’,
amp : ‘&’,
nbsp : ‘ ‘
}
let entity_cover_key=”,entity_cover={};
for(let item in entity){
entity_cover_key+=entity[item];
entity_cover[entity[item]]=’&’+item+’;’;
}
return function(type){
if(type == 1){
return this.replace(/&([^&;]+);/g,function(a,b){
return typeof entity[b] === ‘string’ ? entity[b] : a;
})
}else{
let reg=new RegExp(‘[‘+entity_cover_key+’]’,’g’)
return this.replace(reg,function(c){
return entity_cover[c];
});
}
}
})()
console.log(‘"><& &asds;’.covert(1)); // “”><& ”
console.log(‘<div>121212</div>’.covert()); // <div>121212</div>
发表回复