bin/git-http-backend-verify: scrutinize /info/refs query string
According to RFC 3986 section 2.3 "Unreserved Characters", characters
in the unreserved range (i.e matches [A-Za-z0-9._~-]) should not
be percent encoded by producers and when found percent encoded,
should be decoded back to the corresponding unreserved character.
Although Git's `git-http-backend` *does* decode any percent-encoded
characters it finds in either the name and/or value of parameters
in the query string, the much simpler `git-http-backend-verify`
script does not.
Furthermore, the only accepted and understood query strings (and
then only when the URL ends with "/info/refs") are:
1) service=git-upload-pack
2) service=git-receive-pack
Each of these potential query string values consists only of
"unreserved" characters and therefore should never contain any
percent-encoded characters.
Although `git-http-backend` does tolerate additional parameters
in the query string (that are ignored) and `git-http-backend-verify`
also tolerates extra, ignored parameters in the query string, none
are currently defined.
Therefore, reject any query strings provided for "GET" or "HEAD"
and a path ending in "/info/refs" that contain a "%" character.
Sending either of the accepted "service" parameters using any
percent-encoded characters could only be a request from a bad actor
and would be interpreted as a non-smart request by the
`git-http-backend-verify` script (unless the server software
properly normalizes the incoming URL before processing it).
By explicitly rejecting such query strings for GET/HEAD requests
(those with a path ending in /info/refs and a query string containing
a "%" character), the client's incorrect behavior gets flagged
immediately rather than attempting to process the request as a
non-smart request which could precipitate difficult to diagnose
problems.
It's worth noting that one particularly well-known and very popular
Git repository hosting provider accepts exactly only
"service=git-upload-pack" or "service=git-receive-pack" as the query
string for ".../info/refs" requests and rejects anything else
including any percent encodings and or extra parameters.
Signed-off-by: Kyle J. McKay <mackyle@gmail.com>