All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] tag-ref and tag object binding
@ 2016-01-25 21:22 Santiago Torres
  2016-01-26  9:35 ` Michael J Gruber
  0 siblings, 1 reply; 17+ messages in thread
From: Santiago Torres @ 2016-01-25 21:22 UTC (permalink / raw)
  To: Git

Hello everyone.

I've done some further research on the security properties of git
metadata and I think I've identified something that might be worth
discussing. In this case, The issue is related to the refs that point to
git tag objects. Specifically, the "loose" nature of tag refs might
possibly trick people into installing the wrong revision (version?) of a
file.

To elaborate, the ref of a tag object can be moved around in the same
way a branch can be moved around (either manually or by using git
commands). If someone with write access can modify where this ref points
to, and points it to another valid tag (e.g., an older, vulnerable
version), then many tools that work under the assumption of static tags
might mistakenly install/pull the wrong reivision of source code. I've
verified that this is possible to pull off in package managers such as
PIP, rubygems, gradle(maven), as well as git submodules tracking tags.

In order to stay loyal to the way files in the .git directory are
ordered, I don't think that making the ref file (or packed refs) files
differently is an option. However, I think that it could be possible to
store the "origin ref" in the git tag object, so tools can verify that
they are looking at the appropriate tag. There might also be a simpler
solution to this, and I would appreciate any feedback.

What do you guys think?

Thanks!
Santiago.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-25 21:22 [RFC] tag-ref and tag object binding Santiago Torres
@ 2016-01-26  9:35 ` Michael J Gruber
  2016-01-26 15:29   ` Santiago Torres
  0 siblings, 1 reply; 17+ messages in thread
From: Michael J Gruber @ 2016-01-26  9:35 UTC (permalink / raw)
  To: Santiago Torres, Git

Santiago Torres venit, vidit, dixit 25.01.2016 22:22:
> Hello everyone.
> 
> I've done some further research on the security properties of git
> metadata and I think I've identified something that might be worth
> discussing. In this case, The issue is related to the refs that point to
> git tag objects. Specifically, the "loose" nature of tag refs might
> possibly trick people into installing the wrong revision (version?) of a
> file.
> 
> To elaborate, the ref of a tag object can be moved around in the same
> way a branch can be moved around (either manually or by using git
> commands). If someone with write access can modify where this ref points
> to, and points it to another valid tag (e.g., an older, vulnerable
> version), then many tools that work under the assumption of static tags
> might mistakenly install/pull the wrong reivision of source code. I've
> verified that this is possible to pull off in package managers such as
> PIP, rubygems, gradle(maven), as well as git submodules tracking tags.
> 
> In order to stay loyal to the way files in the .git directory are
> ordered, I don't think that making the ref file (or packed refs) files
> differently is an option. However, I think that it could be possible to
> store the "origin ref" in the git tag object, so tools can verify that
> they are looking at the appropriate tag. There might also be a simpler
> solution to this, and I would appreciate any feedback.
> 
> What do you guys think?
> 
> Thanks!
> Santiago.

If you cannot trust those with write access to a repo that you are
pulling and installing from you might want to re-check where you are
pulling or installing from ;)

In fact, just like you shouldn't blindly download and install a tarball
(but check its signature) you shouldn't blindly pull and install from a
repo.

Your best bet is checking the signature of signed tags. Now, if you're
worried about someone maliciously pointing you to the wrong, correctly
signed tag then you should verify that the tag object contains the tag
"name" that you expect (for example by using "git verify-tag -v" or "git
cat-file -p"), since that is part of the signed content.

Michael

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26  9:35 ` Michael J Gruber
@ 2016-01-26 15:29   ` Santiago Torres
  2016-01-26 20:26     ` Jeff King
  0 siblings, 1 reply; 17+ messages in thread
From: Santiago Torres @ 2016-01-26 15:29 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Git

On Tue, Jan 26, 2016 at 10:35:34AM +0100, Michael J Gruber wrote:
> Santiago Torres venit, vidit, dixit 25.01.2016 22:22:
> > Hello everyone.
> > 
> > I've done some further research on the security properties of git
> > metadata and I think I've identified something that might be worth
> > discussing. In this case, The issue is related to the refs that point to
> > git tag objects. Specifically, the "loose" nature of tag refs might
> > possibly trick people into installing the wrong revision (version?) of a
> > file.
> > 
> > To elaborate, the ref of a tag object can be moved around in the same
> > way a branch can be moved around (either manually or by using git
> > commands). If someone with write access can modify where this ref points
> > to, and points it to another valid tag (e.g., an older, vulnerable
> > version), then many tools that work under the assumption of static tags
> > might mistakenly install/pull the wrong reivision of source code. I've
> > verified that this is possible to pull off in package managers such as
> > PIP, rubygems, gradle(maven), as well as git submodules tracking tags.
> > 
> > In order to stay loyal to the way files in the .git directory are
> > ordered, I don't think that making the ref file (or packed refs) files
> > differently is an option. However, I think that it could be possible to
> > store the "origin ref" in the git tag object, so tools can verify that
> > they are looking at the appropriate tag. There might also be a simpler
> > solution to this, and I would appreciate any feedback.
> > 
> > What do you guys think?
> > 
> > Thanks!
> > Santiago.
> 
> If you cannot trust those with write access to a repo that you are
> pulling and installing from you might want to re-check where you are
> pulling or installing from ;)

Yeah, I see your point, but mechanisms to ensure the server's origin can
be bypassed (e.g., a MITM). I don't think it would hurt to ensure the
source pointed to is the source itself. The tag signature can help us do
this.

> 
> In fact, just like you shouldn't blindly download and install a tarball
> (but check its signature) you shouldn't blindly pull and install from a
> repo.

Yep. As a matter of fact, many of these package managers can install
from a specific commit, which should be safer. However, I do think that
pointing to a tag is more "usable" given that they are human-readable.
Also, tags are usually meant to point to releases, so it follows its
design pattern doesn't it?. I think it wouldn't be a bad idea to provide
a hard-binding between tag-refs and tags themselves.

