diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-04-27 12:23:47 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-04-27 12:23:50 -0700 |
commit | 631f6f1d47cc51a46c8ab48ea1178ea04cff0b8a (patch) | |
tree | b2ecf2c3862aa8328f036c6882c2c851ed781cba | |
parent | Git 2.3.6 (diff) | |
parent | push --signed: tighten what the receiving end can ask to sign (diff) | |
download | tgif-631f6f1d47cc51a46c8ab48ea1178ea04cff0b8a.tar.xz |
Merge branch 'jc/push-cert' into maint
The "git push --signed" protocol extension did not limit what the
"nonce" that is a server-chosen string can contain or how long it
can be, which was unnecessarily lax. Limit both the length and the
alphabet to a reasonably small space that can still have enough
entropy.
* jc/push-cert:
push --signed: tighten what the receiving end can ask to sign
-rw-r--r-- | send-pack.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/send-pack.c b/send-pack.c index 25947d7df9..677bac3193 100644 --- a/send-pack.c +++ b/send-pack.c @@ -281,6 +281,28 @@ free_return: return update_seen; } +#define NONCE_LEN_LIMIT 256 + +static void reject_invalid_nonce(const char *nonce, int len) +{ + int i = 0; + + if (NONCE_LEN_LIMIT <= len) + die("the receiving end asked to sign an invalid nonce <%.*s>", + len, nonce); + + for (i = 0; i < len; i++) { + int ch = nonce[i] & 0xFF; + if (isalnum(ch) || + ch == '-' || ch == '.' || + ch == '/' || ch == '+' || + ch == '=' || ch == '_') + continue; + die("the receiving end asked to sign an invalid nonce <%.*s>", + len, nonce); + } +} + int send_pack(struct send_pack_args *args, int fd[], struct child_process *conn, struct ref *remote_refs, @@ -323,6 +345,7 @@ int send_pack(struct send_pack_args *args, push_cert_nonce = server_feature_value("push-cert", &len); if (!push_cert_nonce) die(_("the receiving end does not support --signed push")); + reject_invalid_nonce(push_cert_nonce, len); push_cert_nonce = xmemdupz(push_cert_nonce, len); } |