Index: urllib3-1.22/dummyserver/handlers.py
===================================================================
--- urllib3-1.22.orig/dummyserver/handlers.py
+++ urllib3-1.22/dummyserver/handlers.py
@@ -28,7 +28,10 @@ class Response(object):
         self.headers = headers or [("Content-type", "text/plain")]
 
     def __call__(self, request_handler):
-        status, reason = self.status.split(' ', 1)
+        if hasattr(self.status, "decode"):
+            status, reason = self.status.decode().split(" ", 1)
+        else:
+            status, reason = self.status.split(" ", 1)
         request_handler.set_status(int(status), reason)
         for header, value in self.headers:
             request_handler.add_header(header, value)
@@ -51,6 +54,13 @@ class Response(object):
 RETRY_TEST_NAMES = collections.defaultdict(int)
 
 
+def request_params(request):
+    params = {}
+    for k, v in request.arguments.items():
+        params[k] = next(iter(v))
+    return params
+
+
 class TestingApp(RequestHandler):
     """
     Simple app that performs various operations, useful for testing an HTTP
@@ -227,6 +237,12 @@ class TestingApp(RequestHandler):
     def headers(self, request):
         return Response(json.dumps(request.headers))
 
+    def headers_and_params(self, request):
+        params = request_params(request)
+        return Response(
+            json.dumps({"headers": dict(request.headers), "params": params})
+        )
+
     def successful_retry(self, request):
         """ Handler which will return an error and then success
 
Index: urllib3-1.22/urllib3/_collections.py
===================================================================
--- urllib3-1.22.orig/urllib3/_collections.py
+++ urllib3-1.22/urllib3/_collections.py
@@ -259,6 +259,24 @@ class HTTPHeaderDict(MutableMapping):
         else:
             return vals[1:]
 
+    def _prepare_for_method_change(self):
+        """
+        Remove content-specific header fields before changing the request
+        method to GET or HEAD according to RFC 9110, Section 15.4.
+        """
+        content_specific_headers = [
+            "Content-Encoding",
+            "Content-Language",
+            "Content-Location",
+            "Content-Type",
+            "Content-Length",
+            "Digest",
+            "Last-Modified",
+        ]
+        for header in content_specific_headers:
+            self.discard(header)
+        return self
+
     # Backwards compatibility for httplib
     getheaders = getlist
     getallmatchingheaders = getlist
Index: urllib3-1.22/urllib3/connectionpool.py
===================================================================
--- urllib3-1.22.orig/urllib3/connectionpool.py
+++ urllib3-1.22/urllib3/connectionpool.py
@@ -32,6 +32,7 @@ from .connection import (
     HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection,
     HTTPException, BaseSSLError,
 )
+from ._collections import HTTPHeaderDict
 from .request import RequestMethods
 from .response import HTTPResponse
 
@@ -680,7 +681,11 @@ class HTTPConnectionPool(ConnectionPool,
         redirect_location = redirect and response.get_redirect_location()
         if redirect_location:
             if response.status == 303:
+                # Change the method according to RFC 9110, Section 15.4.4.
                 method = 'GET'
+                # And lose the body not to transfer anything sensitive.
+                body = None
+                headers = HTTPHeaderDict(headers)._prepare_for_method_change()
 
             try:
                 retries = retries.increment(method, url, response=response, _pool=self)
Index: urllib3-1.22/urllib3/poolmanager.py
===================================================================
--- urllib3-1.22.orig/urllib3/poolmanager.py
+++ urllib3-1.22/urllib3/poolmanager.py
@@ -3,7 +3,7 @@ import collections
 import functools
 import logging
 
-from ._collections import RecentlyUsedContainer
+from ._collections import HTTPHeaderDict, RecentlyUsedContainer
 from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool
 from .connectionpool import port_by_scheme
 from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown
@@ -329,9 +329,12 @@ class PoolManager(RequestMethods):
         # Support relative URLs for redirecting.
         redirect_location = urljoin(url, redirect_location)
 
-        # RFC 7231, Section 6.4.4
         if response.status == 303:
-            method = 'GET'
+            # Change the method according to RFC 9110, Section 15.4.4.
+            method = "GET"
+            # And lose the body not to transfer anything sensitive.
+            kw["body"] = None
+            kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
 
         retries = kw.get('retries')
         if not isinstance(retries, Retry):
Index: urllib3-1.22/test/with_dummyserver/test_connectionpool.py
===================================================================
--- urllib3-1.22.orig/test/with_dummyserver/test_connectionpool.py
+++ urllib3-1.22/test/with_dummyserver/test_connectionpool.py
@@ -5,6 +5,7 @@ import sys
 import unittest
 import time
 import warnings
+import json
 
 import mock
 
@@ -29,6 +30,7 @@ from urllib3.packages.six import b, u
 from urllib3.packages.six.moves.urllib.parse import urlencode
 from urllib3.util.retry import Retry, RequestHistory
 from urllib3.util.timeout import Timeout
+from urllib3 import HTTPHeaderDict
 
 from dummyserver.testcase import HTTPDummyServerTestCase, SocketDummyServerTestCase
 from dummyserver.server import NoIPv6Warning, HAS_IPV6_AND_DNS
@@ -415,6 +417,18 @@ class TestConnectionPool(HTTPDummyServer
         self.assertEqual(r.status, 200)
         self.assertEqual(r.data, b'Dummy server!')
 
+    def test_303_redirect_makes_request_lose_body(self):
+        with HTTPConnectionPool(self.host, self.port) as pool:
+            response = pool.request(
+                "POST",
+                "/redirect",
+                fields={"target": "/headers_and_params", "status": "303 See Other"},
+            )
+        data = response.data.decode("utf-8")
+        data = json.loads(data)
+        assert data["params"] == {}
+        assert "Content-Type" not in HTTPHeaderDict(data["headers"])
+
     def test_bad_connect(self):
         pool = HTTPConnectionPool('badhost.invalid', self.port)
         try:
Index: urllib3-1.22/urllib3/__init__.py
===================================================================
--- urllib3-1.22.orig/urllib3/__init__.py
+++ urllib3-1.22/urllib3/__init__.py
@@ -19,6 +19,7 @@ from .util.request import make_headers
 from .util.url import get_host
 from .util.timeout import Timeout
 from .util.retry import Retry
+from ._collections import HTTPHeaderDict
 
 
 # Set default logging handler to avoid "No handler found" warnings.
@@ -37,6 +38,7 @@ __version__ = '1.22'
 __all__ = (
     'HTTPConnectionPool',
     'HTTPSConnectionPool',
+    "HTTPHeaderDict",
     'PoolManager',
     'ProxyManager',
     'HTTPResponse',
