我遇到了默认的ASP.NET url-form-encoded模型绑定器的问题,它进入了一个无限循环。
可以通过创建ApiController来重现该问题:
public class TestController : ApiController
{
public HttpResponseMessage Put([FromBody] Data data)
{
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
}
以下数据模型:
public class Data
{
public string Title { get; set; }
public SubData SubData { get; set; }
}
public class SubData
{
public IList<Item> Items { get; set; }
}
public class Item
{
public IList<SubItem> SubItems { get; set; }
}
public class SubItem
{
public string Name { get; set; }
}
然后通过以下方式致电控制器:
$.ajax({
url: '/api/Test',
type: 'PUT',
data: {
Title: 'hello',
SubData: {
Items: null
}
}
});
我在这里创建了一个问题和完整示例:https://aspnetwebstack.codeplex.com/workitem/2280
问题
将Data.SubData.Items属性作为 null 传递会导致模型绑定器进入无限循环。这将继续消耗内存,直到没有任何剩余。一旦所有内存消失,将调用TestController并且data参数为null(不抛出异常)。传递空数组或者根本不传递该属性将允许活页夹正常工作。
调试asp.net源表明无限循环位于CollectionModelBinder.BindComplexCollectionFromIndexes方法中。 indexNames迭代器是一个while(true)并且绑定子项始终有效,didBind永远不会设置为false,因此它永远不会脱离foreach。它选择此方法,因为客户端的值为null。
仅发送一个空数组是不够的,因为攻击者可以轻松地使用它来发起DOS攻击。
问题
任何帮助都将不胜感激。