Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle (legal vis-à-vis HTTP) OPTIONS * requests #2117

Open
doriantaylor opened this issue Aug 28, 2023 · 1 comment
Open

How to handle (legal vis-à-vis HTTP) OPTIONS * requests #2117

doriantaylor opened this issue Aug 28, 2023 · 1 comment

Comments

@doriantaylor
Copy link
Contributor

doriantaylor commented Aug 28, 2023

On the basis that PATH_INFO can already have a value of * if Rack::Lint is not used, we can accept this PR. However, I still think we should have a follow up discussion about the right behavior here.

Originally posted by @ioquatix in #2114 (comment)

This is a thorny issue because while RFC9110 asserts (along with its predecessors dating all the way back to RFC2068) that an OPTIONS * request is a perfectly valid mechanism for obtaining global information about a Web server's capabilities. However, the CGI spec, RFC3875, upon which the Rack specification is based, does not seem to acknowledge this validity, and thus does not specify how it should be implemented. An informal poll of Web server implementations suggests that the prevailing behaviour is to put the * of OPTIONS * into the PATH_INFO variable, while leaving SCRIPT_NAME untouched. What makes this issue thorny is that Rack applications (that are running without Rack::Lint) that do not check the request method could be in for a rude surprise if they try to use the PATH_INFO of an OPTIONS * under the assumption that it it is either empty or starts with a /. A particularly obvious hazard is if the * character gets treated as a glob(3) pattern.

As it stands for Rack, the method Rack::Request#path in particular does not account for the possibility that PATH_INFO may contain anything other than an empty string or one that starts with /, per RFC3875 (again, it is my opinion that RFC3875 itself is in error). This situation propagates to other methods in Rack::Request, such as #fullpath, #url, and everything downstream from there.

One solution (within Rack::Request at least) would be, in the call to #path, to check if the request method was OPTIONS and the PATH_INFO was * and faking up a result in that case (e.g. using / in lieu). That would mitigate the potential for harm at least for those applications using Rack::Request. Those who do not would have to be warned to test the request method before dispatching any URI behaviour (a sensible practice in any case).

I should also footnote that the OPTIONS method is not the only one where the request-URI is something other than that which starts with a /; the CONNECT method for one (which one could conceivably do something useful with in Rack using connection hijacking) and the PRI * request for upgrading to HTTP/2 are other specimens, off the top of my head. The point here is it's not just the special case of OPTIONS *.

@ioquatix
Copy link
Member

ioquatix commented Aug 28, 2023

My initial feeling is, at least Request#path should never contain *. I think in this case, OPTIONS *, Request#path should return nil. At worst, this will blow up in places where it would always do the wrong thing.

cc @tenderlove do you have any opinion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants