Search code examples
httpfile-uploadhttp-headers

HTTP: Can I trust 'Content-Length' request header value


I'm developing a file uploading service. I want my users to be restricted for total uploaded files sizes, i.e. they have quotas for uploaded files. So I want to check for available quota as a user starts upload a new file. The easiest way is to take 'Content-Length' header value of the POST request and check it against remaining user's quota. But I'm anxious about whether I can trust 'Content-Length' value. What if a bad guy specifies a small value in 'Content-Length' header and starts uploading a huge file.

Should I check additionally during reading from input stream (and saving a file on disk) or it's redundant (and such a situation should be detected by Web servers)?


Solution

  • Short answer: it's safe

    Long answer: Generally, servers are required to read (at most) as many bytes as are specified in the Content-Length request header. Any bytes that comes after that are expected to indicate a completely new request (reusing the same connection).

    I'd assume that this requirement is validated on the server by checking that the next few bytes can be parsed as a request-line.

    request-line = method SP request-target SP HTTP-version CRLF
    

    If your bad guy is not smart enough to inject request headers in the right locations of the message body, the server should (must?) automatically treat the entire chain of requests as invalid and abort the file upload.

    If your guy does inject new request headers in the message body (a.k.a. request smuggling), each resulting request is technically still valid and you'll still be able to trust that the Content-Length is valid for each message body. You just have to watch out for a different kind of attacks. For example: you might have a proxy installed that filters incoming requests, but only does so by checking the headers of the first request. The smuggled requests get a free pass, which is an obvious security breach.