On 07/02/2017 07:34 PM, Ismael Bouya wrote: > (Sun, Jul 02, 2017 at 07:22:23PM -0400) Eli Schwartz via arch-general : >> Okay, this I am genuinely curious about. >> >> In what circumstances can I have: >> - the systemd repository cloned over the git:// protocol >> - an annotated tag for systemd v233 signed by Lennart Poettering. >> - an annotated tag for systemd v232 signed by Lennart Poettering. >> - a man in the middle attack >> - `git verify-tag --raw v233` reports a GOODSIG with a VALIDSIG >> ${fingerprint} that matches with Lennart's known GPG fingerprint as >> recorded in validpgpkeys >> >> And as a result, when I run the git command `git checkout >> refs/tags/v233`, I am tricked into getting v232 instead which contains a >> vulnerability. > > Until there, it's exactly the topic of the presentation linked by > Nicohood So I was under the impression that git tags encode the tagname in the actual blob, and I didn't see how that attack (rooted in the basic nature of a branch as a lightweight, mutable, *pushable* pointer to a commit) was supposed to work unless of course it was talking about a lightweight tag (which is not really meant for public/permanent use)... Having actually tested this out, I find myself quite bewildered. Because, git *does* encode the tagname in the blob, like I thought. And... you *can* simply copy .git/refs/tags/tagname to create a fake tag, and then you see something quite bewildering: ``` [eschwartz@arch ~/git]$ git clone https://github.com/systemd/systemd [...] [eschwartz@arch ~/git]$ cd systemd [eschwartz@arch ~/git/systemd]$ echo "$(git show-ref -s v233)" > .git/refs/tags/v232 [eschwartz@arch ~/git/systemd]$ git tag -v v232 object d60c527009133a1ed3d69c14b8c837c790e78d10 type commit tag v233 tagger Lennart Poettering <lennart@xxxxxxxxxxxxxx> 1488405946 +0100 systemd 233 gpg: Signature made Wed 01 Mar 2017 05:05:46 PM EST gpg: using RSA key B63B21879C3485B0 gpg: Good signature from "Lennart Poettering <lennart@xxxxxxxxxxxxxx>" [unknown] gpg: aka "Lennart Poettering <lennart@xxxxxxxxxxxxx>" [unknown] gpg: aka "Lennart Poettering (Red Hat) <lpoetter@xxxxxxxxxx>" [unknown] gpg: aka "Lennart Poettering (Sourceforge.net) <poettering@xxxxxxxxxxxxxxxxxxxxx>" [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 63CD A1E5 D3FC 22B9 98D2 0DD6 327F 2695 1A01 5CC4 Subkey fingerprint: 16B1 C4EE C0BC 021A C777 F681 B63B 2187 9C34 85B0 ``` I simply do not understand why git doesn't error when it sees that a tag ref named v232 points to a tag blob named v233. The information is all there, and it seems trivial to add a check. Oh well, one more reason to use commit hashes rather than pkgver tags. (The other reason is, because upstreams themselves are quite capable of modifying tags and re-signing them without waiting for some attacker to play with the ref pointers.) Anyway, I learned something today. -- Eli Schwartz
Attachment:
signature.asc
Description: OpenPGP digital signature