I don't think there is an issue the way you have tried to describe
this scenario.

On Sat, Nov 24, 2012 at 3:12 AM, Michael Hirshleifer <111...@caltech.edu> wrote:
> Evil Guy creates 2 files, 1 evil and 1 innocuous, with the same SHA-1
> checksum (including Git header). Mr. Evil creates a local branch with an
> innocuous name like “test-bugfix”, and adds a commit containing a reference
> to the evil file. Separately, using a sockpuppet, Evil Guy creates an
> innocuous bugfix (very likely to be accepted) containing the innocuous file,
> and submits it to Good Guy. Before Good Guy can commit the bugfix, Evil Guy
> pushes the evil branch to Github, and then immediately deletes it; or
> equivalently --force pushes any innocuous commit on top of it. (This is
> unlikely to arouse suspicion, and he can always say he deleted it because it
> didn’t work.)

Here you assume Evil Guy has write access to the same repository as
Good Guy. Lets assume this is possible, e.g. Evil Guy is actually
impersonating White Hat because he managed to steal White Hat's
credentials through a compromised host. Typically Evil Guy doesn't
have write access to Good Guy's repository, and thus can't introduce
objects into it without Good Guy being the one that creates the

But lets just keep he assumption that Evil Guy can write to the same
repository as Good Guy, and that he managed to create the bad branch
and delete it, leaving the bad object in an unreachable state for 2

> Git keeps unreferenced objects around for a few weeks, so when Good Guy
> commits the patch and pushes to Github, an object with an sha1sum that
> matches the good file will already exist in the main repository. Since Git
> keeps the local copy of files when sha1sums match, the main Github
> repository will then contain the evil file associated with Good Guy’s
> commit. Any users cloning from Github will get the evil version. This is an
> exploit.

Typically... Git will fail with an error message when Good Guy pushes.
Good Guy's client will (rightly) believe that the object doesn't exist
on the remote side, after all it is unreachable. So his client will
include it in the pack being transmitted during push. When this pack
arrives on the remote side, the remote will identify it already has an
object named the same as an object coming in the pack. The remote will
do a byte-for-byte compare of both objects. As soon as a single byte
differs, it will abort with an error.

At this point Good Guy can't push to his repository. `git gc
--expire=now` will fix the repository by removing the unreachable
object, at which point Evil Guy's evil object is gone.

> And Good Guy’s local repository will contain the good file; he will not
> notice anything amiss unless he nukes his local repository and clones from
> Github again. Even when the compromise is discovered, there will be no
> reason to suspect Evil Guy; the evil file seems to have been committed by
> Good Guy.

See above. Good Guy would have noticed something is amiss because the
object he sent already existed and didn't match.

> Previous discussion about hash collisions in Git seems to conclude that they
> aren’t a security threat. See
> http://stackoverflow.com/questions/9392365/how-would-git-handle-a-sha-1-collision-on-a-blob/9392525#9392525,
> Linus Torvalds arguing that Git’s security doesn’t depend on SHA-1 collision
> resistance.

This is largely true because there are additional defenses (e.g. the
byte for byte compare on identical objects), and for projects like the
Linux kernel there are many eyes looking at files all of the time.
Anything that is amiss would be announced quickly on LKML and
discussed until the root cause is identified and resolved.
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to