django / daphne

Django Channels HTTP/WebSocket server
BSD 3-Clause "New" or "Revised" License
2.37k stars 266 forks source link

Daphne allows `\x00` within header values. #514

Closed kenballus closed 3 months ago

kenballus commented 3 months ago

Steps to reproduce

  1. Run this WSGI application with Daphne:
    $ daphne -b 0.0.0.0 -p 80 server:app

    (This application just base64-encodes and echos back various parts of the incoming request)

  2. Send a request with a null byte in a header called Test, then extract and decode the Test header value:
    $ printf 'GET / HTTP/1.1\r\nHost: whatever\r\nTest: a\x00a\r\n\r\n' \
    | timeout 1 ncat --no-shutdown localhost 80 \
    | grep 'headers' \
    | jq '.["headers"][1][1]' \
    | sed 's/"//g' \
    | base64 -d \
    | xxd
    00000000: 6100 61                                  a.a
  3. Observe that the null byte is present in the response.

What I expected to happen

RFC 9110 says this:

Field values containing CR, LF, or NUL characters are invalid and dangerous, due to the varying ways that implementations might parse and interpret those characters; a recipient of CR, LF, or NUL within a field value MUST either reject the message or replace each of those characters with SP before further processing or forwarding of that message.

Daphne complies with this rule for CR and LF, so I expected that Daphne would also comply for NUL by either rejecting the request or replacing the null byte with a space.

Platform

Linux 6.9.6, Daphne main @ 0f15e4595b195a7d6c0cb4df58df69afd6b17045

carltongibson commented 3 months ago

Hi @kenballus. Thanks for the report. Yes, that looks like something to clean up. Would you like to prepare a PR?

kenballus commented 3 months ago

Upon further investigation, I'm pretty sure this is a bug in Twisted. I'll submit a PR there.

carltongibson commented 3 months ago

Ok, great. Please do let me know how you get on.