> 
> Your best bet is checking the signature of signed tags. Now, if you're
> worried about someone maliciously pointing you to the wrong, correctly
> signed tag then you should verify that the tag object contains the tag
> "name" that you expect (for example by using "git verify-tag -v" or "git
> cat-file -p"), since that is part of the signed content.

Yep, this is my intuition behind my proposal. While someone can manually
inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,
there's no mechanism to ensure that the ref is pointing to the intended
tag. I do believe that package managers and git submodules could check
whether the ref is pointing to the right tag with a small change in the
tag header. Although it would be up to each tool to implement this
check.

I don't think that an addition like this would get in the way of any
existing git workflow, and should be backwards-compatible right?

Thanks,
-Santiago.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26 15:29   ` Santiago Torres
@ 2016-01-26 20:26     ` Jeff King
  2016-01-26 21:13       ` Junio C Hamano
                         ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Jeff King @ 2016-01-26 20:26 UTC (permalink / raw)
  To: Santiago Torres; +Cc: Michael J Gruber, Git

On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:

> > If you cannot trust those with write access to a repo that you are
> > pulling and installing from you might want to re-check where you are
> > pulling or installing from ;)
> 
> Yeah, I see your point, but mechanisms to ensure the server's origin can
> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the
> source pointed to is the source itself. The tag signature can help us do
> this.

Right. I think the more interesting use case here is "I trust the
upstream repository owner, but I do not trust their hosting site of
choice."

> > Your best bet is checking the signature of signed tags. Now, if you're
> > worried about someone maliciously pointing you to the wrong, correctly
> > signed tag then you should verify that the tag object contains the tag
> > "name" that you expect (for example by using "git verify-tag -v" or "git
> > cat-file -p"), since that is part of the signed content.
> 
> Yep, this is my intuition behind my proposal. While someone can manually
> inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,
> there's no mechanism to ensure that the ref is pointing to the intended
> tag. I do believe that package managers and git submodules could check
> whether the ref is pointing to the right tag with a small change in the
> tag header. Although it would be up to each tool to implement this
> check.
> 
> I don't think that an addition like this would get in the way of any
> existing git workflow, and should be backwards-compatible right?

Doesn't this already exist?

  $ git cat-file tag v2.0.0
  object e156455ea49124c140a67623f22a393db62d5d98
  type commit
  tag v2.0.0
  tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700

  Git 2.0
  -----BEGIN PGP SIGNATURE-----
  [...]
  -----END PGP SIGNATURE-----

Tag objects already have a "tag" header, which is part of the signed
content. If you use "git verify-tag -v", you can check both that the
signature is valid and that the tag is the one you are expecting.

Of course, "verify-tag" could do this for you if you give it a refname,
too, but I think that may be the tip of the iceberg in terms of
automatic verification. In particular, verify-tag knows it was signed by
_somebody_, but it doesn't know what the signing policy is. As a human,
_I_ know that Junio is the right person to be signing the release tag,
but no tool does.

Git pretty much punts on all of these issues and assumes either a human
or a smarter tool is looking at the verification output. But I don't
think it would hurt to build in some features to let git automatically
check some things, if only to avoid callers duplicating work to
implement the checks themselves.

-Peff

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26 20:26     ` Jeff King
@ 2016-01-26 21:13       ` Junio C Hamano
  2016-01-28 21:09         ` Santiago Torres
  2016-01-26 21:44       ` Santiago Torres
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2016-01-26 21:13 UTC (permalink / raw)
  To: Jeff King; +Cc: Santiago Torres, Michael J Gruber, Git

Jeff King <peff@peff.net> writes:

> On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:
>
>> > If you cannot trust those with write access to a repo that you are
>> > pulling and installing from you might want to re-check where you are
>> > pulling or installing from ;)
>> 
>> Yeah, I see your point, but mechanisms to ensure the server's origin can
>> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the
>> source pointed to is the source itself. The tag signature can help us do
>> this.
>
> Right. I think the more interesting use case here is "I trust the
> upstream repository owner, but I do not trust their hosting site of
> choice."

Yup, and push-certificate is there to help with that issue.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26 20:26     ` Jeff King
  2016-01-26 21:13       ` Junio C Hamano
@ 2016-01-26 21:44       ` Santiago Torres
  2016-01-26 22:44       ` Junio C Hamano
  2016-01-27  7:23       ` Michael J Gruber
  3 siblings, 0 replies; 17+ messages in thread
From: Santiago Torres @ 2016-01-26 21:44 UTC (permalink / raw)
  To: Jeff King; +Cc: Michael J Gruber, Git

On Tue, Jan 26, 2016 at 03:26:51PM -0500, Jeff King wrote:
> On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:
> 
> > > If you cannot trust those with write access to a repo that you are
> > > pulling and installing from you might want to re-check where you are
> > > pulling or installing from ;)
> > 
> > Yeah, I see your point, but mechanisms to ensure the server's origin can
> > be bypassed (e.g., a MITM). I don't think it would hurt to ensure the
> > source pointed to is the source itself. The tag signature can help us do
> > this.
> 
> Right. I think the more interesting use case here is "I trust the
> upstream repository owner, but I do not trust their hosting site of
> choice."

Yes, I think this is another possible scenario. Thanks for pointing it
out.

