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 better?

- 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


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to