Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f077798

Browse files
committed
Default MVC input formatter to UntrustedData for CWE-1188
MessagePackInputFormatter handles HTTP request bodies, but its default/null options path fell back to MessagePackSerializerOptions.Standard and therefore TrustedData. That left hash-based model binding without the untrusted-data collision-resistance defaults expected at this trust boundary. Default null input-formatter options to Standard.WithSecurity(UntrustedData), while preserving caller-supplied options. Add a regression test that verifies the parameterless formatter deserializes dictionary request bodies with the collision-resistant comparer.
1 parent 06ea249 commit f077798

2 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/MessagePack.AspNetCoreMvcFormatter/MessagePackInputFormatter.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@ namespace MessagePack.AspNetCoreMvcFormatter
99
public class MessagePackInputFormatter : InputFormatter
1010
{
1111
private const string ContentType = "application/x-msgpack";
12-
private readonly MessagePackSerializerOptions? options;
12+
private static readonly MessagePackSerializerOptions DefaultOptions = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData);
13+
private readonly MessagePackSerializerOptions options;
1314

1415
public MessagePackInputFormatter()
15-
: this(null)
16+
: this(DefaultOptions)
1617
{
1718
}
1819

1920
public MessagePackInputFormatter(MessagePackSerializerOptions? options)
2021
{
21-
this.options = options;
22+
this.options = options ?? DefaultOptions;
2223

2324
SupportedMediaTypes.Add(ContentType);
2425
}

tests/MessagePack.AspNetCoreMvcFormatter.Tests/AspNetCoreMvcFormatterTest.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.IO;
67
using System.Text;
78
using System.Threading;
@@ -195,6 +196,34 @@ public void MessagePackInputFormatterSupportsXMsgPack()
195196
inputFormatter.SupportedMediaTypes.Is(MsgPackContentType);
196197
}
197198

199+
[Fact]
200+
public async Task MessagePackInputFormatterDefaultsToUntrustedData()
201+
{
202+
const long value1 = 0x100000001;
203+
const long value2 = 0x200000002;
204+
205+
var messagePackBinary = MessagePackSerializer.Serialize(new Dictionary<long, int>
206+
{
207+
[value1] = 1,
208+
[value2] = 2,
209+
});
210+
211+
var httpContext = new DefaultHttpContext();
212+
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
213+
httpContext.Request.Body = new NonSeekableReadStream(messagePackBinary);
214+
httpContext.Request.ContentType = MsgPackContentType;
215+
216+
InputFormatterContext inputFormatterContext = this.CreateInputFormatterContext(typeof(Dictionary<long, int>), httpContext);
217+
var inputFormatter = new MessagePackInputFormatter();
218+
219+
InputFormatterResult result = await inputFormatter.ReadAsync(inputFormatterContext);
220+
221+
Assert.False(result.HasError);
222+
var dictionary = Assert.IsType<Dictionary<long, int>>(result.Model);
223+
Assert.Equal(EqualityComparer<long>.Default.GetHashCode(value1), EqualityComparer<long>.Default.GetHashCode(value2));
224+
Assert.NotEqual(dictionary.Comparer.GetHashCode(value1), dictionary.Comparer.GetHashCode(value2));
225+
}
226+
198227
/// <summary>
199228
/// <see href="https://github.com/aspnet/Mvc/blob/master/test/Microsoft.AspNetCore.Mvc.Formatters.Json.Test/JsonOutputFormatterTests.cs#L453">JsonOutputFormatterTests.cs#L453</see>.
200229
/// </summary>

0 commit comments

Comments
 (0)