> 
> > > Your best bet is checking the signature of signed tags. Now, if you're
> > > worried about someone maliciously pointing you to the wrong, correctly
> > > signed tag then you should verify that the tag object contains the tag
> > > "name" that you expect (for example by using "git verify-tag -v" or "git
> > > cat-file -p"), since that is part of the signed content.
> > 
> > Yep, this is my intuition behind my proposal. While someone can manually
> > inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,
> > there's no mechanism to ensure that the ref is pointing to the intended
> > tag. I do believe that package managers and git submodules could check
> > whether the ref is pointing to the right tag with a small change in the
> > tag header. Although it would be up to each tool to implement this
> > check.
> > 
> > I don't think that an addition like this would get in the way of any
> > existing git workflow, and should be backwards-compatible right?
> 
> Doesn't this already exist?
> 
>   $ git cat-file tag v2.0.0
>   object e156455ea49124c140a67623f22a393db62d5d98
>   type commit
>   tag v2.0.0
>   tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700
> 
>   Git 2.0
>   -----BEGIN PGP SIGNATURE-----
>   [...]
>   -----END PGP SIGNATURE-----
> 
> Tag objects already have a "tag" header, which is part of the signed
> content. If you use "git verify-tag -v", you can check both that the
> signature is valid and that the tag is the one you are expecting.

Oh, I inspected the tag object with cat-file, but I assumed this was
being inserted by the command itself (by "pretty printing"). This is
exactly what I was thinking.

> 
> Of course, "verify-tag" could do this for you if you give it a refname,
> too, but I think that may be the tip of the iceberg in terms of
> automatic verification. 

Yes, I think it could be a good first step though (maybe returning non-0
if the tag header could help in this case).

If this header exists, I think that package managers (and git
submodules) should use it to verify this metadata attacks don't take
place; it sounds rather simple.

> In particular, verify-tag knows it was signed by
> _somebody_, but it doesn't know what the signing policy is. As a human,
> _I_ know that Junio is the right person to be signing the release tag,
> but no tool does.

Yes, shipping a keychain might be helpful, I know the folks at I2P[1] do
that in their monotone repository. Maybe something similar could be an
extension to git? (using hooks, possibly?)

> 
> Git pretty much punts on all of these issues and assumes either a human
> or a smarter tool is looking at the verification output. 

Yeah, I agree. This works pretty well in some workflows (e.g., the one
in this very ML), but I have the feeling this is not the trend that
newer users of the tool are adopting.

> But I don't think it would hurt to build in some features to let git
> automatically check some things, if only to avoid callers duplicating
> work to implement the checks themselves.

Yeah, I think this check (and maybe others) could be quite simple to
integrate and lessen the workload on the git user. Inspecting each git
tag after recursively cloning might mitigate an attack like this, but it
sounds burdensome.

Thanks!
-Santiago.

[1]
https://geti2p.net/en/get-involved/guides/monotone#setting-up-trust-evaluation-hooks

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26 20:26     ` Jeff King
  2016-01-26 21:13       ` Junio C Hamano
  2016-01-26 21:44       ` Santiago Torres
@ 2016-01-26 22:44       ` Junio C Hamano
  2016-01-27  7:23       ` Michael J Gruber
  3 siblings, 0 replies; 17+ messages in thread
From: Junio C Hamano @ 2016-01-26 22:44 UTC (permalink / raw)
  To: Jeff King; +Cc: Santiago Torres, Michael J Gruber, Git

Jeff King <peff@peff.net> writes:

>> I don't think that an addition like this would get in the way of any
>> existing git workflow, and should be backwards-compatible right?
>
> Doesn't this already exist?
>
>   $ git cat-file tag v2.0.0
>   object e156455ea49124c140a67623f22a393db62d5d98
>   type commit
>   tag v2.0.0
>   tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700
>
>   Git 2.0
>   -----BEGIN PGP SIGNATURE-----
>   [...]
>   -----END PGP SIGNATURE-----
>
> Tag objects already have a "tag" header, which is part of the signed
> content. If you use "git verify-tag -v", you can check both that the
> signature is valid and that the tag is the one you are expecting.

Another thing worth mentioning is that "fsck" does not insist that
refs/tags/$NAME must have a "tag" line that says "tag $NAME", and
that is a very deliberate design decision.  A project may want to
allow multiple people tag the same commit with the same tagname and
publish all of them in the same ref hierarchy.  For example, while I
am away, Peff may make an emergency maintenance release and tag it
like so:

    $ git tag -s -m 'Git v2.7.1' v2.7.1 master
    $ git push $there tags/v2.7.1:tags/peff/v2.7.1 master

and announce to the list that he has cut a release, and published
his signed tag as peff/v2.7.1 in the public repository.  While
everybody in the project trusts Peff as much as they trust me, I
would still want to sign the same commit myself, endorsing what Peff
did for the project, when I come back, by doing something like:

    $ git tag -s -m 'Git v2.7.1' v2.7.1 peff/v2.7.1^0
    $ git push $there v2.7.1

In fact, I think "git describe" uses the name recorded in the
closest tag, not the refname such a tag is found at, when giveing a
name to the commit.  E.g.

    $ git tag foo v2.7.0
    $ git tag -d v2.7.0
    $ git describe master
    warning: tag 'v2.7.0' is really 'foo' here
    v2.7.0-170-ge572fef

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26 20:26     ` Jeff King
                         ` (2 preceding siblings ...)
  2016-01-26 22:44       ` Junio C Hamano
@ 2016-01-27  7:23       ` Michael J Gruber
  2016-01-27  7:33         ` Jeff King
  3 siblings, 1 reply; 17+ messages in thread
From: Michael J Gruber @ 2016-01-27  7:23 UTC (permalink / raw)
  To: Jeff King, Santiago Torres; +Cc: Git

Jeff King venit, vidit, dixit 26.01.2016 21:26:
> On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:
> 
>>> If you cannot trust those with write access to a repo that you are
>>> pulling and installing from you might want to re-check where you are
>>> pulling or installing from ;)
>>
>> Yeah, I see your point, but mechanisms to ensure the server's origin can
>> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the
>> source pointed to is the source itself. The tag signature can help us do
>> this.
> 
> Right. I think the more interesting use case here is "I trust the
> upstream repository owner, but I do not trust their hosting site of
> choice."
> 
>>> Your best bet is checking the signature of signed tags. Now, if you're
>>> worried about someone maliciously pointing you to the wrong, correctly
>>> signed tag then you should verify that the tag object contains the tag
>>> "name" that you expect (for example by using "git verify-tag -v" or "git
>>> cat-file -p"), since that is part of the signed content.
>>
>> Yep, this is my intuition behind my proposal. While someone can manually
>> inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,
>> there's no mechanism to ensure that the ref is pointing to the intended
>> tag. I do believe that package managers and git submodules could check
>> whether the ref is pointing to the right tag with a small change in the
>> tag header. Although it would be up to each tool to implement this
>> check.
>>
>> I don't think that an addition like this would get in the way of any
>> existing git workflow, and should be backwards-compatible right?
> 
> Doesn't this already exist?
> 
>   $ git cat-file tag v2.0.0
>   object e156455ea49124c140a67623f22a393db62d5d98
>   type commit
>   tag v2.0.0
>   tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700
> 
>   Git 2.0
>   -----BEGIN PGP SIGNATURE-----
>   [...]
>   -----END PGP SIGNATURE-----
> 
> Tag objects already have a "tag" header, which is part of the signed
> content. If you use "git verify-tag -v", you can check both that the
> signature is valid and that the tag is the one you are expecting.

Yes, that's what I described in my last paragraph, using the term
(embedded) tag "name" which is technically wrong (it's not the tag
object's name, which would be a sha1) but the natural term for users.

> Of course, "verify-tag" could do this for you if you give it a refname,
> too, but I think that may be the tip of the iceberg in terms of
> automatic verification. In particular, verify-tag knows it was signed by
> _somebody_, but it doesn't know what the signing policy is. As a human,
> _I_ know that Junio is the right person to be signing the release tag,
> but no tool does.
> 
> Git pretty much punts on all of these issues and assumes either a human
> or a smarter tool is looking at the verification output. But I don't
> think it would hurt to build in some features to let git automatically
> check some things, if only to avoid callers duplicating work to
> implement the checks themselves.

That is really a can of worms for several reasons:

- Do you fetch tags into refs/tags/ or refs/tags/upstream/ or wherever,
and which part of the tag refname should we check for?

We can DWIM that to the last part after / and allow "--tagname" to
override, of course.

- By all means, we need to avoid a false sense of security. "GOOD
SIGNATURE" in gpg terms is bad enough with the usual trust model when
users don't check who actually made that signature.

If you don't *really* check the signature then anyone can shove a signed
tag object under your nose with the *expected tag header* (tag "name")
so that there is no gain at all, unless you envison a scenario where Man
I. T. Middle can mess with refs but not objects.

So, for those who shy away from for-each-ref and such, we may add the
header check to verify-tag, with a big warning about the marginal gain
in security (or the requirements for an actual gain).

Michael

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27  7:23       ` Michael J Gruber
@ 2016-01-27  7:33         ` Jeff King
  2016-01-27  7:53           ` Michael J Gruber
  0 siblings, 1 reply; 17+ messages in thread
From: Jeff King @ 2016-01-27  7:33 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Santiago Torres, Git

On Wed, Jan 27, 2016 at 08:23:02AM +0100, Michael J Gruber wrote:

> > Tag objects already have a "tag" header, which is part of the signed
> > content. If you use "git verify-tag -v", you can check both that the
> > signature is valid and that the tag is the one you are expecting.
> 
> Yes, that's what I described in my last paragraph, using the term
> (embedded) tag "name" which is technically wrong (it's not the tag
> object's name, which would be a sha1) but the natural term for users.

Indeed. I should have read further back in the quoting. :)

> > Git pretty much punts on all of these issues and assumes either a human
> > or a smarter tool is looking at the verification output. But I don't
> > think it would hurt to build in some features to let git automatically
> > check some things, if only to avoid callers duplicating work to
> > implement the checks themselves.
> 
> That is really a can of worms for several reasons:
> [...]
> So, for those who shy away from for-each-ref and such, we may add the
> header check to verify-tag, with a big warning about the marginal gain
> in security (or the requirements for an actual gain).

Yeah, definitely. My thinking was that `verify-tag` could learn a series
of optional consistency checks, enabled by command line options, and
verifying programs (or humans) could turn them on to avoid having to
replicate them manually. So something like:

  git verify-tag \
    --verify-tagger-matches-key \
    --verify-tag-matches-ref \ # or --verify-tag-matches=v2.0.0
    v2.0.0

or to implement more specific policy, maybe an option to check for a
_specific_ tagger, either by email (as provided by gpg) or even key-id.

Those are all things that are not _too_ hard to do if you're willing to
parse gpg or git output, but we could make life easier for our callers.
And hopefully by asking for specific, concrete checks, it doesn't
introduce a false sense of security. I.e., we're not making a foolproof
tool; we're making building blocks that one could use for a more
foolproof tool.

-Peff

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27  7:33         ` Jeff King
@ 2016-01-27  7:53           ` Michael J Gruber
  2016-01-27  8:09             ` Jeff King
  2016-01-28 21:06             ` Santiago Torres
  0 siblings, 2 replies; 17+ messages in thread
From: Michael J Gruber @ 2016-01-27  7:53 UTC (permalink / raw)
  To: Jeff King; +Cc: Santiago Torres, Git

Jeff King venit, vidit, dixit 27.01.2016 08:33:
> On Wed, Jan 27, 2016 at 08:23:02AM +0100, Michael J Gruber wrote:
> 
>>> Tag objects already have a "tag" header, which is part of the signed
>>> content. If you use "git verify-tag -v", you can check both that the
>>> signature is valid and that the tag is the one you are expecting.
>>
>> Yes, that's what I described in my last paragraph, using the term
>> (embedded) tag "name" which is technically wrong (it's not the tag
>> object's name, which would be a sha1) but the natural term for users.
> 
> Indeed. I should have read further back in the quoting. :)
> 
>>> Git pretty much punts on all of these issues and assumes either a human
>>> or a smarter tool is looking at the verification output. But I don't
>>> think it would hurt to build in some features to let git automatically
>>> check some things, if only to avoid callers duplicating work to
>>> implement the checks themselves.
>>
>> That is really a can of worms for several reasons:
>> [...]
>> So, for those who shy away from for-each-ref and such, we may add the
>> header check to verify-tag, with a big warning about the marginal gain
>> in security (or the requirements for an actual gain).
> 
> Yeah, definitely. My thinking was that `verify-tag` could learn a series
> of optional consistency checks, enabled by command line options, and
> verifying programs (or humans) could turn them on to avoid having to
> replicate them manually. So something like:
> 
>   git verify-tag \
>     --verify-tagger-matches-key \
>     --verify-tag-matches-ref \ # or --verify-tag-matches=v2.0.0
>     v2.0.0
> 
> or to implement more specific policy, maybe an option to check for a
> _specific_ tagger, either by email (as provided by gpg) or even key-id.
> 
> Those are all things that are not _too_ hard to do if you're willing to
> parse gpg or git output, but we could make life easier for our callers.
> And hopefully by asking for specific, concrete checks, it doesn't
> introduce a false sense of security. I.e., we're not making a foolproof
> tool; we're making building blocks that one could use for a more
> foolproof tool.

OK, let's make a tool that helps fooling as well as proofing :)

I'll look into the tag header check. Maybe "--check-tagname"? "check"
seems to imply less than "verify".

As for the gpg related stuff: We provide the full diagnostic output from
gpg on request. But I think a mismatch between the signing key's uid and
the taggers' name/email is more common than not, and on the other hand a
signature by a key identified by its uid is meaningless unless you keep
your keyring tidy... We could punt on that and let users identify the
key by any means that gpg allows, of course, and check that the
signature comes from whatever "gpg --list-key <userspecified>" gives as
long as it's unique.

But maybe I'm biased by my zoo of uids/emails addresses/full name
spellings... and general paranoia regarding the term "verify" ;)

Michael

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27  7:53           ` Michael J Gruber
@ 2016-01-27  8:09             ` Jeff King
  2016-01-27  9:14               ` Michael J Gruber
  2016-01-28 21:06             ` Santiago Torres
  1 sibling, 1 reply; 17+ messages in thread
From: Jeff King @ 2016-01-27  8:09 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Santiago Torres, Git

On Wed, Jan 27, 2016 at 08:53:08AM +0100, Michael J Gruber wrote:

> > Yeah, definitely. My thinking was that `verify-tag` could learn a series
> > of optional consistency checks, enabled by command line options, and
> > verifying programs (or humans) could turn them on to avoid having to
> > replicate them manually. So something like:
> > 
> >   git verify-tag \
> >     --verify-tagger-matches-key \
> >     --verify-tag-matches-ref \ # or --verify-tag-matches=v2.0.0
> >     v2.0.0
> > 
> > or to implement more specific policy, maybe an option to check for a
> > _specific_ tagger, either by email (as provided by gpg) or even key-id.
> > 
> > Those are all things that are not _too_ hard to do if you're willing to
> > parse gpg or git output, but we could make life easier for our callers.
> > And hopefully by asking for specific, concrete checks, it doesn't
> > introduce a false sense of security. I.e., we're not making a foolproof
> > tool; we're making building blocks that one could use for a more
> > foolproof tool.
> 
> OK, let's make a tool that helps fooling as well as proofing :)
> 
> I'll look into the tag header check. Maybe "--check-tagname"? "check"
> seems to imply less than "verify".

Yeah, I think that is fine (I actually wrote --check originally; I'm not
quite sure why I decided to change it).

> As for the gpg related stuff: We provide the full diagnostic output from
> gpg on request. But I think a mismatch between the signing key's uid and
> the taggers' name/email is more common than not,

Is it? I'd think if you are using that name with a signed tag, you would
bother to issue (and get people to sign) the matching uid. Certainly it
is the case for git and linux signatures, but I admit that it a pretty
small sampling size.

The bigger issue is that gpg seems to give us only _one_ uid, when there
may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a
sub-key that has several uids associated with it. The one that "git
verify-tag --raw" shows from gpg is gitster@pobox.com, which is good,
but I think that's just because it happens to be the first uid. Or maybe
there is some gpg arcana going on that I don't know about.

> and on the other hand a
> signature by a key identified by its uid is meaningless unless you keep
> your keyring tidy... We could punt on that and let users identify the
> key by any means that gpg allows, of course, and check that the
> signature comes from whatever "gpg --list-key <userspecified>" gives as
> long as it's unique.

Right, I think it's an open question whether people actually participate
in the web of trust. I don't have a good signature path to Junio's key,
but I happen to know what it is based on past interaction.

But then, I also do not really verify tags. Why would I? I routinely
fetch and run "make" on the result, and there is no cryptographic
protection there at all. Verifying tag signatures after a release seems
all but pointless. :)

I think for any of this to be useful, it has to be part of some tool
that is very opinionated on policy. E.g., imagine a post-fetch hook that
validated that each incoming commit was signed, and that the signer was
part of a whitelisted group of keys that you "somehow" got hold of
out-of-band for your project. That is not that useful for an open-source
project, but I could see the appeal for a proprietary development
environment.

-Peff

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27  8:09             ` Jeff King
@ 2016-01-27  9:14               ` Michael J Gruber
  2016-01-27 18:10                 ` Junio C Hamano
  0 siblings, 1 reply; 17+ messages in thread
From: Michael J Gruber @ 2016-01-27  9:14 UTC (permalink / raw)
  To: Jeff King; +Cc: Santiago Torres, Git

Jeff King venit, vidit, dixit 27.01.2016 09:09:
> On Wed, Jan 27, 2016 at 08:53:08AM +0100, Michael J Gruber wrote:
> 
>>> Yeah, definitely. My thinking was that `verify-tag` could learn a series
>>> of optional consistency checks, enabled by command line options, and
>>> verifying programs (or humans) could turn them on to avoid having to
>>> replicate them manually. So something like:
>>>
>>>   git verify-tag \
>>>     --verify-tagger-matches-key \
>>>     --verify-tag-matches-ref \ # or --verify-tag-matches=v2.0.0
>>>     v2.0.0
>>>
>>> or to implement more specific policy, maybe an option to check for a
>>> _specific_ tagger, either by email (as provided by gpg) or even key-id.
>>>
>>> Those are all things that are not _too_ hard to do if you're willing to
>>> parse gpg or git output, but we could make life easier for our callers.
>>> And hopefully by asking for specific, concrete checks, it doesn't
>>> introduce a false sense of security. I.e., we're not making a foolproof
>>> tool; we're making building blocks that one could use for a more
>>> foolproof tool.
>>
>> OK, let's make a tool that helps fooling as well as proofing :)
>>
>> I'll look into the tag header check. Maybe "--check-tagname"? "check"
>> seems to imply less than "verify".
> 
> Yeah, I think that is fine (I actually wrote --check originally; I'm not
> quite sure why I decided to change it).
> 
>> As for the gpg related stuff: We provide the full diagnostic output from
>> gpg on request. But I think a mismatch between the signing key's uid and
>> the taggers' name/email is more common than not,
> 
> Is it? I'd think if you are using that name with a signed tag, you would
> bother to issue (and get people to sign) the matching uid. Certainly it
> is the case for git and linux signatures, but I admit that it a pretty
> small sampling size.
> 
> The bigger issue is that gpg seems to give us only _one_ uid, when there
> may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a
> sub-key that has several uids associated with it. The one that "git
> verify-tag --raw" shows from gpg is gitster@pobox.com, which is good,
> but I think that's just because it happens to be the first uid. Or maybe
> there is some gpg arcana going on that I don't know about.

You do not sign with a uid, you sign with a (sub)key, and the tag is
signed with Junio's primary key. His subkey is encryption only.

uids do not identify keys, you can add and delete them at will without
changing the primary key id. To help recognize ("identify") a key, gpg
displays the uid with the most recent self-signature, which is usually
the most "recent uid".

You do sign a uid.

So, if you want to be sure that a tag is signed "with a specific uid" by
relying on signatures from a set of signers, you would really need to
check that the key that signed the tag has a signature on the correct
uid. Having a signed key with the right uid in it doesn't mean much
unlss the right uid is signed.

E.g., I have a key with many signatures, and I could have Junio's uid on
it in a minute without invalidating any of those signatures.

>> and on the other hand a
>> signature by a key identified by its uid is meaningless unless you keep
>> your keyring tidy... We could punt on that and let users identify the
>> key by any means that gpg allows, of course, and check that the
>> signature comes from whatever "gpg --list-key <userspecified>" gives as
>> long as it's unique.
> 
> Right, I think it's an open question whether people actually participate
> in the web of trust. I don't have a good signature path to Junio's key,
> but I happen to know what it is based on past interaction.
> 
> But then, I also do not really verify tags. Why would I? I routinely
> fetch and run "make" on the result, and there is no cryptographic
> protection there at all. Verifying tag signatures after a release seems
> all but pointless. :)

No signature protects us from our own dogfood :)

