XSS跨站脚本攻击

一、简介

      跨站脚本攻击(cross site scripting),web应用最主流攻击方法;为了避免和层叠样式表(cascading style sheet)重名而简写成XSS。

1.1 成因

      系统太过于信任用户输入,而没有对其提交的数据进行转译处理或过滤,使得提交的数据中存在可执行代码并嵌入到web页面中。

1.2 危害

1. 盗取用户账号

2.控制敏感数据

3.非法转账

4.强制发送邮件

5.控制受害者机器向其他网站发起进攻

二、XSS种类

2.1 反射性

      又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。


2.2 持久性

      又称为持久型跨站点脚本,它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,因为每当用户打开页面,查看内容时脚本将自动执行。谷歌的orkut曾经就遭受到XSS。



三、XSS漏洞修复

      了解了XSS的起因和类型后,就可以寻找漏洞的修复方式了。笔者参考网友分享的各类技术贴后将预防方式分为三种,即:html预防,javascript预防。在数据添加到DOM时候,我们可以需要对内容进行HtmlEncode或JavaScriptEncode,以预防XSS攻击。   

3.1 javascriptEncoding

      使用“\”对特殊字符进行转义,除数字字母之外,小于127的字符编码使用16进制“\xHH”的方式进行编码,大于用unicode(非常严格模式)。

//使用“\”对特殊字符进行转义,除数字字母之外,小于127使用16进制“\xHH”的方式进行编码,大于用unicode(非常严格模式)。
var JavaScriptEncode = function(str){
     
    var hex=new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
        
    function changeTo16Hex(charCode){
        return "\\x" + charCode.charCodeAt(0).toString(16);
    }
    
    function encodeCharx(original) {
        
        var found = true;
        var thecharchar = original.charAt(0);
        var thechar = original.charCodeAt(0);
        switch(thecharchar) {
            case '\n': return "\\n"; break; //newline
            case '\r': return "\\r"; break; //Carriage return
            case '\'': return "\\'"; break;
            case '"': return "\\\""; break;
            case '\&': return "\\&"; break;
            case '\\': return "\\\\"; break;
            case '\t': return "\\t"; break;
            case '\b': return "\\b"; break;
            case '\f': return "\\f"; break;
            case '/': return "\\x2F"; break;
            case '<': return "\\x3C"; break;
            case '>': return "\\x3E"; break;
            default:
                found=false;
                break;
        }
        if(!found){
            if(thechar > 47 && thechar < 58){ //数字
                return original;
            }
            
            if(thechar > 64 && thechar < 91){ //大写字母
                return original;
            }

            if(thechar > 96 && thechar < 123){ //小写字母
                return original;
            }        
            
            if(thechar>127) { //大于127用unicode
                var c = thechar;
                var a4 = c%16;
                c = Math.floor(c/16); 
                var a3 = c%16;
                c = Math.floor(c/16);
                var a2 = c%16;
                c = Math.floor(c/16);
                var a1 = c%16;
                return "\\u"+hex[a1]+hex[a2]+hex[a3]+hex[a4]+"";        
            }
            else {
                return changeTo16Hex(original);
            }
            
        }
    }     
  
    var preescape = str;
    var escaped = "";
    var i=0;
    for(i=0; i < preescape.length; i++){
        escaped = escaped + encodeCharx(preescape.charAt(i));
    }
    return escaped;
}

3.2 htmlEncoding

将字符转换成HTMLEntites,以对抗XSS。

