dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.3k stars 4.74k forks source link

HttpClient send MultipartFormDataContent / Azure WAF Multipart request body failed strict validation #98089

Closed coding-connect closed 9 months ago

coding-connect commented 9 months ago

Description

I get an 403 error by sending a file with HttpClient to a backend under a Azure WAF. The answer were 403 response with 'Multipart request body failed strict validation'.

var multipartContent = new MultipartFormDataContent();
FileStream fileStream = new FileStream(attachment, FileMode.Open, FileAccess.Read);
var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
multipartContent.Add(fileContent, "anomaliesAttachments", Path.GetFileName(attachment));
var responsePostFile = await Client.PostAsync("https://backend-api-url/file", multipartContent);

I read some anwers on stackoverflow that this problem could be due to the boundaries inside the request. The boundaries are surrounds in the HTTP header with double quotes. Browser don't have double quotes on boundaries and the rfc does not contains double quote https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html ....

By removing boundary double quote with this code

var boundary = multipartContent.Headers.ContentType.Parameters.First(o => o.Name == "boundary");
boundary.Value = boundary.Value.Replace("\"", String.Empty);

The answer a 200, the waf is not blocking anymore the request.

Reproduction Steps

Code run on .NET standard 2.1. Server is under a microsoft WAF Azure. Could be possible to use any interceptor to view the request and boundary and compare it with a request send by any browser.

Expected behavior

Boundary should not have doublequote

Actual behavior

The boundary seems have double quote multipart/form-data; boundary="04982073-787d-414b-a0d2-8e8a1137e145"

Regression?

No response

Known Workarounds

No response

Configuration

.Net standard 2.1

Other information

No response

ghost commented 9 months ago

Tagging subscribers to this area: @dotnet/ncl See info in area-owners.md if you want to be subscribed.

Issue Details
### Description I get an 403 error by sending a file with HttpClient to a backend under a Azure WAF. The answer were 403 response with 'Multipart request body failed strict validation'. ``` var multipartContent = new MultipartFormDataContent(); FileStream fileStream = new FileStream(attachment, FileMode.Open, FileAccess.Read); var fileContent = new StreamContent(fileStream); fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); multipartContent.Add(fileContent, "anomaliesAttachments", Path.GetFileName(attachment)); var responsePostFile = await Client.PostAsync("https://backend-api-url/file", multipartContent); ``` I read some anwers on stackoverflow that this problem could be due to the boundaries inside the request. The boundaries are surrounds in the HTTP header with double quotes. Browser don't have double quotes on boundaries and the rfc does not contains double quote https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html .... By removing boundary double quote with this code ``` var boundary = multipartContent.Headers.ContentType.Parameters.First(o => o.Name == "boundary"); boundary.Value = boundary.Value.Replace("\"", String.Empty); ``` The answer a 200, the waf is not blocking anymore the request. ### Reproduction Steps Code run on .NET standard 2.1. Server is under a microsoft WAF Azure. Could be possible to use any interceptor to view the request and boundary and compare it with a request send by any browser. ### Expected behavior Boundary should not have doublequote ### Actual behavior The boundary seems have double quote multipart/form-data; boundary="04982073-787d-414b-a0d2-8e8a1137e145" ### Regression? _No response_ ### Known Workarounds _No response_ ### Configuration .Net standard 2.1 ### Other information _No response_
Author: coding-connect
Assignees: -
Labels: `area-System.Net.Http`, `untriaged`
Milestone: -
ManickaP commented 9 months ago

This is a duplicate of https://github.com/dotnet/runtime/issues/68968 We closed this issue as won't fix, because using quotes is legal by RFC, even necessary in some cases, see RFC 2046 Section 5.1.1.

I strongly encourage you to report this to the Azure WAF.

coding-connect commented 9 months ago

@ManickaP What is the best way to report a bug to the Azure Waf team ?

ManickaP commented 9 months ago

There's a feedback button in Azure portal which should lead to creating a support request - that should be the official way to get a support.

Another avenue might be one of azure repos here on GH: https://github.com/Azure, although I haven't found the one for WAF. Lastly, there's a tech community: https://techcommunity.microsoft.com/t5/azure-network-security/bd-p/AzureNetworkSecurity.

coding-connect commented 9 months ago

@ManickaP Thanks for the links. I will report the bug to the team.

wfurt commented 9 months ago

Note that the RFC does have quotes in the example...

As a very simple example, the following multipart message has two parts, both of them plain text, one of them explicitly typed and one of them implicitly typed:

     From: Nathaniel Borenstein <nsb@bellcore.com> 
     To:  Ned Freed <ned@innosoft.com> 
     Subject: Sample message 
     MIME-Version: 1.0 
     Content-type: multipart/mixed; boundary="simple 
     boundary" 
coding-connect commented 9 months ago

@wfurt You are right this is writen in the https://www.rfc-editor.org/rfc/rfc2046#section-5.1.1 (but paradoxically in many other exemples in the rfc they don't put double quotes...)

WARNING TO IMPLEMENTORS:  The grammar for parameters on the Content-
   type field is such that it is often necessary to enclose the boundary
   parameter values in quotes on the Content-type line.  This is not
   always necessary, but never hurts.