|
| 1 | +From c6fd08c83115ce2f69a82923499c60794ebc3908 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Hayden <8418760+Hayden-IO@users.noreply.github.com> |
| 3 | +Date: Wed, 21 Jan 2026 16:52:44 -0800 |
| 4 | +Subject: [PATCH] Drop support for fetching public keys by URL in the search |
| 5 | + index (#2731) |
| 6 | + |
| 7 | +This mitigates blind SSRF. Note that this API was marked as experimental |
| 8 | +so while this is a breaking change to the API, we offered no guarantee |
| 9 | +of stability. |
| 10 | + |
| 11 | +Fixes GHSA-4c4x-jm2x-pf9j |
| 12 | + |
| 13 | +Signed-off-by: Hayden <8418760+Hayden-IO@users.noreply.github.com> |
| 14 | + |
| 15 | +Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> |
| 16 | +Upstream Patch reference: https://github.com/sigstore/rekor/commit/60ef2bceba192c5bf9327d003bceea8bf1f8275f.patch |
| 17 | +--- |
| 18 | + .../client/entries/entries_client.go | 2 +- |
| 19 | + .../pkg/generated/models/search_index.go | 20 ------------------- |
| 20 | + .../sigstore/rekor/pkg/util/fetch.go | 10 +++++++--- |
| 21 | + 3 files changed, 8 insertions(+), 24 deletions(-) |
| 22 | + |
| 23 | +diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go |
| 24 | +index fe2630e..668ec29 100644 |
| 25 | +--- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go |
| 26 | ++++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go |
| 27 | +@@ -58,7 +58,7 @@ type ClientService interface { |
| 28 | + /* |
| 29 | + CreateLogEntry creates an entry in the transparency log |
| 30 | + |
| 31 | +-Creates an entry in the transparency log for a detached signature, public key, and content. Items can be included in the request or fetched by the server when URLs are specified. |
| 32 | ++Creates an entry in the transparency log for a detached signature, public key, and content. |
| 33 | + */ |
| 34 | + func (a *Client) CreateLogEntry(params *CreateLogEntryParams, opts ...ClientOption) (*CreateLogEntryCreated, error) { |
| 35 | + // TODO: Validate the params before sending |
| 36 | +diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go |
| 37 | +index bb1cccc..e731a3b 100644 |
| 38 | +--- a/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go |
| 39 | ++++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go |
| 40 | +@@ -229,10 +229,6 @@ type SearchIndexPublicKey struct { |
| 41 | + // Required: true |
| 42 | + // Enum: [pgp x509 minisign ssh tuf] |
| 43 | + Format *string `json:"format"` |
| 44 | +- |
| 45 | +- // url |
| 46 | +- // Format: uri |
| 47 | +- URL strfmt.URI `json:"url,omitempty"` |
| 48 | + } |
| 49 | + |
| 50 | + // Validate validates this search index public key |
| 51 | +@@ -243,10 +239,6 @@ func (m *SearchIndexPublicKey) Validate(formats strfmt.Registry) error { |
| 52 | + res = append(res, err) |
| 53 | + } |
| 54 | + |
| 55 | +- if err := m.validateURL(formats); err != nil { |
| 56 | +- res = append(res, err) |
| 57 | +- } |
| 58 | +- |
| 59 | + if len(res) > 0 { |
| 60 | + return errors.CompositeValidationError(res...) |
| 61 | + } |
| 62 | +@@ -305,18 +297,6 @@ func (m *SearchIndexPublicKey) validateFormat(formats strfmt.Registry) error { |
| 63 | + return nil |
| 64 | + } |
| 65 | + |
| 66 | +-func (m *SearchIndexPublicKey) validateURL(formats strfmt.Registry) error { |
| 67 | +- if swag.IsZero(m.URL) { // not required |
| 68 | +- return nil |
| 69 | +- } |
| 70 | +- |
| 71 | +- if err := validate.FormatOf("publicKey"+"."+"url", "body", "uri", m.URL.String(), formats); err != nil { |
| 72 | +- return err |
| 73 | +- } |
| 74 | +- |
| 75 | +- return nil |
| 76 | +-} |
| 77 | +- |
| 78 | + // ContextValidate validates this search index public key based on context it is used |
| 79 | + func (m *SearchIndexPublicKey) ContextValidate(ctx context.Context, formats strfmt.Registry) error { |
| 80 | + return nil |
| 81 | +diff --git a/vendor/github.com/sigstore/rekor/pkg/util/fetch.go b/vendor/github.com/sigstore/rekor/pkg/util/fetch.go |
| 82 | +index 7f8e93f..5c5c464 100644 |
| 83 | +--- a/vendor/github.com/sigstore/rekor/pkg/util/fetch.go |
| 84 | ++++ b/vendor/github.com/sigstore/rekor/pkg/util/fetch.go |
| 85 | +@@ -21,14 +21,18 @@ import ( |
| 86 | + "fmt" |
| 87 | + "io" |
| 88 | + "net/http" |
| 89 | ++ "time" |
| 90 | + ) |
| 91 | + |
| 92 | +-// FileOrURLReadCloser Note: caller is responsible for closing ReadCloser returned from method! |
| 93 | ++// FileOrURLReadCloser reads content either from a URL or a byte slice |
| 94 | ++// Note: Caller is responsible for closing the returned ReadCloser |
| 95 | ++// Note: This must never be called from any server codepath to prevent SSRF |
| 96 | + func FileOrURLReadCloser(ctx context.Context, url string, content []byte) (io.ReadCloser, error) { |
| 97 | + var dataReader io.ReadCloser |
| 98 | + if url != "" { |
| 99 | +- //TODO: set timeout here, SSL settings? |
| 100 | +- client := &http.Client{} |
| 101 | ++ client := &http.Client{ |
| 102 | ++ Timeout: 30 * time.Second, |
| 103 | ++ } |
| 104 | + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) |
| 105 | + if err != nil { |
| 106 | + return nil, err |
| 107 | +-- |
| 108 | +2.45.4 |
| 109 | + |
0 commit comments