This release fixes three security issues reported by @sondt99 and @Xiaoyiyi23.
Security
Private repository names disclosed over HTTP ([GHSA-fgxm-5hvv-x4vh], medium)
Soft Serve's implementation of Go's ?go-get=1 could expose a private repo name that a user didn't have access to.
The Git and LFS routes could leak the name as well via status code.
no-access collaborators could read private repositories ([GHSA-pmgj-8mr6-9rff], medium)
Previously on private repositories a no-access collaborator was elevated to read-only due to a mis ordered check.
Repositories could stay public after being made private ([GHSA-f3fj-9625-rv3m], medium)
Repository records were cached in memory with no expiry and trusted for all access checks. Making a repository private cleared the cache before the change was saved, allow for a race condition where a request arriving before the save took effect could cache the old public record, and the repository would stay readable until the server restarted. Multiple instances sharing a database also had a variant of this which caused the cache of one instance to never get propagated to the others.
Fixed
- Deleting a user who owns repositories always failed with "database is locked". It now refuses with a list of the repositories they own.
- A repository whose directory had already been deleted couldn't be deleted. Now the database entry is removed regardless of the directory removal.
- The
repository_visibility_changewebhook fired every time visibility was set, even if the value didn't change.
Changelog
Fixed
- dc351aa: fix: answer the same for private and missing repositories over HTTP (@taciturnaxolotl)
- 5b307b4: fix: keep a repository private after its visibility changes (@taciturnaxolotl)
- d108e2c: fix: refuse to delete users who still own repositories (@taciturnaxolotl)
- 0a4e6f0: fix: send the visibility webhook only when visibility changes (@taciturnaxolotl)
- bf0f7bb: fix: stop failed logins and stray requests from creating repositories (@taciturnaxolotl)
- 74e4154: fix: stop go-get requests from revealing private repository names (@taciturnaxolotl)
- db6e0d0: fix: stop granting read access to no-access collaborators on private repos (@taciturnaxolotl)
Deps
- 8877a14: fix(deps): update Go and x/crypto to clear reported vulnerabilities (@taciturnaxolotl)
Other stuff
- 37685d3: ci: sync dependabot config (#927) (@charmcli)
- e89e310: refactor: move LFS lock handlers into their own file (@taciturnaxolotl)
- d12156d: refactor: share the missing-repository check across LFS handlers (@taciturnaxolotl)
- 6b169bc: v0.12.3 (@taciturnaxolotl)
Verifying the artifacts
First, download the checksums.txt file and the checksums.txt.sigstore.json file files, for example, with wget:
wget 'https://github.com/charmbracelet/soft-serve/releases/download/v0.12.3/checksums.txt'
wget 'https://github.com/charmbracelet/soft-serve/releases/download/v0.12.3/checksums.txt.sigstore.json'Then, verify it using cosign:
cosign verify-blob \
--certificate-identity 'https://github.com/charmbracelet/meta/.github/workflows/goreleaser.yml@refs/heads/main' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle 'checksums.txt.sigstore.json' \
./checksums.txtIf the output is Verified OK, you can safely use it to verify the checksums of other artifacts you downloaded from the release using sha256sum:
sha256sum --ignore-missing -c checksums.txtDone! You artifacts are now verified!
Thoughts? Questions? We love hearing from you. Feel free to reach out on X, Discord, Slack, The Fediverse, Bluesky.