diff --git a/src/Http/Http/src/Features/FormFeature.cs b/src/Http/Http/src/Features/FormFeature.cs index 796e996187..7be6a576bf 100644 --- a/src/Http/Http/src/Features/FormFeature.cs +++ b/src/Http/Http/src/Features/FormFeature.cs @@ -175,8 +175,10 @@ namespace Microsoft.AspNetCore.Http.Features while (section != null) { // Parse the content disposition here and pass it further to avoid reparsings - ContentDispositionHeaderValue contentDisposition; - ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition); + if (!ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition)) + { + throw new InvalidDataException("Form section has invalid Content-Disposition value: " + section.ContentDisposition); + } if (contentDisposition.IsFileDisposition()) { diff --git a/src/Http/Http/test/Features/FormFeatureTests.cs b/src/Http/Http/test/Features/FormFeatureTests.cs index 8a63421c75..f8595564de 100644 --- a/src/Http/Http/test/Features/FormFeatureTests.cs +++ b/src/Http/Http/test/Features/FormFeatureTests.cs @@ -115,6 +115,14 @@ namespace Microsoft.AspNetCore.Http.Features "\r\n" + "Foo\r\n"; + private const string InvalidContentDispositionValue = "form-data; name=\"description\" - filename=\"temp.html\""; + + private const string MultipartFormFileInvalidContentDispositionValue = "--WebKitFormBoundary5pDRpGheQXaM8k3T\r\n" + +"Content-Disposition: " + +InvalidContentDispositionValue + +"\r\n" + +"\r\n" + +"Foo\r\n"; private const string MultipartFormWithField = MultipartFormField + @@ -137,6 +145,10 @@ namespace Microsoft.AspNetCore.Http.Features MultipartFormFileSpecialCharacters + MultipartFormEndWithSpecialCharacters; + private const string MultipartFormWithInvalidContentDispositionValue = + MultipartFormFileInvalidContentDispositionValue + + MultipartFormEnd; + [Theory] [InlineData(true)] [InlineData(false)] @@ -489,6 +501,24 @@ namespace Microsoft.AspNetCore.Http.Features await responseFeature.CompleteAsync(); } + [Fact] + public async Task ReadFormAsync_MultipartWithInvalidContentDisposition_Throw() + { + var formContent = Encoding.UTF8.GetBytes(MultipartFormWithInvalidContentDispositionValue); + var context = new DefaultHttpContext(); + var responseFeature = new FakeResponseFeature(); + context.Features.Set(responseFeature); + context.Request.ContentType = MultipartContentType; + context.Request.Body = new NonSeekableReadStream(formContent); + + IFormFeature formFeature = new FormFeature(context.Request, new FormOptions()); + context.Features.Set(formFeature); + + var exception = await Assert.ThrowsAsync(() => context.Request.ReadFormAsync()); + + Assert.Equal("Form section has invalid Content-Disposition value: " + InvalidContentDispositionValue, exception.Message); + } + private Stream CreateFile(int size) { var stream = new MemoryStream(size);