Skip to content

Dependency on frozen golang.org/x/crypto/openpgp propagates GO-2026-5932 to all consumers #57

Description

@jmrplens

Summary

go-selfupdate depends on golang.org/x/crypto/openpgp, which is frozen, deprecated, and covered by GO-2026-5932. Because validate.go imports it unconditionally, the advisory propagates to every downstream consumer, including those that never verify a PGP signature.

Why this cannot be fixed by upgrading

The advisory has no fixed version:

Found in: golang.org/x/crypto@v0.54.0
Fixed in: N/A

Its affected range is introduced: 0, i.e. every release of the module. The finding is not a specific bug but the package's status: "unmaintained, unsafe by design, and has known security issues". No dependency bump will ever clear it.

Upstream will not fix it either. The Go team froze the package through accepted proposal golang/go#44226 (closed as completed, August 2021):

the golang.org/x/crypto/openpgp package is now frozen and deprecated. No new changes will be accepted except for security fixes.

Why it affects consumers that do not use PGP

validate.go imports the package at file scope for the PGPValidator.KeyRing field:

https://github.com/creativeprojects/go-selfupdate/blob/v1.6.0/validate.go#L17

Go has no way to drop a package-level import, so openpgp is linked into any binary importing selfupdate, regardless of which Validator is configured.

Concretely, in a project that configures selfupdate.ChecksumValidator and signs its releases with cosign/sigstore rather than GPG, govulncheck still reports:

Vulnerability #1: GO-2026-5932
    Found in: golang.org/x/crypto@v0.54.0
    Fixed in: N/A
    Example traces found:
      #1: internal/autoupdate/autoupdate.go:14:2: autoupdate.init calls selfupdate.init, which eventually calls armor.init
      #5: internal/autoupdate/autoupdate.go:14:2: autoupdate.init calls selfupdate.init, which calls openpgp.init
      ...

Every trace is a package init() call — no openpgp function is ever invoked — but the advisory is still reported, and consumers with a CI vulnerability gate have to carry a permanent allowlist entry for it.

Proposed fix

Migrate to github.com/ProtonMail/go-crypto/openpgp, the maintained fork recommended both by the advisory itself and by the x/crypto/openpgp package documentation:

If you are required to interoperate with OpenPGP systems and need a maintained package, consider github.com/ProtonMail/go-crypto/openpgp, which is a maintained fork that aims to be a drop-in replacement for this package.

The change is small: the fork's CheckDetachedSignature / CheckArmoredDetachedSignature take an extra *packet.Config, where nil selects the library defaults and matches current behaviour.

One caveat worth flagging: ProtonMail/go-crypto@v1.4.1 resolves github.com/cloudflare/circl@v1.6.2, which is affected by GO-2026-4550. Bumping circl to v1.6.3 avoids trading one advisory for another.

An alternative, if you would rather not change the dependency, is to move the PGP validators into their own package (e.g. selfupdate/pgp) so consumers that do not use them never link openpgp. That is a larger API change, and it would not help consumers that do use PGPValidator.

Compatibility

The migration changes the type of the exported PGPValidator.KeyRing field, since openpgp.EntityList would come from a different package. Callers using WithArmoredKeyRing([]byte) are unaffected; callers assigning a key ring they built themselves with x/crypto would need to update their import. That suggests a minor version bump.

I have verified locally that signatures produced with golang.org/x/crypto/openpgp still verify correctly through the migrated PGPValidator (and that tampered payloads are still rejected), so already-signed release assets keep validating.

I am opening a PR with the change, full test suite passing and golangci-lint clean. Happy to adjust the approach if you prefer the subpackage route.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions