A place to cache linked articles (think custom and personal wayback machine)
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.md 18KB

il y a 9 mois
il y a 9 mois
il y a 9 mois
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. title: Unsigned Commits
  2. url: https://blog.glyph.im/2024/01/unsigned-commits.html
  3. hash_url: ce5fdc61fd66cdb9ce548fb543eba986
  4. archive_date: 2024-01-25
  5. og_image: https://blog.glyph.im/images/back9.png
  6. description: Deciphering Glyph, the blog of Glyph Lefkowitz.
  7. favicon: https://blog.glyph.im/images/favicon.ico
  8. language: en_US
  9. <p>I am going to tell you why I don’t think you should sign your Git commits, even
  10. though doing so with SSH keys is now easier than ever. But first, to
  11. contextualize my objection, I have a brief hypothetical for you, and then a bit
  12. of history from the evolution of security on the web.</p>
  13. <hr>
  14. <p><img alt="paper reading “Sign Here:” with a pen poised over it" src="https://blog.glyph.im/images/just-sign-here.jpeg"></p>
  15. <hr>
  16. <p>It seems like these days, everybody’s signing all different kinds of papers.</p>
  17. <p>Bank forms, permission slips, power of attorney; it seems like if you want to
  18. securely validate a document, you’ve gotta sign it.</p>
  19. <p>So I have invented a machine that automatically signs every document on your
  20. desk, just in case it needs your signature. Signing is good for security, so
  21. you should probably get one, and turn it on, just in case something needs your
  22. signature on it.</p>
  23. <p>We also want to make sure that verifying your signature is easy, so we will
  24. have them all notarized and duplicates stored permanently and publicly for
  25. future reference.</p>
  26. <p>No? Not interested?</p>
  27. <hr>
  28. <p>Hopefully, that sounded like a silly idea to you.</p>
  29. <p>Most adults in modern civilization have learned that signing your name to a
  30. document has an <em>effect</em>. It is not merely decorative; the words in the
  31. document being signed have some specific meaning and can be enforced against
  32. you.</p>
  33. <p>In some ways the metaphor of “signing” in cryptography is bad. One does not
  34. “sign” things with “keys” in real life. But here, it is spot on: a
  35. cryptographic signature can have an effect.</p>
  36. <p>It should be an <em>input</em> to some software, one that is acted upon. Software
  37. does a thing differently depending on the presence or absence of a signature.
  38. If it doesn’t, the signature probably shouldn’t be there.</p>
  39. <hr>
  40. <p>Consider the most venerable example of encryption and signing that we all deal
  41. with every day: HTTPS. Many years ago, browsers would happily display
  42. unencrypted web pages. The browser would also encrypt the connection, if the
  43. server operator had paid for an expensive certificate and correctly configured
  44. their server. If that operator messed up the encryption, it would pop up a
  45. helpful dialog box that would tell the user “This website did something wrong
  46. that you cannot possibly understand. Would you like to ignore this and keep
  47. working?” with buttons that said “Yes” and “No”.</p>
  48. <p>Of course, these are not the precise words that were written. The words, as
  49. written, said things about “information you exchange” and “security
  50. certificate” and “certifying authorities” but “Yes” and “No” were the words
  51. that most users <em>read</em>. Predictably, most users just clicked “Yes”.</p>
  52. <p>In the usual case, where users ignored these warnings, it meant that no user
  53. ever got meaningful security from HTTPS. It was a component of the web stack
  54. that did nothing but funnel money into the pockets of certificate authorities
  55. and occasionally present annoying interruptions to users.</p>
  56. <p>In the case where the user carefully read and honored these warnings in the
  57. spirit they were intended, adding any sort of transport security to your
  58. website was a potential liability. If you got everything perfectly correct,
  59. nothing happened except the browser would display a picture of a <a href="https://www.wired.com/2016/11/googles-chrome-hackers-flip-webs-security-model/">small green
  60. purse</a>. If
  61. you made any small mistake, it would scare users off and thereby directly harm
  62. your business. You would only want to do it if you were doing something that
  63. put a big enough target on your site that you became unusually interesting to
  64. attackers, or were required to do so by some contractual obligation like credit
  65. card companies.</p>
  66. <p>Keep in mind that the second case here is the <em>best</em> case.</p>
  67. <p>In 2016, the browser makers noticed this problem and started taking some
  68. <a href="https://security.googleblog.com/2016/09/moving-towards-more-secure-web.html">pretty aggressive
  69. steps</a>
  70. towards actually enforcing the security that HTTPS was supposed to provide, by
  71. fixing the user interface to do the right thing. If your site didn’t have
  72. security, it would be shown as “Not Secure”, a subtle warning that would
  73. gradually escalate in intensity as time went on, correctly incentivizing site
  74. operators to adopt transport security certificates. On the user interface
  75. side, certificate errors would be significantly harder to disregard, making it
  76. so that users who didn’t understand what they were seeing would actually be
  77. stopped from doing the dangerous thing.</p>
  78. <p>Nothing fundamental<sup id="fnref:1:unsigned-commits-2024-1"></sup> changed about the technical aspects of the
  79. cryptographic primitives or constructions being used by HTTPS in this time
  80. period, but <em>socially</em>, the meaning of an HTTP server signing and encrypting
  81. its requests changed a lot.</p>
  82. <hr>
  83. <p>Now, let’s consider signing Git commits.</p>
  84. <p>You may have heard that in some abstract sense you “should” be signing your
  85. commits. GitHub puts a little green “verified” badge next to commits that are
  86. signed, which is neat, I guess. They provide “security”. 1Password provides a
  87. <a href="https://developer.1password.com/docs/ssh/git-commit-signing/">nice UI</a> for
  88. setting it up. If you’re not a 1Password user, GitHub itself recommends you
  89. <a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key#telling-git-about-your-ssh-key">put in just a few lines of
  90. configuration</a>
  91. to do it with either a GPG, SSH, or even an S/MIME key.</p>
  92. <p>But while GitHub’s documentation quite lucidly tells you <em>how</em> to sign your
  93. commits, its explanation of
  94. <a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification">why</a>
  95. is somewhat less clear. Their purse is the word “Verified”; it’s still green.
  96. If you enable “<a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits">vigilant
  97. mode</a>”,
  98. you can make the blank “no verification status” option say “Unverified”, but
  99. not much else changes.</p>
  100. <p>This is like the old-style HTTPS verification “Yes”/“No” dialog, except that
  101. there is not even an interruption to your workflow. They might put the
  102. “Unverified” status on there, but they’ve gone ahead and clicked “Yes” for you.</p>
  103. <p>It is tempting to think that the “HTTPS” metaphor will map neatly onto Git
  104. commit signatures. It was bad when the web wasn’t using HTTPS, and the next
  105. step in that process was for <a href="https://en.wikipedia.org/wiki/Let%27s_Encrypt">Let’s
  106. Encrypt</a> to come along and for
  107. the browsers to fix their implementations. Getting your certificates properly
  108. set up in the meanwhile and becoming familiar with the tools for properly doing
  109. HTTPS was unambiguously a <em>good</em> thing for an engineer to do. I did, and I’m
  110. quite glad I did so!</p>
  111. <p>However, there is a significant difference: signing and encrypting an HTTPS
  112. request is ephemeral; signing a Git commit is functionally permanent.</p>
  113. <p>This ephemeral nature meant that errors in the early HTTPS landscape were
  114. easily fixable. Earlier I mentioned that there was a time where you might
  115. <em>not</em> want to set up HTTPS on your production web servers, because any small
  116. screw-up would break your site and thereby your business. But if you were
  117. really skilled and you could see the future coming, you could set up
  118. monitoring, avoid these mistakes, and rapidly recover. These mistakes didn’t
  119. need to badly break your site.</p>
  120. <p>We <em>can</em> extend the analogy to HTTPS, but we have to take a detour into one of
  121. the more unpleasant mistakes in HTTPS’s history: <a href="https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning">HTTP Public Key
  122. Pinning</a>, or “HPKP”.
  123. The idea with HPKP was that you could publish a record in an HTTP header where
  124. your site commits<sup id="fnref:2:unsigned-commits-2024-1"></sup> to using certain certificate authorities for a period of
  125. time, where that period of time could be “forever”. Attackers gonna attack,
  126. and <a href="https://scotthelme.co.uk/using-security-features-to-do-bad-things/#usinghpkpforevil">attack they
  127. did</a>.
  128. Even without getting attacked, a site could easily commit “HPKP Suicide” where
  129. they would pin the wrong certificate authority with a long timeline, and their
  130. site was effectively gone for every browser that had ever seen those pins. As
  131. a result, after a few years, HPKP was <a href="https://scotthelme.co.uk/hpkp-is-no-more/">completely removed from all
  132. browsers</a>.</p>
  133. <p>Git commit signing is even worse. With HPKP, you could easily make terrible
  134. mistakes with permanent consequences even though you knew the <em>exact</em> meaning
  135. of the data you were putting into the system at the time you were doing it.
  136. With signed commits, you are saying something permanently, but you don’t really
  137. know <em>what</em> it is that you’re saying.</p>
  138. <hr>
  139. <p><em>Today</em>, what is the benefit of signing a Git commit? GitHub might present it
  140. as “Verified”. It’s worth noting that only <em>GitHub</em> will do this, since they
  141. are the root of trust for this signing scheme. So, by signing commits and
  142. registering your keys with GitHub, you are, at best, helping to lock in GitHub
  143. as a permanent piece of infrastructure that is even harder to dislodge because
  144. they are not only where your code is stored, but also the arbiters of whether
  145. or not it is trustworthy.</p>
  146. <p><em>In the future</em>, what is the possible security benefit? If we all collectively
  147. decide we want Git to be more secure, then we will need to meaningfully treat
  148. signed commits differently from unsigned ones.</p>
  149. <p>There’s a long tail of unsigned commits several billion entries long. And
  150. those are in the permanent record as much as the signed ones are, so future
  151. tooling will have to be able to deal with them. If, as stewards of Git, we
  152. wish to move towards a more secure Git, as the stewards of the web moved
  153. towards a more secure web, we do <em>not</em> have the option that the web did. In
  154. the browser, the meaning of a plain-text HTTP or incorrectly-signed HTTPS site
  155. changed, in order to encourage the site’s operator to <em>change</em> the site to be
  156. HTTPS.</p>
  157. <p>In contrast, the meaning of an unsigned commit cannot change, because there are
  158. zillions of unsigned commits lying around in critical infrastructure and we
  159. need them to remain there. Commits cannot meaningfully be changed to become
  160. signed retroactively. Unlike an online website, they are part of a historical
  161. record, not an operating program. So we cannot establish the difference in
  162. treatment by changing how unsigned commits are treated.</p>
  163. <p>That means that tooling maintainers will need to provide some difference in
  164. behavior that provides some incentive. With HTTPS where the binary choice was
  165. clear: don’t present sites with incorrect, potentially compromised
  166. configurations to users. The question was just <em>how</em> to achieve that. With
  167. Git commits, the difference in treatment of a “trusted” commit is far less
  168. clear.</p>
  169. <p>If you will forgive me a slight straw-man here, one possible naive
  170. interpretation is that a “trusted” signed commit is that it’s OK to run in CI.
  171. Conveniently, it’s not simply “trusted” in a general sense. If you signed it,
  172. it’s trusted to be <em>from you</em>, specifically. Surely it’s fine if we bill the
  173. CI costs for validating the PR that includes that signed commit to your GitHub
  174. account?</p>
  175. <p>Now, someone can piggy-back off a 1-line typo fix that you made on top of an
  176. unsigned commit to some large repo, making you implicitly responsible for
  177. transitively signing all unsigned parent commits, even though you haven’t
  178. looked at any of the code.</p>
  179. <p>Remember, also, that the only central authority that is practically trustable
  180. at this point is your GitHub account. That means that if you are using a
  181. third-party CI system, even if you’re using a third-party Git host, you can
  182. only run “trusted” code if GitHub is online and responding to requests for its
  183. “get me the trusted signing keys for this user” API. This also adds a lot of
  184. value to a GitHub credential breach, strongly motivating attackers to sneakily
  185. attach their own keys to your account so that their commits in unrelated repos
  186. can be “Verified” by you.</p>
  187. <p>Let’s review the pros and cons of turning on commit signing <em>now</em>, before you
  188. know what it is going to be used for:</p>
  189. <table>
  190. <thead>
  191. <tr>
  192. <th align="left">Pro</th>
  193. <th align="left">Con</th>
  194. </tr>
  195. </thead>
  196. <tbody>
  197. <tr>
  198. <td align="left">Green “Verified” badge</td>
  199. <td align="left"><strong>Unknown, possibly unlimited future liability</strong> for the consequences of running code in a commit you signed</td>
  200. </tr>
  201. <tr>
  202. <td align="left"><p></p></td>
  203. <td align="left">Further implicitly cementing GitHub as a centralized trust authority in the open source world</td>
  204. </tr>
  205. <tr>
  206. <td align="left"></td>
  207. <td align="left">Introducing unknown reliability problems into infrastructure that relies on commit signatures</td>
  208. </tr>
  209. <tr>
  210. <td align="left"></td>
  211. <td align="left">Temporary breach of your GitHub credentials now lead to potentially permanent consequences if someone can smuggle a new trusted key in there</td>
  212. </tr>
  213. <tr>
  214. <td align="left"></td>
  215. <td align="left">New kinds of ongoing process overhead as commit-signing keys become new permanent load-bearing infrastructure, like “what do I do with expired keys”, “how often should I rotate these”, and so on</td>
  216. </tr>
  217. </tbody>
  218. </table>
  219. <p>I feel like the “Con” column is coming out ahead.</p>
  220. <hr>
  221. <p>That probably seemed like increasingly unhinged hyperbole, and it was.</p>
  222. <p>In reality, the consequences are unlikely to be nearly so dramatic. The status
  223. quo has a very high amount of inertia, and probably the “Verified” badge will
  224. remain the only visible difference, except for a few repo-specific esoteric
  225. workflows, like pushing trust verification into offline or sandboxed build
  226. systems. I do still think that there is <em>some</em> potential for nefariousness
  227. around the “unknown and unlimited” dimension of any future plans that might
  228. rely on verifying signed commits, but any flaws are likely to be subtle attack
  229. chains and not anything flashy and obvious.</p>
  230. <p>But I think that one of the biggest problems in information security is a lack
  231. of <a href="https://owasp.org/www-community/Threat_Modeling">threat modeling</a>. We
  232. encrypt things, we sign things, we institute <a href="https://cryptosmith.com/password-sanity/exp-harmful/">rotation
  233. policies</a> and
  234. <a href="https://neal.fun/password-game/">elaborate</a> useless
  235. <a href="https://xkcd.com/936/">rules</a> for passwords, because we are looking for a
  236. “best practice” that is going to save us from having to think about what our
  237. actual security problems are.</p>
  238. <p>I think the actual harm of signing git commits is to perpetuate an engineering
  239. culture of unquestioningly cargo-culting sophisticated and complex tools like
  240. cryptographic signatures into new contexts where they have no use.</p>
  241. <p>Just from a baseline utilitarian philosophical perspective, for a given action
  242. A, all else being equal, it’s always better <em>not</em> to do A, because taking an
  243. action always has <em>some</em> non-zero opportunity cost even if it is just the time
  244. taken to do it. Epsilon cost and zero benefit is still a net harm. This is
  245. even more true in the context of a complex system. Any action taken in
  246. response to a rule in a system is going to interact with all the other rules in
  247. that system. You have to pay complexity-rent on every new rule. So an
  248. apparently-useless embellishment like signing commits can have potentially
  249. far-reaching consequences in the future.</p>
  250. <p>Git commit signing itself is not particularly consequential. I have probably
  251. spent more time writing this blog post than the sum total of all the time
  252. wasted by all programmers configuring their git clients to add useless
  253. signatures; even the relatively modest readership of this blog will likely
  254. transfer more data reading this post than all those signatures will take to
  255. transmit to the various git clients that will read them. If I just convince
  256. you not to sign your commits, I don’t think I’m coming out ahead in the
  257. <a href="https://en.wikipedia.org/wiki/Felicific_calculus">felicific calculus</a> here.</p>
  258. <p>What I am actually trying to point out here is that it is useful to <em>carefully
  259. consider how to avoid adding junk complexity to your systems</em>. One area where
  260. junk tends to leak in to designs and to cultures particularly easily is in
  261. intimidating subjects like trust and safety, where it is easy to get anxious
  262. and convince ourselves that piling on more <em>stuff</em> is safer than leaving things
  263. simple.</p>
  264. <p>If I can help you avoid adding even a little bit of unnecessary complexity, I
  265. think it will have been well worth the cost of the writing, and the reading.</p>
  266. <h2 id="acknowledgments">Acknowledgments</h2>
  267. <p class="update-note">Thank you to <a href="https://www.patreon.com/creatorglyph">my patrons</a> who are
  268. supporting my writing on this blog. If you like what you’ve read here and
  269. you’d like to read more of it, or you’d like to support my <a href="https://github.com/glyph/">various open-source
  270. endeavors</a>, you can <a href="https://www.patreon.com/join/8655595">support me on Patreon as
  271. well</a>! I am also <a href="mailto:consulting@glyph.im">available for
  272. consulting work</a> if you think your organization
  273. could benefit from expertise on topics such as “What <em>else</em> should I <em>not</em> apply a cryptographic signature to?”.</p>