nginx Interoperability Analysis

Luis David Pedrosa luis.pedrosa at
Thu Sep 18 08:24:50 UTC 2014

Hello everyone,

I'm Luis Pedrosa and I a researcher and graduate student at the  
University of Southern California. My research involves using program  
analysis techniques on protocol implementations to automatically find  
interoperability issues. The idea is to automatically find scenarios  
that lead, for example, a client to send something to a server that is  
somehow rejected as an invalid message. The point being to either find  
bugs in the code that can be fixed or, more importantly, to find  
ambiguities in the standard that should clarified.

To evaluate our tool we analyze open-source protocol code and find  
potential bugs. I've been analyzing the SPDY protocol using the  
spdylay library as a client and nginx as as a server. We found a few  
situations where interoperability breaks down between these two, and  
would like to hear from the nginx-devel community on whether these  
issues are legitimate and relevant. The issue we found are:

- nginx doesn't support "HTTP/0.9" in the "version" header and rejects  
the message as a bad request. Actually, I believe it looks for  
anything starting with the following pattern: "HTTP/[1-9]". Is there a  
reason for HTTP/0.9 to be rejected, while HTTP/3 onwards would be  
accepted, especially since nginx does support HTTP/0.9 outside of  
SPDY? spdylay doesn't understand the semantics of the header and let's  
anything through. The SPDY draft doesn't really offer any insight into  
allowed values here other than the example "HTTP/1.1". Should the SPDY  
specification be more clear about the semantics here?

- When parsing the path header, nginx must un-escape percent-encoded  
characters (e.g. %20 for space). If the path has a %, followed by  
something other than two hexadecimal digits (e.g. path="/%%"), nginx  
rejects the message as a bad request. Again, spdylay doesn't care  
about the semantics of the header. The SPDY draft refers to RFC-3986  
for URIs, which does require two hex digits after a percent. In your  
opinion, is automatic character escaping and percent encoding  
something the client should do, or is this something that should be  
left up to whoever made the link in the first place?

- We also found a deeper issue with correctly formatted  
percent-encoded characters. It turns out that nginx explicitly blocks  
the correctly encoded NUL character (%00) in the path header. As  
before, spdylay doesn't care about such things. RFC-3986 explicitly  
allows the decoder to reject this character if it does not want to  
handle it. Is there a particular reason for nginx to reject this  
encoded character, or is it just a can of worms no one wants to open?

- nginx does not allow either the carriage-return ('\r') or the  
line-feed ('\n') character in header values. spdylay doesn't check for  
this. I don't believe the SPDY draft mentions this as a problem, but  
if this were pure HTTP the constraint would make sense as it would  
start the next header. Should the SPDY draft mention something about  
handling this corner case?

- As nginx parses the path, it keeps track of the hierarchy depth and  
rejects requests that try to break out of the web-root directory  
(path="/a/../../"). This is a sane security policy, as this was a huge  
problem in the early years of the web. spdylay doesn't understand the  
semantics of the path header and lets anything through. I was  
surprised to see this being handled in parsing code. Is there a reason  
that this would be handled as a bad request, instead of a permission  
issue? Is it just such a bad idea that the sooner it's shot down the  

- nginx doesn't allow the TRACE method header value. This is a  
perfectly fine message to send, so spdylay let's it out. Is there a  
particular reason why such a simple HTTP method isn't handled?

Please let me know what you think of these issues and of the ability  
to find them mostly automatically.

Thank you.

Best regards,

Luis D. Pedrosa

More information about the nginx-devel mailing list