VYPR
Moderate severityOSV Advisory· Published Jan 22, 2026· Updated Jan 23, 2026

Rekor COSE v0.0.1 Canonicalize crashes when passed empty Message

CVE-2026-23831

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.

PackageAffected versionsPatched versions
github.com/sigstore/rekorGo
< 1.5.01.5.0

Affected products

1

Patches

1
39bae3d192bc

Merge commit from fork (#2729)

https://github.com/sigstore/rekorHaydenJan 21, 2026via ghsa
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

News mentions

0

No linked articles in our index yet.