测试用的是net.sf.json.JSONObject,大家也可以去试试其他JSONObject。
JSONObject json = null; json = new JSONObject(); json.put("code", 200); json.put("info", "tester"); json.put("msg", "success"); System.out.println(json); // 输出:{"code":200,"info":"tester","msg":"success"}
在这里info是一个String,所以,很多前端工程师可能会选择使用Stirng.replace方法转义or过滤特殊字符。
如果在info中注入{‘replace’:function(){alert(/xss/)}}呢?
json = new JSONObject(); json.put("code", 200); json.put("info", "{'replace':function(){alert(/xss/)}}"); json.put("msg", "success"); System.out.println(json); // 输出:{"code":200,"info":{"replace":function(){ alert(/xss/) }},"msg":"success"}
JSONObject在输出json串时,info会作为对象输出,并且其中嵌入replace方法,js在使用replace方法转义过滤时,也就调用了嵌入的replace方法。
可以根据不同的场景把info构造成不同的对象,也可以构造成数组[function(){alert(/xss/)}] 或者 简单的函数 function(){alert(/xss/)}
NOTE:这种方式在jQuery中行不通,jQuery会对json串的格式做检查,一般的ajax,还有jsonp可能会存在这种xss问题。
相关吐槽:
hehe 2013-06-21 1楼
这属于json hijack吗
hehe 2013-06-21
@hehe 我理解是转换对象的时候自定义的replace方法(xss)hijack了原有replace方法,是这个意思?
door2guest (2级) 2013-06-21
@hehe 可以这么理解。 这里重点是可以控制输出json的结构。
园长MM (1级) 2013-06-21 2楼
这跟用JSONOBJECT没什么关系,明显后端提供的数据有问题
door2guest (2级) 2013-06-22
@园长MM 文章说的就是后端输出json导致的问题,可以控制info改变json的结构。
园长MM (1级) 2013-06-22
@door2guest 昨晚睡的代码没贴上,debug了下其实是直接用object put’会有问题,在转换的时候JsonObject抛了一个JsonException异常,也就是说转换后的json代码是有问题的。把实现方式改成Map
天气有点热 (1级) 2013-06-22 3楼
net.sf.json代码片段:
import net.sf.json.JSONObject; public class Test { public static void main(String[] args) { JSONObject json = new JSONObject(); json.put(“key”, “{‘replace’:function(){alert(/xss/)}}”); System.out.println(json); System.out.println(((JSONObject)json.get(“key”)).get(“replace”)); } }
org.json代码片段:
import org.json.JSONException; import org.json.JSONObject; public class Test { public static void main(String[] args) throws JSONException { JSONObject json = new JSONObject(); json.put(“key”, “{‘replace’:function(){alert(/xss/)}}”); System.out.println(json); System.out.println(((JSONObject)json.get(“key”)).get(“replace”)); } }
使用net.sf.json输出结果是:
{"key":{"replace":function(){ alert(/xss/) }}} function(){ alert(/xss/) }
这里net.sf.json的value实际是一个JSONObject对象,所以还可以调用注入value中JSONObject对象,这是net.sf.json正常的嵌套功能,但是它不符合js json的标准
使用org.json输出结果是:
{"key":"{'replace':function(){alert(/xss/)}}"} Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to org.json.JSONObject at Test.main(Test.java:20)
org.json是符合js json标准的,它的value就是个String,cast成JSONObject就报异常了.
其实就是个net.sf.json的json与js json输出标准不一样造成的,从而可以控制输出端的内容,通过构造在前端做某些js函数操作时,其内容会被当成js语句块执行,就是上面的xss了
那为什么不用org.json,要用net.sf.json了?因为net.sf.json更为强大(比如:多层嵌套(类似迭代器),javabean转换等)
天气有点热 (1级) 2013-06-22
@天气有点热 编辑器这么坑爹,第一个
怎么就匹配最后一个[/code]了,不是应该匹配最近的一个
吗?
door2guest (2级) 2013-06-22
@天气有点热 总结的非常好
文章来源于lcx.cc:JSONObject输出json串可引发XSS
相关推荐: 【新闻】360卫士 VS 金山毒霸 - 坐观好戏
本次360搜集用户信息事件(详情点这里:360秘密收集用户信息日志文件大规模外泄),周教主的对策估计很快出来了... 随着元旦节假日的结束,周教主开始策划如何圆谎了。 由于金山手上有铁证,而这些铁证又可以由谷歌来证明,加之谷歌凭360那…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论