On Fri, Mar 22 2019, Daniel Kahn Gillmor wrote: > On Wed 2019-03-20 23:35:48 +0100, Ævar Arnfjörð Bjarmason wrote: >> But e.g. if you've signed a v1.00 in foo.git, but also maintain bar.git >> and have a v2.00 there, I can be fooled in foo.git with your proposed >> change by having the v2.00 bar.git tag pushed to it (just, with the >> proposed change, not the other way around). > > Presumably the tool looking for the "most interesting new tag" already > has some sort of pattern that it looks for in a tag name (to avoid > accidentally ingesting some development-specific, non-release tag). > > So yes, this is true for upstreams which issue signed release tags on > multiple projects named with the generic form v1.2.3, but it is *not* > true of projects which name their tags the way that (for example) > GnuPG's upstream does (e.g. gnupg-2.2.14 and libgpg-error-1.36). > > In that case, and the matching pattern itself will exclude tags from > other repositories. > >> It *does* help with the "pass of an old tag [from the same repository]" >> problem, which I'd expect would realistically be the only threat model >> that matters (forcing a downgrade to an old buggy version), whereas some >> entirely different project is likely going to be next fed to some >> project-specific build infrastructure and then won't even build. > > I agree that a cross-project tag substitution attack is more exotic than > an in-project downgrade or freeze attack, but i'm not inclined to wager > on it never being exploitable. Why take that gamble? FWIW I wasn't arguing that this was a good thing ("just a point of clarification..."), just walking through and elaborating an exploitable case you mentioned so we're all on the same page as to what the current problem(s) are. >> I wonder if there's a more general fix to be found here that'll have >> nothing to do with GPG or signed tags per-se. A lot of people have this >> "given tags in the repo, what's the latest one?" problem. I think >> they'll mostly use the --sort option now, maybe some variant of that >> which for each <older>/<newer> tag in the chain also checked: >> >> git merge-base --is-ancestor <older> <newer> >> >> That would serve as a check for such rouge tags, even if none of them >> were signed, and a "they must be signed" option could be added, along >> with "start walking from here". > > I agree that this is a common tag verification use case, and i've seen > probably a dozen different attempts to do it which all fail in some > curious ways if you assume that the repository being pulled from is > malicious. > > I like the idea you're describing here, and would be happy to see some > reasonable, easy-to-use git subcommand that says something like "find > the most interesting tag that derives from the current HEAD". for some > version of "interesting", of course :) It would probably be a good start > to have "interesting" mean: > > * the tag name matches some particular pattern > > * the tag is cryptographically signed by at least one member of a > specific curated keyring > > * the tag is the "most recent" or "farthest descendant" (these are > subtly different, i'm not sure which one makes more sense) > > Anyway, the fact that there isn't an obvious perfect answer for how to > do this shouldn't stop git from offering a reasonable, well-vetted, > *good* answer. Because the current situation just means that every > project that cares about verifying signed tags makes up their own > approach, and i would happily bet that most of them get it wrong in some > corner case. > > And if there's a tool that does a sensible verification of some workflow > that we think is reasonable, that tool will also help to encourgae > projects to adopt that reasonable workflow. This is a good thing! > > --dkg