Fix Multipart content view parsing (#6653)

#### Description

On get_message_content_view, the content type wasn't including the
boundary, and was only setting the MIME type. This made the multipart
content view unusable, as the boundary was required on parsing. To fix
the issue, we assign the full content type instead.

This wasn't triggered by any previous tests because they would test
against the multipart parser directly, and not the generic parser.

#### Checklist

 - [X] I have updated tests where applicable.
 - [x] I have added an entry to the CHANGELOG.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Daniel López Guimaraes 2024-03-08 22:33:02 +01:00 committed by GitHub
parent 7930759962
commit ee5aac0a12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 35 additions and 2 deletions

View File

@ -7,7 +7,8 @@
## Unreleased: mitmproxy next
* Fix multipart form content view being unusable.
([#6653](https://github.com/mitmproxy/mitmproxy/pull/6653), @DaniElectra)
## 07 March 2024: mitmproxy 10.2.4

View File

@ -1,3 +1,4 @@
from .. import http
from . import base
from mitmproxy.coretypes import multidict
from mitmproxy.net.http import multipart
@ -11,7 +12,17 @@ class ViewMultipart(base.View):
yield [("highlight", "Form data:\n")]
yield from base.format_dict(multidict.MultiDict(v))
def __call__(self, data: bytes, content_type: str | None = None, **metadata):
def __call__(
self,
data: bytes,
content_type: str | None = None,
http_message: http.Message | None = None,
**metadata,
):
# The content_type doesn't have the boundary, so we get it from the header again
headers = getattr(http_message, "headers", None)
if headers:
content_type = headers.get("content-type")
if content_type is None:
return
v = multipart.decode_multipart(content_type, data)

View File

@ -81,6 +81,18 @@ def test_get_message_content_view():
desc, lines, err = contentviews.get_message_content_view("raw", r, f)
assert desc == "[cannot decode] Raw"
del r.headers["content-encoding"]
r.headers["content-type"] = "multipart/form-data; boundary=AaB03x"
r.content = b"""
--AaB03x
Content-Disposition: form-data; name="submit-name"
Larry
--AaB03x
""".strip()
desc, lines, err = contentviews.get_message_content_view("multipart form", r, f)
assert desc == "Multipart form"
r.content = None
desc, lines, err = contentviews.get_message_content_view("raw", r, f)
assert list(lines) == [[("error", "content missing")]]

View File

@ -1,5 +1,6 @@
from . import full_eval
from mitmproxy.contentviews import multipart
from mitmproxy.test import tutils
def test_view_multipart():
@ -13,6 +14,14 @@ Larry
""".strip()
assert view(v, content_type="multipart/form-data; boundary=AaB03x")
req = tutils.treq()
req.headers["content-type"] = "multipart/form-data; boundary=AaB03x"
req.content = v
assert view(
v, content_type="multipart/form-data; boundary=AaB03x", http_message=req
)
assert not view(v)
assert not view(v, content_type="multipart/form-data")