The Truth about GET and HTTP Standards
On Friday, Xavier talked about the newly introduced HTTP Query method. This new method was introduced to allow "GET" requests that include a body. The main reason for this was that GET requests typically do not contain a body. But what if they do?
The HTTP RFCs had "issues" defining this properly. RFC2616, which originally defined HTTP 1.1, stated in section 4.3:
A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests.
And the GET specification never discussed message bodies.
This was somewhat reworded in the newer version, RFC 7231, section 4.3.2:
??????A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
I did a quick check of a couple of common web servers I had handy, to see what would happen:
Apache
For this test, I ran Apache 2.4.68 on a Mac. It happily accepted a body with a GET request:
% nc -c localhost 8080 GET /cgi-bin/test-cgi HTTP/1.1 Host: localhost Content-Length: 6 TEST HTTP/1.1 200 OK Date: Tue, 22 Sep 2026 14:39:17 GMT Server: Apache/2.4.68 (Unix) Transfer-Encoding: chunked Content-Type: text/plain; charset=iso-8859-1 18a CGI/1.0 test script report: [some details omited] CONTENT_LENGTH = 6 BODY = TEST
The data was collected using a slightly modified version of the standard "test-cgi" script. The body was received just fine, and a 200 status was returned.
NGINX
% nc -c 10.128.1.11 80
GET /cgi-bin/test-cgi HTTP/1.1
Host: localhost
Content-Length: 6
TESTHTTP/1.1 301 Moved Permanently
Server: nginx
The request still did not trigger an error. But the body was ignored. The server started sending the response as soon as it received the headers. The body was ignored.
Python
A simple Python web server (python -m http.server 8000) appears to behave just like NGINX. The body is ignored, but a response is sent back, and the status code is 200.
Node
Node also ignores the Content-Length header and processes the request without error.
lighthttpd
lighttpd/1.4.74 will return a 400 error and refuse to process the request.
Java/Tomcat
Tomcat ignores the Content-Length header but returns a 200 response.
Do you have any web servers to test to see how they respond to a GET request with a body?
--
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

Comments