var HtmlEncode = function(str){
    var hex = new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
    var preescape = str;
    var escaped = "";
    for(var i = 0; i < preescape.length; i++){
        var p = preescape.charAt(i);
        escaped = escaped + escapeCharx(p);
    }
    
    return escaped;
                    
    function escapeCharx(original){
        var found=true;
        var thechar=original.charCodeAt(0);
        switch(thechar) {
            case 10: return "<br/>"; break; //newline
            case 32: return " "; break; //space
            case 34:return """; break; //"
            case 38:return "&"; break; //&
            case 39:return "'"; break; //'
            case 47:return "/"; break; // /
            case 60:return "<"; break; //<
            case 62:return ">"; break; //>
            case 198:return "Æ"; break;
            case 193:return "Á"; break;
            case 194:return "Â"; break; 
            case 192:return "À"; break; 
            case 197:return "Å"; break; 
            case 195:return "Ã"; break; 
            case 196:return "Ä"; break; 
            case 199:return "Ç"; break; 
            case 208:return "Ð"; break;
            case 201:return "É"; break; 
            case 202:return "Ê"; break; 
            case 200:return "È"; break; 
            case 203:return "Ë"; break;
            case 205:return "Í"; break;
            case 206:return "Î"; break; 
            case 204:return "Ì"; break; 
            case 207:return "Ï"; break;
            case 209:return "Ñ"; break; 
            case 211:return "Ó"; break;
            case 212:return "Ô"; break; 
            case 210:return "Ò"; break; 
            case 216:return "Ø"; break; 
            case 213:return "Õ"; break; 
            case 214:return "Ö"; break;
            case 222:return "Þ"; break; 
            case 218:return "Ú"; break; 
            case 219:return "Û"; break; 
            case 217:return "Ù"; break; 
            case 220:return "Ü"; break; 
            case 221:return "Ý"; break;
            case 225:return "á"; break; 
            case 226:return "â"; break; 
            case 230:return "æ"; break; 
            case 224:return "à"; break; 
            case 229:return "å"; break; 
            case 227:return "ã"; break; 
            case 228:return "ä"; break; 
            case 231:return "ç"; break; 
            case 233:return "é"; break;
            case 234:return "ê"; break; 
            case 232:return "è"; break; 
            case 240:return "ð"; break; 
            case 235:return "ë"; break; 
            case 237:return "í"; break; 
            case 238:return "î"; break; 
            case 236:return "ì"; break; 
            case 239:return "ï"; break; 
            case 241:return "ñ"; break; 
            case 243:return "ó"; break;
            case 244:return "ô"; break; 
            case 242:return "ò"; break; 
            case 248:return "ø"; break; 
            case 245:return "õ"; break;
            case 246:return "ö"; break; 
            case 223:return "ß"; break; 
            case 254:return "þ"; break; 
            case 250:return "ú"; break; 
            case 251:return "û"; break; 
            case 249:return "ù"; break; 
            case 252:return "ü"; break; 
            case 253:return "ý"; break; 
            case 255:return "ÿ"; break;
            case 162:return "¢"; break; 
            case '\r': break;
            default:
                found=false;
                break;
        }
        if(!found){
            if(thechar>127) {
                var c=thechar;
                var a4=c%16;
                c=Math.floor(c/16); 
                var a3=c%16;
                c=Math.floor(c/16);
                var a2=c%16;
                c=Math.floor(c/16);
                var a1=c%16;
                return "&#x"+hex[a1]+hex[a2]+hex[a3]+hex[a4]+";";        
            }
            else{
                return original;
            }
        }    
    }
}

      还有人弄了简单HtmlEncode,有两种方式。 1. 用浏览器内部转换器实现html转码(但我觉得这种方式有风险的,因为内部转换器可能有漏洞)。 2. 只转一部分html字符(这种方式不完整)。

var HtmlUtil = {
    htmlEncode:function (html){
        var temp = document.createElement ("div");
        (temp.textContent != undefined ) ? (temp.textContent = html) : (temp.innerText = html);
        var output = temp.innerHTML;
        temp = null;
        return output;
    },
    htmlDecode:function (text){
        var temp = document.createElement("div");
        temp.innerHTML = text;
        var output = temp.innerText || temp.textContent;
        temp = null;
        return output;
    },
    htmlEncodeByRegExp:function (str){
        var s = "";
        if(str.length == 0) return "";
        s = str.replace(/&/g,"&");
        s = s.replace(/</g,"<");
        s = s.replace(/>/g,">");
        s = s.replace(/ /g," ");
        s = s.replace(/\'/g,"'");
        s = s.replace(/\"/g,""");
        return s;
    },
    htmlDecodeByRegExp:function (str){
        var s = "";
        if(str.length == 0) return "";
        s = str.replace(/&/g,"&");
        s = s.replace(/</g,"<");
        s = s.replace(/>/g,">");
        s = s.replace(/ /g," ");
        s = s.replace(/'/g,"\'");
        s = s.replace(/"/g,"\"");
        return s;
    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值