问题:
Spring的数据绑定器允许您设置自动创建的List<>
的最大大小(),例如到3项。通过修改发送到服务器的HTTP内容,可以轻松绕过此限制并使Spring创建3000多个项目的列表。
换句话说:在测试我的webapp时,我能够通过创建恶意HTTP请求来强制Spring的数据绑定器创建List&lt;&gt;由4000件物品组成,虽然我已将限量设定为3件。这可能很容易导致任何应用服务器上的内存不足。
问题:
我是否遗漏了一些明显如何阻止Spring执行此操作的内容,或者更确切地说,这是一个应该向Spring的错误跟踪器报告的错误?
使用的版本:
弹簧工具套件-3.3.0.RELEASE,
d:\平方米\回购\有机\ springframework的\弹簧的web \ 3.2.4.RELEASE \弹簧网络3.2.4.RELEASE.jar
说明
我需要将多个html <input />
元素绑定到单个List<String>
对象,例如:
<input type="text" name="phoneNumber[0]" />
...
<input type="text" name="phoneNumber[n]" />
Spring默认使用org.springframework.beans.propertyeditors.CustomCollectionEditor
执行此类转换。以下是一个简单的代码段,介绍了上述问题。
代码:
public class ContactDataEntity {
private List<String> phoneNumber;
// getters and setters
}
@RequestMapping(value = VIEW_PAGE_1, method = RequestMethod.POST)
public String xxx(HttpServletRequest request, Model model) {
// set and bind
ContactDataEntity contactData = new ContactDataEntity();
ServletRequestDataBinder binder = new ServletRequestDataBinder(contactData);
binder.setAutoGrowCollectionLimit(3); // set limit to 3 items
binder.bind(request);
// test binding results
List<String> numbers = contactData.getPhoneNumber();
if (numbers != null) {
System.out.print("numbers SIZE: " + numbers.size() + ", DATA: ");
for (String s : numbers) System.out.print(s + ", ");
System.out.print("\n");
}
// validate and return view name...
}
正确数据的结果(&lt; = 3项,一切正常,我使用Firefox的Live HTTP Headers):
(对不起图片的链接,但“你需要至少10个声望来发布图片。”和“你需要至少10个声望才能发布2个以上的链接。”)
过多项目的结果(&gt; 3项,一切正常,500内部服务器错误发生):
i.stack.imgur.com/MfWYy.jpg
简单的伎俩(&gt; 3项,没有错误报告,抱歉我的拼写错误'覆盖'):
i.stack.imgur.com/FNlXE.jpg
让我们利用上述内容:
i.stack.imgur.com/XPIhc.jpg
所以,我的问题再次提出:我是否遗漏了一些明显的事情,如何阻止Spring这样做,或者更确切地说,这是一个应该报告给Spring的bug追踪器的错误?
//编辑:
我把它报告为一个错误:https://jira.springsource.org/browse/SPR-11472
答案 0 :(得分:2)
好的,在Spring 3.2.9和4.0.3的官方修复发布之前,我已经覆盖了Spring的默认CustomCollectionEditor来暂时修复这个bug。
唯一的缺点是你不能在你的HTML代码/ HTTP请求中使用它:
&phoneNumber=0
&phoneNumber=1
&phoneNumber=2
&phoneNumber=3
但您需要明确地为每个参数编制索引:
&phoneNumber[0]=0
&phoneNumber[1]=1
&phoneNumber[2]=2
&phoneNumber[3]=3
现在简单地忽略了不带[]的多个参数,请参阅以下代码中的注释。
package xxx;
import java.util.List;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
/**
* @see <a href="https://jira.springsource.org/browse/SPR-11472">https://jira.springsource.org/browse/SPR-11472</a>
*/
public class CustomListEditorSPR11472 extends CustomCollectionEditor {
@SuppressWarnings("rawtypes")
public CustomListEditorSPR11472(Class<List> collectionType) {
super(collectionType);
}
@Override
public void setValue(Object value) {
/*
* Force Spring to ignore all HTTP request **MULTIPLE** parameters without "[]" on the end so that
* binder.setAutoGrowCollectionLimit() could work correctly. Example:
*
* phoneNumber[2]=2
* Above request is OK, a List containing: 'null, null, 2' is created.
*
* phoneNumber=2
* Above request is OK, **SINGLE** parameter without "[]", a List containing: '2' is created
*
* phoneNumber[0]=0&phoneNumber=1&phoneNumber=2
* **MULTIPLE** parameters without "[]" are ignored, a List containing: '0' is created.
*/
if ((value != null && value.getClass().isArray()) == false) {
super.setValue(value);
}
}
}
当然,您还需要在活页夹中注册CustomEditor:
binder.registerCustomEditor(List.class, new CustomListEditorSPR11472(List.class));
或单个属性的更细粒度版本:
binder.registerCustomEditor(List.class, "phoneNumber", new CustomListEditorSPR11472(List.class));