> I think for any of this to be useful, it has to be part of some tool
> that is very opinionated on policy. E.g., imagine a post-fetch hook that
> validated that each incoming commit was signed, and that the signer was
> part of a whitelisted group of keys that you "somehow" got hold of
> out-of-band for your project. That is not that useful for an open-source
> project, but I could see the appeal for a proprietary development
> environment.

That one is easy already by setting "GNUPGHOME" to a special dir with a
small keyring and tight trust settings (or having a dedicated account on
the incoming side in the first place).

Michael

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27  9:14               ` Michael J Gruber
@ 2016-01-27 18:10                 ` Junio C Hamano
  2016-01-27 20:09                   ` Michael J Gruber
  0 siblings, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2016-01-27 18:10 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Jeff King, Santiago Torres, Git

Michael J Gruber <git@drmicha.warpmail.net> writes:

> Jeff King venit, vidit, dixit 27.01.2016 09:09:
>
>> The bigger issue is that gpg seems to give us only _one_ uid, when there
>> may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a
>> sub-key that has several uids associated with it. The one that "git
>> verify-tag --raw" shows from gpg is gitster@pobox.com, which is good,
>> but I think that's just because it happens to be the first uid. Or maybe
>> there is some gpg arcana going on that I don't know about.
>
> You do not sign with a uid, you sign with a (sub)key, and the tag is
> signed with Junio's primary key. His subkey is encryption only.

Hmm, actually I meant to sign my tags with signing subkey, not the
primary one, but I may have made a mistake.

> You do sign a uid.
>
> So, if you want to be sure that a tag is signed "with a specific uid" by
> relying on signatures from a set of signers, you would really need to
> check that the key that signed the tag has a signature on the correct
> uid. Having a signed key with the right uid in it doesn't mean much
> unlss the right uid is signed.
>
> E.g., I have a key with many signatures, and I could have Junio's uid on
> it in a minute without invalidating any of those signatures.

I have signatures on my primary key from others, and my signing key
is signed by my primary key and by no other keys.  Here is an
abbreviated output from running "gpg --list-sigs 96AFE6CB":

pub   4096R/713660A7 2011-10-01
uid                  Junio C Hamano <gitster@pobox.com>
sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>
sig          93674C40 2011-10-04  Theodore Y. Ts'o <tytso@mit.edu>
sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>
sig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>
sig          02A80207 2011-10-05  Andrew Morton (akpm) <akpm@linux-foundation.org>
uid                  Junio C Hamano <junio@pobox.com>
sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>
sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>
sig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>
uid                  Junio C Hamano <jch@google.com>
sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>
sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>
sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>
sub   4096R/833262C4 2011-10-01
sig          713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
sub   4096R/96AFE6CB 2011-10-03 [expires: 2017-09-20]
sig          713660A7 2015-09-21  Junio C Hamano <gitster@pobox.com>
sub   4096R/B3F7CAC9 2014-09-20 [expires: 2017-09-19]
sig          713660A7 2014-09-20  Junio C Hamano <gitster@pobox.com>

So I understand that the way you trust 96AFE6CB has to be indirect.
You may have somebody's key you know belongs to that somebody you
trust (say, Linus) in the list of signers of 713660A7 (my primary),
and you know 96AFE6CB is a key I use because it is signed by my
primary key.

You can add a subkey to your keyring a uid that says "Junio", but
the signature on that subkey would not have a signature by me you
can verify by following the web of trust.  You are correct to point
out that "this key claims to be by somebody, and it has some
signature" is not a sufficient reason for you to trust it.

> That one is easy already by setting "GNUPGHOME" to a special dir with a
> small keyring and tight trust settings (or having a dedicated account on
> the incoming side in the first place).

Yes, I understand that the above is how automated services per
project should be set up, with a dedicated verification keyring that
holds keys the project trusts.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27 18:10                 ` Junio C Hamano
@ 2016-01-27 20:09                   ` Michael J Gruber
  2016-01-27 20:21                     ` Jeff King
  0 siblings, 1 reply; 17+ messages in thread
From: Michael J Gruber @ 2016-01-27 20:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Santiago Torres, Git

Junio C Hamano venit, vidit, dixit 27.01.2016 19:10:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>> Jeff King venit, vidit, dixit 27.01.2016 09:09:
>>
>>> The bigger issue is that gpg seems to give us only _one_ uid, when there
>>> may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a
>>> sub-key that has several uids associated with it. The one that "git
>>> verify-tag --raw" shows from gpg is gitster@pobox.com, which is good,
>>> but I think that's just because it happens to be the first uid. Or maybe
>>> there is some gpg arcana going on that I don't know about.
>>
>> You do not sign with a uid, you sign with a (sub)key, and the tag is
>> signed with Junio's primary key. His subkey is encryption only.
> 
> Hmm, actually I meant to sign my tags with signing subkey, not the
> primary one, but I may have made a mistake.

Oops, I needed to refresh my copy of your key, sorry. You did sign 2.7.0
with the subkey 0xB0B5E88696AFE6CB

>> You do sign a uid.
>>
>> So, if you want to be sure that a tag is signed "with a specific uid" by
>> relying on signatures from a set of signers, you would really need to
>> check that the key that signed the tag has a signature on the correct
>> uid. Having a signed key with the right uid in it doesn't mean much
>> unlss the right uid is signed.
>>
>> E.g., I have a key with many signatures, and I could have Junio's uid on
>> it in a minute without invalidating any of those signatures.
> 
> I have signatures on my primary key from others, and my signing key
> is signed by my primary key and by no other keys.  Here is an
> abbreviated output from running "gpg --list-sigs 96AFE6CB":
> 
> pub   4096R/713660A7 2011-10-01
> uid                  Junio C Hamano <gitster@pobox.com>
> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>
> sig          93674C40 2011-10-04  Theodore Y. Ts'o <tytso@mit.edu>
> sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>
> sig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>
> sig          02A80207 2011-10-05  Andrew Morton (akpm) <akpm@linux-foundation.org>
> uid                  Junio C Hamano <junio@pobox.com>
> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>
> sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>
> sig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>
> uid                  Junio C Hamano <jch@google.com>
> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>
> sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>
> sub   4096R/833262C4 2011-10-01
> sig          713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>
> sub   4096R/96AFE6CB 2011-10-03 [expires: 2017-09-20]
> sig          713660A7 2015-09-21  Junio C Hamano <gitster@pobox.com>
> sub   4096R/B3F7CAC9 2014-09-20 [expires: 2017-09-19]
> sig          713660A7 2014-09-20  Junio C Hamano <gitster@pobox.com>
> 
> So I understand that the way you trust 96AFE6CB has to be indirect.
> You may have somebody's key you know belongs to that somebody you
> trust (say, Linus) in the list of signers of 713660A7 (my primary),
> and you know 96AFE6CB is a key I use because it is signed by my
> primary key.
> 
> You can add a subkey to your keyring a uid that says "Junio", but
> the signature on that subkey would not have a signature by me you
> can verify by following the web of trust.  You are correct to point
> out that "this key claims to be by somebody, and it has some
> signature" is not a sufficient reason for you to trust it.

"subkey" and "uid" are different things. You bind a subkey to your
primary key with that self-signature. subkeys don't carry any other
signatures.

A primary key "carries" the uids, and whenever someone "signs your key"
they in fact sign a specific uid - usually all, resulting in multiple
signatures, one for each uid of the (primary) key.

A key is usually considered trusted if it carries "a" signature from a
trusted key.

So, assuming my key carries a signature from a trusted key to at least
one uid, it would be trusted no matter what (fake) uids I add to it later.

>> That one is easy already by setting "GNUPGHOME" to a special dir with a
>> small keyring and tight trust settings (or having a dedicated account on
>> the incoming side in the first place).
> 
> Yes, I understand that the above is how automated services per
> project should be set up, with a dedicated verification keyring that
> holds keys the project trusts.

Michael

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27 20:09                   ` Michael J Gruber
@ 2016-01-27 20:21                     ` Jeff King
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff King @ 2016-01-27 20:21 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Junio C Hamano, Santiago Torres, Git

On Wed, Jan 27, 2016 at 09:09:31PM +0100, Michael J Gruber wrote:

> "subkey" and "uid" are different things. You bind a subkey to your
> primary key with that self-signature. subkeys don't carry any other
> signatures.
> 
> A primary key "carries" the uids, and whenever someone "signs your key"
> they in fact sign a specific uid - usually all, resulting in multiple
> signatures, one for each uid of the (primary) key.
> 
> A key is usually considered trusted if it carries "a" signature from a
> trusted key.
> 
> So, assuming my key carries a signature from a trusted key to at least
> one uid, it would be trusted no matter what (fake) uids I add to it later.

