什么是json
JSON(JavaS
官方网站: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等内置组建(如activeX、ajax)等请求获取json数据,如由XMLHttpRequest 得到的文本格式,可通过ev 通过ev httpRequest = getHttpRequest() //get aa.json var userInfo = ev 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
step1 用户A通过修改会员信息,伪造攻击脚步,name:<img src=javas 提交至web服务器 step2 json数据格式(vm模板): var userInfo = {"name":"$name"}; step3 用户A把json地址发给用户B,用户B在不知情的情况下(用浏览器)打开 var userInfo = {"name":="<img src=javas 结果:用户A伪造的攻击脚步:alert(1) 在用户B的浏览器解析并执行 |
攻击原理场景2
step1 用户A通过修改会员信息,伪造攻击脚步,name:"};alert(2);{" 提交至web服务器 step2 json.vm 模板内容: var userInfo = {"name":"$name"}; userinfo.vm 模板内容: <script src="json.vm"></script> <script> dispalayName(userInfo.name); </script> step3 用户B打开userinfo.vm查看用户A的信息:userinfo.vm?userid=b json.vm渲染结果: var userInfo = {"name":""};alert(2);{""}; 结果:用户A伪造的攻击脚步:alert(2) 被浏览者B的浏览器解析并执行 |
攻击原理场景3(html dom)
step1 用户A通过修改会员信息,伪造攻击脚步,name:<img src=vbscript:msgbox(0)> 提交至web服务器 step2 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> step3 用户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方式,分别为javas
1。通常情况下采用采用:javas
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之后,就不能作为javas
3。解析javas
附
javas
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("\\"); } else if (c < 0x1000) {// len == 3 buffer.append("\\"); } 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,"&");
s = s.replace(/</g,"<");
s = s.replace(/>/g,">");
s = s.replace(/ /g," ");
s = s.replace(/\'/g,"'");
s = s.replace(/\"/g,""");
return s;
}