http.server: HTTP/1.1 requests without Host, with two Host fields or with an invalid Host value are accepted

Aperta
#161,675 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
35/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Ferma
Stack tecnologico
python

Direzione di ricerca

Start with BaseHTTPRequestHandler.parse_request and trace how it handles HTTP/1.1 headers. The report’s three examples define the cases to check: missing Host, duplicate Host fields, and an invalid Host value. Done means each case receives a 400 Bad Request; note that the issue body references linked PR gh-161696.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

stdlib type-bug
Bug report

BaseHTTPRequestHandler.parse_request does not look at the Host field. RFC 9112 section 3.2 states: "A server MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request message that lacks a Host header field and to any request message that contains more than one Host header field line or a Host header field with an invalid field value."

All three kinds of request below get status 200 and reach the handler. The 400 for a missing Host is from RFC 2616 section 14.23; the 400 for duplicate or invalid Host values was added in RFC 7230 section 5.4 (2014).

import http.server, socket, threading

class Handler(http.server.BaseHTTPRequestHandler):
    protocol_version = "HTTP/1.1"
    def do_GET(self):
        body = ("Host: %r\n" % self.headers.get_all("Host")).encode()
        self.send_response(200)
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)
    def log_message(self, *args): pass

server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler)
threading.Thread(target=server.serve_forever, daemon=True).start()

for request in [b"GET / HTTP/1.1\r\n\r\n",
                b"GET / HTTP/1.1\r\nHost: a.example\r\nHost: b.example\r\n\r\n",
                b"GET / HTTP/1.1\r\nHost: a b\r\n\r\n"]:
    with socket.create_connection(server.server_address, timeout=2) as s:
        s.sendall(request)
        s.shutdown(socket.SHUT_WR)
        lines = s.makefile("rb").read().split(b"\r\n")
    print(request, "->", lines[0], lines[-1])
server.shutdown()

Output:

b'GET / HTTP/1.1\r\n\r\n' -> b'HTTP/1.1 200 OK' b'Host: None\n'
b'GET / HTTP/1.1\r\nHost: a.example\r\nHost: b.example\r\n\r\n' -> b'HTTP/1.1 200 OK' b"Host: ['a.example', 'b.example']\n"
b'GET / HTTP/1.1\r\nHost: a b\r\n\r\n' -> b'HTTP/1.1 200 OK' b"Host: ['a b']\n"

Expected: HTTP/1.1 400 Bad Request for all three requests.

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Linked PRs
  • gh-161696
Lingua principale
Python
Stelle
78.2k
Fork
36.6k
Merge medio
19h 57m
PR unite (30g)
630

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di python/cpython

Tutte le issue di python/cpython

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.