Right. I think I didn't do a good job of explaining myself earlier, so
let me try to rephrase.

When we look at the v2.7 tag, GPG sees that we are signed by Junio's
subkey, 96AFE6CB. It then knows that belongs to the main public key
713660A7, because the main key signed the subkey. And then it sees that
there are several uids for that main key, each with their own signatures
by other people.

So of the three uids that I have for that key:

  pub   4096R/713660A7 2011-10-01
  uid                  Junio C Hamano <gitster@pobox.com>
  uid                  Junio C Hamano <jch@google.com>
  uid                  Junio C Hamano <junio@pobox.com>

it reports back to git only one (the pobox.com), which we relay to the
user via --raw. If we wanted to check that the key matches the "tagger"
header, that works. But why did gpg return that first uid, and not any
of the others? We would ideally see all of them, and consider it OK if
it matches any uid (assuming that uid is sufficiently signed for gpg to
consider it valid).

Weirder, if you _don't_ use "--raw", the human-readable output gives us
all of the uids as "aka" lines:

  $ git verify-tag v2.7.0
  $ git verify-tag v2.7.0
  gpg: Signature made Mon 04 Jan 2016 05:08:12 PM EST using RSA key ID 96AFE6CB
  gpg: Good signature from "Junio C Hamano <gitster@pobox.com>"
  gpg:                 aka "Junio C Hamano <jch@google.com>"
  gpg:                 aka "Junio C Hamano <junio@pobox.com>"

  $ git verify-tag --raw v2.7.0
  [GNUPG:] SIG_ID xFANmHj+QJ1gwIcoRuT5BF/y8H4 2016-01-04 1451945292
  [GNUPG:] GOODSIG B0B5E88696AFE6CB Junio C Hamano <gitster@pobox.com>
  [GNUPG:] VALIDSIG E1F036B1FEE7221FC778ECEFB0B5E88696AFE6CB 2016-01-04 1451945292 0 4 0 1 2 00 96E07AF25771955980DAD10020D04E5A713660A7
  [GNUPG:] TRUST_FULLY

It seems like we should be able to get the raw-output to tell us all of
those uids. I guess it is not the end of the world to go back to gpg and
say "give me all of the valid uids that match this signing key", but it
seems silly to have to do so.

-Peff

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-27  7:53           ` Michael J Gruber
  2016-01-27  8:09             ` Jeff King
