NEW303475
HTTPS 307 redirect forgets POST body after accepting certificate warning
https://bugs.webkit.org/show_bug.cgi?id=303475
Summary HTTPS 307 redirect forgets POST body after accepting certificate warning
alexander.zeijlon
Reported 2025-12-03 07:22:37 PST
Created attachment 477598 [details] redirect-servers.py starts two Python Flask apps. Go to http://127.0.0.1:5000/ and post the form to see the faulty behavior in Safari. Steps to reproduce: 1. Set up "Server A" (HTTP) and "Server B" (HTTPS with a self-signed/untrusted certificate). 2. Configure Server A to respond to a POST request at /redir with HTTP 307 Temporary Redirect and a Location header pointing to https://ServerB/target. 3. Ensure the certificate for Server B is NOT currently in the browser's exception list (clear recent history/site preferences if necessary). 4. Open Firefox Network Monitor (DevTools). 5. Create an HTML form to send a POST request with a body (e.g., {"data": "FORM POST DATA"}) to http://ServerA/redir. 6. Submit the form. Firefox will block the redirect and show the "Potential Security Risk Ahead" page for Server B. 7. Click "Advanced" -> "Accept the Risk and Continue". 8. Observe the method of the request sent to Server B in the Network Monitor or server logs. See attached example servers written in Python (Flask). Actual results: Firefox resumes the request to the target URL but changes the HTTP method from POST to GET and discards the request body. Expected results: The request to https://ServerB/target should be a POST request containing the original body data. According to RFC 7231, a 307 redirect MUST NOT allow the method to change unless the user explicitly confirms it. In this specific case, the user is confirming the certificate exception, not a change in HTTP method. The expectation is that once the security exception is granted, the original request (POST + Body) is replayed exactly as intended by the 307 status code. See https://datatracker.ietf.org/doc/html/rfc7231#section-6.4.7 Note that Google Chrome and MS Edge seem to work as explained above, while Epiphany and Safari (WebKit browsers) and Firefox have similar faulty behaviors.
Attachments
redirect-servers.py starts two Python Flask apps. Go to http://127.0.0.1:5000/ and post the form to see the faulty behavior in Safari. (1.16 KB, text/x-python)
2025-12-03 07:22 PST, alexander.zeijlon
no flags
alexander.zeijlon
Comment 1 2025-12-04 05:40:27 PST
Apologies! I just realized that there are plenty of references to Firefox in the problem description. These should of course say "Safari". (The bug was reported to both WebKit and Mozilla, hence the mistake.)
alexander.zeijlon
Comment 2 2025-12-05 00:23:25 PST
I tried to work around this by making the form post directly to the Location header's URL instead of setting the Location header, <form action="https://ServerB/target" method="post">. But this also does not work. The request is changed to a GET, and the request body is lost. In this instance, it looks like Safari/WebKit is the only browser engine that changes the method when it encounters an untrusted certificate.
Radar WebKit Bug Importer
Comment 3 2025-12-10 07:23:11 PST
Note You need to log in before you can comment on or make changes to this bug.