diff options
author | Jeff King <peff@peff.net> | 2021-09-15 14:36:33 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2021-09-15 12:25:19 -0700 |
commit | 108c265f272d30ffaee423f7cc35885e9ac5d0e5 (patch) | |
tree | a15ea596c4a0bd2a2bd5fa90867b4398067a8091 /serve.c | |
parent | 9db5fb4fb352e79931e50f6de71497e273a3a6ac (diff) | |
download | git-108c265f272d30ffaee423f7cc35885e9ac5d0e5.tar.gz |
serve: reject bogus v2 "command=ls-refs=foo"
When we see a line from the client like "command=ls-refs", we parse
everything after the equals sign as a capability, which we check against
our capabilities table. If we don't recognize the command (e.g.,
"command=foo"), we'll reject it.
But in parse_command(), we use the same get_capability() parser for
parsing non-command lines. So if we see "command=ls-refs=foo", we will
feed "ls-refs=foo" to get_capability(), which will say "OK, that's
ls-refs, with value 'foo'". But then we simply ignore the value
entirely.
The client is violating the spec here, which says:
command = PKT-LINE("command=" key LF)
key = 1*(ALPHA | DIGIT | "-_")
I.e., the key is not even allowed to have an equals sign in it. Whereas
a real non-command capability does allow a value:
capability = PKT-LINE(key[=value] LF)
So by reusing the same get_capability() parser, we are mixing up the
"key" and "capability" tokens. However, since that parser tells us
whether it saw an "=", we can still use it; we just need to reject any
input that produces a non-NULL value field.
The current behavior isn't really hurting anything (the client should
never send such a request, and if it does, we just ignore the "value"
part). But since it does violate the spec, let's tighten it up to
prevent any surprising behavior.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'serve.c')
-rw-r--r-- | serve.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -220,7 +220,7 @@ static int parse_command(const char *key, struct protocol_capability **command) if (*command) die("command '%s' requested after already requesting command '%s'", out, (*command)->name); - if (!cmd || !cmd->advertise(the_repository, NULL) || !cmd->command) + if (!cmd || !cmd->advertise(the_repository, NULL) || !cmd->command || value) die("invalid command '%s'", out); *command = cmd; |