Rekor COSE v0.0.1 Canonicalize crashes when passed empty Message
Description
Rekor is a software supply chain transparency log. In versions 1.4.3 and below, the entry implementation can panic on attacker-controlled input when canonicalizing a proposed entry with an empty spec.message, causing nil Pointer Dereference. Function validate() returns nil (success) when message is empty, leaving sign1Msg uninitialized, and Canonicalize() later dereferences v.sign1Msg.Payload. A malformed proposed entry of the cose/v0.0.1 type can cause a panic on a thread within the Rekor process. The thread is recovered so the client receives a 500 error message and service still continues, so the availability impact of this is minimal. This issue has been fixed in version 1.5.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/sigstore/rekorGo | < 1.5.0 | 1.5.0 |
Affected products
1Patches
139bae3d192bcMerge commit from fork (#2729)
8 files changed · +88 −7
cmd/cleanup-index/main.go+1 −1 modified@@ -13,7 +13,7 @@ // limitations under the License. /* - cleanup-index checks what index entries are in the MySQL table and deletes those entries from the Redis databse. + cleanup-index checks what index entries are in the MySQL table and deletes those entries from the Redis database. It does not go the other way To run:
pkg/pki/minisign/minisign_test.go+1 −1 modified@@ -391,7 +391,7 @@ func TestVerifySignature(t *testing.T) { } if err := s.Verify(dataFile, k); (err == nil) != tc.verified { - t.Errorf("%v: unexpected result in verifying sigature: %v", tc.caseDesc, err) + t.Errorf("%v: unexpected result in verifying signature: %v", tc.caseDesc, err) } }
pkg/pki/pgp/pgp_test.go+2 −2 modified@@ -354,7 +354,7 @@ func TestEmailAddresses(t *testing.T) { var k PublicKey if len(k.Subjects()) != 0 { - t.Errorf("Subjects for unitialized key should give empty slice") + t.Errorf("Subjects for uninitialized key should give empty slice") } tests := []test{ {caseDesc: "Valid armored public key", inputFile: "testdata/valid_armored_public.pgp", subjects: []string{}, keys: 2}, @@ -447,7 +447,7 @@ func TestVerifySignature(t *testing.T) { } if err := s.Verify(dataFile, k); (err == nil) != tc.verified { - t.Errorf("%v: unexpected result in verifying sigature: %v", tc.caseDesc, err) + t.Errorf("%v: unexpected result in verifying signature: %v", tc.caseDesc, err) } }
pkg/pki/tuf/tuf_test.go+1 −1 modified@@ -229,7 +229,7 @@ func TestVerifySignature(t *testing.T) { } if err := s.Verify(nil, k); (err == nil) != tc.verified { - t.Errorf("%v: unexpected result in verifying sigature: %v", tc.caseDesc, err) + t.Errorf("%v: unexpected result in verifying signature: %v", tc.caseDesc, err) } }
pkg/types/cose/v0.0.1/entry.go+14 −1 modified@@ -83,6 +83,9 @@ func (v V001Entry) IndexKeys() ([]string, error) { var result []string // We add the key, the hash of the overall cose envelope, and the hash of the payload itself as keys. + if v.CoseObj.PublicKey == nil { + return nil, errors.New("missing public key") + } keyObj, err := x509.NewPublicKey(bytes.NewReader(*v.CoseObj.PublicKey)) if err != nil { return nil, err @@ -169,6 +172,9 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { return err } + if v.CoseObj.PublicKey == nil { + return errors.New("missing public key") + } v.keyObj, err = x509.NewPublicKey(bytes.NewReader(*v.CoseObj.PublicKey)) if err != nil { return err @@ -199,8 +205,15 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) { if v.keyObj == nil { - return nil, errors.New("cannot canonicalze empty key") + return nil, errors.New("cannot canonicalize empty key") } + if v.sign1Msg == nil { + return nil, errors.New("signed message uninitialized") + } + if v.sign1Msg.Payload == nil { + return nil, errors.New("payload empty") + } + pk, err := v.keyObj.CanonicalValue() if err != nil { return nil, err
pkg/types/cose/v0.0.1/entry_test.go+50 −0 modified@@ -923,3 +923,53 @@ func TestInsertable(t *testing.T) { }) } } + +func TestV001Entry_IndexKeys_MissingPublicKey(t *testing.T) { + v := V001Entry{ + CoseObj: models.CoseV001Schema{ + Data: &models.CoseV001SchemaData{}, + PublicKey: nil, + }, + } + _, err := v.IndexKeys() + if err == nil { + t.Fatal("expected error") + } + if err.Error() != "missing public key" { + t.Errorf("expected 'missing public key' error, got %v", err) + } +} + +func TestCanonicalizeHandlesInvalidInput(t *testing.T) { + v := &V001Entry{} + + // 1. Missing keyObj + _, err := v.Canonicalize(context.TODO()) + if err == nil || err.Error() != "cannot canonicalize empty key" { + t.Fatalf("expected error 'cannot canonicalize empty key', got %v", err) + } + + // Setup valid keyObj for subsequent tests + priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + der, _ := x509.MarshalPKIXPublicKey(&priv.PublicKey) + pub := pem.EncodeToMemory(&pem.Block{ + Bytes: der, + Type: "PUBLIC KEY", + }) + keyObj, _ := sigx509.NewPublicKey(bytes.NewReader(pub)) + v.keyObj = keyObj + + // 2. Missing sign1Msg + _, err = v.Canonicalize(context.TODO()) + if err == nil || err.Error() != "signed message uninitialized" { + t.Fatalf("expected error 'signed message uninitialized', got %v", err) + } + + // 3. Missing Payload in sign1Msg + v.sign1Msg = gocose.NewSign1Message() + v.sign1Msg.Payload = nil + _, err = v.Canonicalize(context.TODO()) + if err == nil || err.Error() != "payload empty" { + t.Fatalf("expected error 'payload empty', got %v", err) + } +}
pkg/types/dsse/v0.0.1/entry.go+4 −1 modified@@ -292,6 +292,9 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { } env := &dsse.Envelope{} + if dsseObj.ProposedContent.Envelope == nil { + return errors.New("proposed content envelope is missing") + } if err := json.Unmarshal([]byte(*dsseObj.ProposedContent.Envelope), env); err != nil { return err } @@ -374,7 +377,7 @@ func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) { } for _, s := range canonicalEntry.Signatures { - if s.Signature == nil { + if s == nil || s.Signature == nil { return nil, errors.New("canonical entry missing required signature") } }
pkg/types/dsse/v0.0.1/entry_test.go+15 −0 modified@@ -252,6 +252,15 @@ func TestV001Entry_Unmarshal(t *testing.T) { }, wantErr: true, }, + { + name: "missing envelope with verifiers", + it: &models.DSSEV001Schema{ + ProposedContent: &models.DSSEV001SchemaProposedContent{ + Verifiers: []strfmt.Base64{[]byte("verifier")}, + }, + }, + wantErr: true, + }, { env: envelope(t, key, []byte(validPayload)), name: "valid", @@ -624,4 +633,10 @@ func TestCanonicalizeHandlesInvalidInput(t *testing.T) { if err == nil { t.Fatalf("expected error canonicalizing invalid input") } + + v.DSSEObj.Signatures = []*models.DSSEV001SchemaSignaturesItems0{nil} + _, err = v.Canonicalize(context.TODO()) + if err == nil { + t.Fatalf("expected error canonicalizing nil signature") + } }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-273p-m2cw-6833ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-23831ghsaADVISORY
- github.com/sigstore/rekor/commit/39bae3d192bce48ef4ef2cbd1788fb5770fee8cdghsax_refsource_MISCWEB
- github.com/sigstore/rekor/releases/tag/v1.5.0ghsax_refsource_MISCWEB
- github.com/sigstore/rekor/security/advisories/GHSA-273p-m2cw-6833ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.