Now Reading
Forging signed commits on GitHub

Forging signed commits on GitHub

2024-01-21 22:49:26

A half-year in the past, I discovered a bug in an inner GitHub API that allow me trick the interior API into signing commits as any consumer. So I may create a commit signed by a consumer I don’t management:

A signed commit authored by @octocat with message “signed from codespace” and date Dec 31 2029

Earlier than I clarify how I did that, first some context on how Git commit signing works:

Git commit internals

Git commits are saved in a customized text-based format that appears like:

tree 55ca6286e3e4f4fba5d0448333fa99fc5a404a73
mother or father 7676f1f3b526f05b530a3566211dab5a5225af9a
writer loops <me@iter.ca> 1678388328 -0500
committer loops <me@iter.ca> 1678388328 -0500

Commit message

Signed commits have a further gpgsig header that has a signature over each line within the commit besides the gpgsig itself:

tree be0788944df13c5d170e050f2fe178360c3df5a5
writer loops <me@iter.ca> 1678388328 -0500
committer loops <me@iter.ca> 1678388328 -0500
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEK6cyil0jdmW2bZPmDXSPTJUzsugFAmQKLGgACgkQDXSPTJUz
 [...]
 =756m
 -----END PGP SIGNATURE-----

Official signed commit

Once you create a commit on GitHub.com, it’s signed with GitHub’s web flow GPG key and has a committer of GitHub <noreply@github.com>. Internet-flow signed commits are proven as signed within the GitHub UI:

This commit was created on GitHub.com and signed with GitHub’s verified signature

If we will trick GitHub into signing a commit with any writer, we will create solid commits that GitHub reveals as signed.

Tricking an inner API endpoint into signing our commits

For some context, I realized how some GitHub internals work by downloading a GitHub Enterprise Server trial VM and deobfuscating the Ruby supply code on the VM.

GitHub Codespaces is a GitHub service that gives you with a growth setting within the cloud. One characteristic of Codespaces is that commits created in it are signed with the net move GPG key (if enabled in settings).

When a commit is created in a codespace with GPG signing enabled, this occurs:

See Also

  1. git checks the gpg.program config possibility, which is ready to /.codespaces/bin/gh-gpgsign
  2. git calls /.codespaces/bin/gh-gpgsign with the uncooked commit physique
  3. The gh-gpgsign binary (which is closed-source) makes an API request to https://api.github.com/vscs_internal/commit/signal with the commit physique
  4. gh-gpgsign returns the signature returned from the API
  5. git inserts the commit signature into the commit information

The /vscs_internal/commit/signal endpoint is attention-grabbing since you can provide it arbitrary uncooked commit information, and get a signature again.

That /vscs_internal/commit/signal endpoint checked that the writer line within the supplied commit information is legitimate by discovering the primary line that matches the regex /Aauthor (.+?) <(.+)>/, and guaranteeing the identify and e-mail extracted from that regex corresponded to the logged-in consumer. However this regex doesn’t match writer strains with 0-length names! So for this commit:

tree 251966888982546b81f8bfc8de1f25077f099a56
mother or father fb5ce469856769a17cca88ec4e2c6159d4669b21
writer  <583231+octocat@customers.noreply.github.com> 1682188800 +0000
committer GitHub <noreply@github.com> 1682188800 +0000
writer username <consumer@instance.com> 1682188800 +0000

commit message

For the reason that first writer identify is zero characters lengthy, the regex skips that line, and the pretend second writer line is used as an alternative. Git ignores further writer strains after the primary, so Codespaces appears to be like on the second writer line however Git appears to be like on the first. This implies we will create GitHub-signed commits with any writer identify+e-mail.

The repair

GitHub fastened the problem by altering the problematic regex to /Aauthor ([^<]*)[ ]{0,1}<(.+)>/, which ought to all writer header strains accepted by git-fsck.

Timeline

  • April 22 2023: I report the problem to GitHub
  • April 24 2023: GitHub closes the problem, saying that having the ability to impersonate your individual account will not be a difficulty
  • April 24 2023: I reply saying that you should utilize this to assault impersonate different individuals
  • Might 2 2023: I reply once more, demonstrating that the problem nonetheless works
  • Might 4 2023: GitHub reopens the problem
  • Might 17 2023: GitHub validates the problem and begins work on a repair
  • June 2023: GitHub fixes the problem on GitHub.com
  • June 23 2023: GitHub closes the problem and rewards me with $10000

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top