@ 2016-01-28 21:06             ` Santiago Torres
  1 sibling, 0 replies; 17+ messages in thread
From: Santiago Torres @ 2016-01-28 21:06 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Jeff King, Git

Hello, sorry for being MIA yesterday among all this movement...

On Wed, Jan 27, 2016 at 08:53:08AM +0100, Michael J Gruber wrote:
> Jeff King venit, vidit, dixit 27.01.2016 08:33:
> > On Wed, Jan 27, 2016 at 08:23:02AM +0100, Michael J Gruber wrote:
> > 
> >>> Tag objects already have a "tag" header, which is part of the signed
> >>> content. If you use "git verify-tag -v", you can check both that the
> >>> signature is valid and that the tag is the one you are expecting.
> >>
> >> Yes, that's what I described in my last paragraph, using the term
> >> (embedded) tag "name" which is technically wrong (it's not the tag
> >> object's name, which would be a sha1) but the natural term for users.
> > 
> > Indeed. I should have read further back in the quoting. :)
> > 
> >>> Git pretty much punts on all of these issues and assumes either a human
> >>> or a smarter tool is looking at the verification output. But I don't
> >>> think it would hurt to build in some features to let git automatically
> >>> check some things, if only to avoid callers duplicating work to
> >>> implement the checks themselves.
> >>
> >> That is really a can of worms for several reasons:
> >> [...]
> >> So, for those who shy away from for-each-ref and such, we may add the
> >> header check to verify-tag, with a big warning about the marginal gain
> >> in security (or the requirements for an actual gain).
> > 
> > Yeah, definitely. My thinking was that `verify-tag` could learn a series
> > of optional consistency checks, enabled by command line options, and
> > verifying programs (or humans) could turn them on to avoid having to
> > replicate them manually. So something like:
> > 
> >   git verify-tag \
> >     --verify-tagger-matches-key \
> >     --verify-tag-matches-ref \ # or --verify-tag-matches=v2.0.0
> >     v2.0.0
> > 
> > or to implement more specific policy, maybe an option to check for a
> > _specific_ tagger, either by email (as provided by gpg) or even key-id.
> > 
> > Those are all things that are not _too_ hard to do if you're willing to
> > parse gpg or git output, but we could make life easier for our callers.
> > And hopefully by asking for specific, concrete checks, it doesn't
> > introduce a false sense of security. I.e., we're not making a foolproof
> > tool; we're making building blocks that one could use for a more
> > foolproof tool.
> 
> OK, let's make a tool that helps fooling as well as proofing :)
> 
> I'll look into the tag header check. Maybe "--check-tagname"? "check"
> seems to imply less than "verify".

This seems like exactly what I was thinking of. What I believe would be
helpful is to provide upstream tools the means to automatically verify tags
(--check-tagname could return non-0 if the tagname doesn't match), could
this possibly be the default behavior (--no-check-tagname instead)?
What worries me is something like this experiment with pip: 

(git-tag2) santiago@LykOS:~$ pip install -e git+https://github.com/santiagotorres/django/@1.8.3#egg=django
Obtaining django from

git+https://github.com/santiagotorres/django/@1.8.3#egg=django
  Cloning https://github.com/santiagotorres/django/ (to 1.8.3) to
  ./.virtualenvs/git-tag2/src/django
  Installing collected packages: django
    Running setup.py develop for django
Successfully installed django
(git-tag2) santiago@LykOS:~$ django-admin.py --version
1.4.10

I only had to swap the tag refs and push for this simulation. Needless
to say, this deprectated django version (1.4.10) is vulnerable to a wide
range known exploits that include session hijacking, DoS, "MySQL
typecasting" and XSS.  And the person who served this tampered tag could
exploit the webserver right away (knows who got this vulnerable
package).

Of course, this could also trick a CI system and have people package the
wrong version of django.

I agree that nothing beats manual inspection of a paranoid developer,
but these tools are widely used today and could avoid these edge cases.

> 
> As for the gpg related stuff: We provide the full diagnostic output from
> gpg on request. But I think a mismatch between the signing key's uid and
> the taggers' name/email is more common than not, and on the other hand a
> signature by a key identified by its uid is meaningless unless you keep
> your keyring tidy... We could punt on that and let users identify the
> key by any means that gpg allows, of course, and check that the
> signature comes from whatever "gpg --list-key <userspecified>" gives as
> long as it's unique.
> 
> But maybe I'm biased by my zoo of uids/emails addresses/full name
> spellings... and general paranoia regarding the term "verify" ;)

Yeah, I believe the gpg related stuff might be a little out of scope. I
think, for the sake of this RFC, that we could assume that tools/people
have acess to the right key and could perform verification. As it was
already pointed out, key distribution and a project-specific gpg
keychain could be integrated.

The problem I see is that, even with the right key and a proper
signature, the tag metadata can still be modified and it wouldn't be
detected.

Thanks!
-Santiago.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] tag-ref and tag object binding
  2016-01-26 21:13       ` Junio C Hamano
@ 2016-01-28 21:09         ` Santiago Torres
  0 siblings, 0 replies; 17+ messages in thread
From: Santiago Torres @ 2016-01-28 21:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Michael J Gruber, Git

On Tue, Jan 26, 2016 at 01:13:16PM -0800, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
> 
> > On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:
> >
> >> > If you cannot trust those with write access to a repo that you are
> >> > pulling and installing from you might want to re-check where you are
> >> > pulling or installing from ;)
> >> 
> >> Yeah, I see your point, but mechanisms to ensure the server's origin can
> >> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the
> >> source pointed to is the source itself. The tag signature can help us do
> >> this.
> >
> > Right. I think the more interesting use case here is "I trust the
> > upstream repository owner, but I do not trust their hosting site of
> > choice."
> 
> Yup, and push-certificate is there to help with that issue.

Yes, I agree, but wouldn't this provide an in-band solution to this
very particular scenario. In order to provide the spureous tag, you have
to provide the tagname it should be pointing to (or tamper with the tag
object).

Push certificates can address many other sorts of attacks, but are not
in-band in this sense are they?

Thanks!
-Santiago.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2016-01-28 21:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-25 21:22 [RFC] tag-ref and tag object binding Santiago Torres
2016-01-26  9:35 ` Michael J Gruber
2016-01-26 15:29   ` Santiago Torres
2016-01-26 20:26     ` Jeff King
2016-01-26 21:13       ` Junio C Hamano
2016-01-28 21:09         ` Santiago Torres
2016-01-26 21:44       ` Santiago Torres
2016-01-26 22:44       ` Junio C Hamano
2016-01-27  7:23       ` Michael J Gruber
2016-01-27  7:33         ` Jeff King
2016-01-27  7:53           ` Michael J Gruber
2016-01-27  8:09             ` Jeff King
2016-01-27  9:14               ` Michael J Gruber
2016-01-27 18:10                 ` Junio C Hamano
2016-01-27 20:09                   ` Michael J Gruber
2016-01-27 20:21                     ` Jeff King
2016-01-28 21:06             ` Santiago Torres

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.