Patch applies fake diffs from commit messages

· devtools · Source ↗

TLDR

  • GNU patch applies diff-shaped text embedded in commit messages when consuming GitHub’s .patch URLs, creating files never part of the real commit.

Key Takeaways

  • GitHub exposes mail-style patches at .patch URLs; wget + patch -p1 is a common, non-exotic workflow affected by this behavior.
  • A commit’s real diff and any unified diff embedded in the commit message are both applied by GNU patch with no separation.
  • The author reproduced targeting .git/hooks/post-applypatch; GNU patch accepted it, though git apply and git am rejected .git/... paths.
  • git apply and git am still accepted injected diffs for ordinary working-tree files, so switching tools is only a partial mitigation.
  • Root cause ownership is unresolved: GNU patch, GitHub’s .patch export format, or the broader mail-patch format contract could each be responsible.

Hacker News Comment Review

  • A practical workaround exists: use the .diff extension instead of .patch on GitHub commit URLs to get hunks only, bypassing the commit message entirely.
  • Commenters split on severity: those who trust patch sources see little added risk since a rogue file in the body looks identical to one in the real diff; others note the issue is the unsafe composition of two individually permissive systems.
  • git-am parses message-vs-patch boundaries using ---, diff -, or Index: line prefixes with no escaping, making injected unindented diffs structurally indistinguishable from real ones.

Notable Comments

  • @holotherapper: “Diff format being too forgiving and commit messages being too permissive are each fine on their own. The bug is the composition.”
  • @jolmg: Switching from .patch to .diff in the GitHub URL strips the commit message entirely, removing the attack surface for this class of injection.

Original | Discuss on HN