`
forrest-fengls
  • 浏览: 15814 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

json安全输出解决方案

阅读更多

最近找寻找json安全输出解决方案,方案基本上已经确定,发到博客给大家分享分享。

 

什么是json

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptStandard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式。

官方网站:http://www.json.org/

JSON是一种数据交换格式,可用于机器之间的数据传送。它只是表达数据,所以它本身是与安全无关的。使用JSON的系统安全与否,取决于该系统自身设计的好坏。JSON本身并不会引入安全隐患。  

json的应用场景

应用场景1

userInfo.json内容: var userInfo ={"name":"123"}
 userInfo.htm:
<script src="userInfo.json" ></script>
<script>
  alert(userInfo.name);
  alert(userInfo.length);
    alert(userInfo.substr(0));
</script>
 

应用场景2

userInfo.json内容:
{"name":"123"}

浏览器、flash等内置组建(如activeXajax)等请求获取json数据,如由XMLHttpRequest 得到的文本格式,可通过eval方法快速地转换成为有用的数据结构。

通过eval(json数据)解析成json对象,通过javascript 对象引用处理:

httpRequest = getHttpRequest()

//get aa.json

var userInfo = eval(httpRequest.responseText)

alert(userInfo.name);

 

应用场景3:

userInfo.json内容: var userInfo ={"name":"123"}

userInfo.htm:
<script src="userInfo.json" ></script>
<script>
  nameDiv.innerHTML=userInfo.name;
</script>
 

json攻击原理:

json http方式提供给外网访问,几乎人人都可以直接打开json地址,

如果用户自己写程序、工具或者使用获取http的命令(wget) 请求获取json数据,那么json只是作为一个文本数据交换使用,不存在安全隐患.

如果使用浏览器打开,那么它就相当于一个普通的html页面, 如果有恶意脚步等就会存在xss攻击的隐患.(xss攻击原里在这里不细讲)

   

攻击原理场景1

step
用户A通过修改会员信息,伪造攻击脚步,name:<img src=javascript:alert(1)>
提交至web服务器

step
json数据格式(vm模板):
var userInfo = {"name":"$name"};

step
用户A把json地址发给用户B,用户B在不知情的情况下(用浏览器)打开

var userInfo = {"name":="<img src=javascript:alert(1)>";

结果:用户A伪造的攻击脚步:alert(1) 在用户B的浏览器解析并执行

 

攻击原理场景2

step
用户A通过修改会员信息,伪造攻击脚步,name:"};alert(2);{"
提交至web服务器

step
json.vm 模板内容:
var userInfo = {"name":"$name"};

userinfo.vm  模板内容:
<script src="json.vm"></script>
<script>
  dispalayName(userInfo.name);
</script>

step
用户B打开userinfo.vm查看用户A的信息:userinfo.vm?userid=b
json.vm渲染结果:
var userInfo = {"name":""};alert(2);{""};

结果:用户A伪造的攻击脚步:alert(2) 被浏览者B的浏览器解析并执行


攻击原理场景3(html dom

step
用户A通过修改会员信息,伪造攻击脚步,name:<img src=vbscript:msgbox(0)>
提交至web服务器

step
json.vm 模板内容:
var userInfo = {"name":"$name"};

userinfo.vm  模板内容:
<div id="divName"></div>
<script src="json.vm"></script>
<script>
  .....
  document.getElementById("divName").innerHTML=userInfo.name;
</script>

step
用户B打开userinfo.vm查看用户A的信息:userinfo.vm?userid=a
json.vm渲染结果:
var userInfo = {"name":"<img src=vbscript:msgbox(0)>"};

结果:用户A伪造的攻击脚步:msgbox(0) 在执行innerHTML插入html的时候被执行
 

严格来讲,攻击原理场景3(html dom)不属于json安装输出范围

解决方案:

为了让用户伪造的脚步不被执行,有两种方案可以实现:

A、   过滤恶意脚步。 (我们不能确保所有的需求都允许过滤,因此不考虑这种方案)

B、对用户数据进行escape编码之后再输出,有两种escape方式,分别为javascript escapehtml escape

1。通常情况下采用采用:javascript escape 之后输出
javasceipt escape:alert(2)
 结果:alert\x282\x29
编码之后长度问题:
  "alert(2)".length==8
  "alert\x282\x29".length==8
  "alert\x282\x29".length==8
  "alert\x282\x29".substr(0,6)=="alert("

结果一样,编码之后不会对字符串长度、字符串截取产生影响.

2。对于html dom(应用场景3),采用html escape之后输出

 需要指出,html escape之后,就不能作为javascript字符窜进行长度,截取部分字符等操作,你能作为html dom插入操作:*.innerHTML=?

3。解析javascript方法eval()不太安全,使用yahoo yuiYAHOO.lang.JSON.parse 代替eval方法,具体请参见http://developer.yahoo.com/yui/json/


javascript escape

public static String escapedJavaScript(String string) {
        if (string == null || string.length() == 0) {
            return string;
        }
        StringBuilder buffer = new StringBuilder(string.length() << 1);
        String hex;
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);
 
            if (c < 127 && COMMON_ASCII[c]) {
                buffer.append(c);
            } else if (c <= 127) {
                hex = Integer.toHexString(c).toUpperCase();
                if (hex.length() < 2) {
                    buffer.append("\\x0");
                } else {
                    buffer.append("\\x");
                }
                buffer.append(hex);
            } else {
                // c > 0x7F // len >= 2
                hex = Integer.toHexString(c).toUpperCase();
                if (c < 0x100) {// len == 2
                    buffer.append("\\u00");
                } else if (c < 0x1000) {// len == 3
                    buffer.append("\\u0");
                } else {// len == 4
                    buffer.append("\\u");
                }
                buffer.append(hex);
            }
        }
        return buffer.toString();
}
 
 
Html escape:
function HTMLEscape(str)
   {
         var s = "";
         if(str.length == 0) return "";
         s    =    str.replace(/&/g,"&amp;");
         s    =    s.replace(/</g,"&lt;");
         s    =    s.replace(/>/g,"&gt;");
         s    =    s.replace(/ /g,"&nbsp;");
         s    =    s.replace(/\'/g,"&#39;");
         s    =    s.replace(/\"/g,"&quot;");
         return   s;
   }
 

 

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics