Visitar URL original
fix(verify): prevent nil-pointer panic in TLogEntries by cmenjivar · Pull Request #658 · sigstore/sigstore-go · GitHub
Skip to content

fix(verify): prevent nil-pointer panic in TLogEntries - #658

Merged
Hayden-IO merged 4 commits into
sigstore:mainfrom
cmenjivar:fix/tlog-entries-nil-panic
Jul 24, 2026
Merged

Hayden-IO merged 4 commits into
sigstore:mainfrom
cmenjivar:fix/tlog-entries-nil-panic

Conversation

@cmenjivar

Copy link
Copy Markdown
Contributor

Summary

This PR hardens bundle verification against malformed or empty transparency-log data by adding defensive nil checks to the bundle and verification paths. When a bundle or its verification material is nil or incomplete, verification now returns explicit validation errors instead of panicking with a nil-pointer dereference. This prevents downstream crashes in consumers such as TFLint when processing certain GitHub Artifact Attestations.

Closes TFLint (issue #2591).

Release Note

Fixed a panic during bundle verification for malformed or empty transparency log data in some GitHub Artifact Attestations.

Documentation

None. No user-facing documentation changes are required for this bug fix.

Verified locally with:

go test ./pkg/bundle ./pkg/verify

@cmenjivar
cmenjivar requested a review from a team as a code owner July 16, 2026 22:13
Signed-off-by: Carlos Menjivar <menjivarc@gmail.com>
@cmenjivar
cmenjivar force-pushed the fix/tlog-entries-nil-panic branch from 58492bf to d15fb43 Compare July 16, 2026 22:16

@Hayden-IO Hayden-IO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned an issue number, but I'm not sure what issue this is referring to?

Comment thread pkg/bundle/bundle.go Outdated

if b.VerificationMaterial == nil {
return nil, nil
return nil, errors.New("bundle verification material is uninitialized or nil")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an acceptable state though, shouldn't a client calling this handle an empty array?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to preserve the original empty-result behavior for an empty TLog entry list: TlogEntries() now returns nil, nil for that case. I also kept the defensive nil check for a nil bundle and switched the missing-verification-material path to use the existing package validation error, so the behavior stays consistent with the rest of the bundle validation flow.

Comment thread pkg/bundle/bundle.go
return fmt.Errorf("%w: bundle version %s is not yet supported", ErrUnsupportedMediaType, bundleVersion)
}

err = validateBundle(b.Bundle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being moved?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the earlier placement was effectively doing the same validation too early, before the method had finished the rest of its bundle checks. Moving it up makes the validation happen immediately after the bundle object is inspected, so malformed bundles are rejected before the method continues into the TLog and inclusion-proof logic.

In other words, the change makes the validation flow more direct:

  • check bundle structure first
  • then proceed with the rest of the validation logic

That also keeps the behavior consistent with the existing validateBundle path and avoids letting later steps run on an invalid bundle.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this SGTM.

Comment thread pkg/bundle/bundle.go Outdated
}

func (b *Bundle) TlogEntries() ([]*tlog.Entry, error) {
if b == nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unnecessary check, if b were nil, b.TlogEntries would have panicked already.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the redundant nil receiver check; the method now keeps the existing behavior for missing verification material without an extra guard.

@cmenjivar

Copy link
Copy Markdown
Contributor Author

You mentioned an issue number, but I'm not sure what issue this is referring to?

terraform-linters/tflint#2591

@Hayden-IO

Copy link
Copy Markdown
Contributor

Thanks, taking a look

Signed-off-by: Carlos Menjivar <menjivarc@gmail.com>
@Hayden-IO

Copy link
Copy Markdown
Contributor

@steiza Could you take a look at the linked issue? I think the fix here to move the validation logic up is fine, but I'm curious if there's something else going on, either with us needing to recommend different verification options to integrators or if there was some issue with GHA provenance generation that led to missing log entries.

Comment thread pkg/bundle/bundle.go
return fmt.Errorf("%w: bundle version %s is not yet supported", ErrUnsupportedMediaType, bundleVersion)
}

err = validateBundle(b.Bundle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this SGTM.

Comment thread pkg/verify/tlog.go Outdated
return nil, err
return nil, fmt.Errorf("failed to retrieve transparency log entries: %w", err)
}
if len(entries) == 0 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VerifyTlogEntry will only be called if the client has configured the verifier to expect a logged signature. An empty entries list shouldn't cause a panic, it should skip the loops and fail to meet the threshold as expected. I don't think we need to have this check.

@cmenjivar cmenjivar Jul 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed if len(entries) == 0 check from VerifyTlogEntry

Signed-off-by: Carlos Menjivar <menjivarc@gmail.com>
@cmenjivar
cmenjivar force-pushed the fix/tlog-entries-nil-panic branch from da45d46 to 3bea1ce Compare July 23, 2026 19:14
Signed-off-by: Carlos Menjivar <menjivarc@gmail.com>
@steiza

steiza commented Jul 24, 2026

Copy link
Copy Markdown
Member

@steiza Could you take a look at the linked issue? I think the fix here to move the validation logic up is fine, but I'm curious if there's something else going on, either with us needing to recommend different verification options to integrators or if there was some issue with GHA provenance generation that led to missing log entries.

Yeah, so what happened here is that GitHub made some breaking changes to the API with version 2026-03-10 which included changes to the artifact attestation APIs. Those breaking changes were mistakenly backported to API version 2022-11-28, and that mistaken backport has now been reverted.

@cmenjivar

Copy link
Copy Markdown
Contributor Author

Thanks for the review and approval! It looks like I don't have write permissions to merge into this branch due to branch protection rules. Could you (or another maintainer) please merge this when you have a moment?

@Hayden-IO
Hayden-IO merged commit fc71b2a into sigstore:main Jul 24, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants