预防XSS——后端HttpUtility.HtmlEncode,AntiXssEncoder.HtmlEncode方法;前端htmlencode,htmldecode,JavaScriptEncode

注意: 在.Net MVC中通过前端页面绑定Model变量的方式一般不需要另外处理Model变量中的xss问题,内部已经自动避免了xss问题,所以用Model也是一种处理xss的方案。

另外,有种情况是Ajax Post 提交参数的值中带有 html 标签不能提交到后端( ASP NET ): 解决方法参考本人之前的博文http://t.csdn.cn/JKKU7

在后端防止XSS攻击(推荐):

C#后端处理:

用以下其中一个方法可解决:
System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode方法
或者System.Web.HttpUtility.HtmlEncode方法。
比如: System.Web.HttpUtility.HtmlEncode(“D ; |"a;”) 即可转换为 “D ; |"a;”
方法具体参数可以查看官网MSDN。

以下是在前端避免XSS攻击使用的方法

javascript另类方法高效实现htmlencode()与htmldecode()函数

先看下项目中的应用:
预防XSS——后端HttpUtility.HtmlEncode,AntiXssEncoder.HtmlEncode方法;前端htmlencode,htmldecode,JavaScriptEncode_第1张图片

转自: https://blog.csdn.net/cuixiping/article/details/7846806

最常见的做法是采用正则表达式替换的方法,将特殊字符如 < > & 等进行替换,htmlencode的时候这样替换还比较容易,但发过来htmldecode的时候就不一定好用了,因为需要反转的情况很多,出了常见的<>&以外,还有 ©"®等数十个字符实体,还有AB中文或者中文之类以字符的Unicode编码的十进制或16进制表示的转义,难以全部列举,用逐个替换不仅代码冗长而且低效,还容易漏掉某些字符。

代码如下:

function htmlencode(s){
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(s));
    return div.innerHTML;
}
function htmldecode(s){
    var div = document.createElement('div');
    div.innerHTML = s;
    return div.innerText || div.textContent;
}

相当简洁!

编码原理就是创建TextNode节点,附加到容器中,再取容器的innerHTML.

解码原理是将字符串赋給容器的innerHTML,再取innerText或textContent.

测试一下:

//测试
document.onclick = function (){
    //<p> & </p>
    alert(htmlencode('

&

'
)); //

& © ABC 中文 中文

alert(htmldecode('<p> & © ABC 中文 中文 </p>')); }

效果不错。
htmldecode对入参有要求,如果入参不是合法的encode后的结果,可能无法得到预期结果。

我在google搜索,在cnblogs找到一篇和我一样思路的,原来已经有别人这样想了=||=,不过他的htmldecode代码有错误。

以下方式比较繁琐(内容只做了解):

转自: https://www.cnblogs.com/lovesong/p/5211667.html

在数据添加到DOM时候,我们可以需要对内容进行HtmlEncode或JavaScriptEncode,以预防XSS攻击。

JavaScriptEncode

使用“\”对特殊字符进行转义,除数字字母之外,小于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;
}

HtmlEncode

将字符转换成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 "
"
; 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; } } } }

Test

<button onclick='alert("1\x29\x3balert\x282\u54c8\u54c8\x29")'>测试JavaScriptEncode值button>
<div><script>alert('1' /);</script>div>

这些编码后的内容都能在页面上显示正常。

番外

还有人弄了简单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(/,"<");
        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;
    }
};

你可能感兴趣的:(笔记,Javascript,xss,前端,.net)