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.