攻击
final String GUESTROLE = guest_role; ... //userdata是准备保存的xml数据,接收了name和email两个用户提交来的数据。 String userdata = <USER role=+ GUESTROLE+ ><name>+ request.getParameter(name)+ </name><email>+ request.getParameter(email)+ </email></USER>; //保存xml userDao.save(userdata);
可以看到,这段代码没有进行任何的过滤操作。一个普通用户注册后,会产生这样一条数据记录:
<?xml version=1.0 encoding=UTF-8?> <USER role=guest_role> <name>user1 </name> <email>user1@a.com </email> </USER>
攻击者输入自己email时,可以输入如下代码:
user1@a.com</email></USER><USER role=admin_role><name>lf</name><email>user2@a.com
<?xml version=1.0 encoding=UTF-8?> <USER role=guest_role> <name>user1 </name> <email>user1@a.com</email> </USER> <USER role=admin_role> <name>lf</name> <email>user2@a.com </email> </USER>
可以看到,多出了一条role=“admin_role”的管理员lf。达到攻击目的。
防御
还是那句老话,有攻击就有防御。防御的原理其实也很简单,就是对关键字符串进行转义:
& --> & < --> < > --> > --> ' --> '
在XML保存和展示之前,对数据部分,单独做转义即可:
String userdata = <USER role=+ GUESTROLE+ ><name>+ StringUtil.xmlencode(request.getParameter(name))+ </name><email>+ StringUtil.xmlencode(rrequest.getParameter(email))+ </email></USER>;
这样就解决啦。