Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* [BUGFIX] Ring: Fix ring token conflict resolution only applied to updated instance and make constantly token conflict check during instance observe period.
* [BUGFIX] Distributor: Fix a panic (`slice bounds out of range`) in the stream push path when the context deadline expires while the worker goroutine is still marshalling a `WriteRequest`. #7541
* [BUGFIX] Query Frontend: Fix native histogram responses not being handled correctly in `minTime()` sort ordering for split_by_interval merge. #7555
* [BUGFIX] Security: Fix `SecretStringSliceCSV.Set()` accepting empty entries from stray or trailing commas (e.g. `newkey,`). #7587

## 1.21.0 2026-04-24

Expand Down
18 changes: 16 additions & 2 deletions pkg/util/flagext/secretstringslicecsv.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package flagext

import "strings"
import (
"fmt"
"strings"
)

// SecretStringSliceCSV is a slice of strings that is parsed from a comma-separated string.
// It implements flag.Value and yaml Marshalers, but masks the value when marshaled to YAML
Expand All @@ -15,12 +18,23 @@ func (v SecretStringSliceCSV) String() string {
}

// Set implements flag.Value
// Each comma-separated entry is trimmed of surrounding whitespace.
// Empty entries (after trimming) are rejected with an error.
func (v *SecretStringSliceCSV) Set(s string) error {
if s == "" {
v.values = nil
return nil
}
v.values = strings.Split(s, ",")
parts := strings.Split(s, ",")
values := make([]string, 0, len(parts))
for _, p := range parts {
p = strings.TrimSpace(p)
if p == "" {
return fmt.Errorf("invalid key list %q: empty entry after trimming", s)
Comment thread
SungJin1212 marked this conversation as resolved.
Outdated
}
values = append(values, p)
}
v.values = values
return nil
}

Expand Down
28 changes: 28 additions & 0 deletions pkg/util/flagext/secretstringslicecsv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,32 @@ func TestSecretStringSliceCSV(t *testing.T) {
require.NoError(t, s.Keys.Set(""))
assert.Equal(t, []string(nil), s.Keys.Value())
})

t.Run("trailing comma is rejected", func(t *testing.T) {
var s TestStruct
err := s.Keys.Set("newkey,")
require.Error(t, err, "trailing comma must produce an error")
assert.Nil(t, s.Keys.Value(), "values must not be updated on error")
})

t.Run("leading comma is rejected", func(t *testing.T) {
var s TestStruct
require.Error(t, s.Keys.Set(",newkey"))
})

t.Run("double comma is rejected", func(t *testing.T) {
var s TestStruct
require.Error(t, s.Keys.Set("newkey,,oldkey"))
})

t.Run("whitespace-only entry is rejected", func(t *testing.T) {
var s TestStruct
require.Error(t, s.Keys.Set("newkey, ,oldkey"))
})

t.Run("surrounding whitespace is trimmed from valid entries", func(t *testing.T) {
var s TestStruct
require.NoError(t, s.Keys.Set(" key1 , key2 "))
assert.Equal(t, []string{"key1", "key2"}, s.Keys.Value())
})
}
Loading