SecretsManager: Limit of 24kiB for raw input for secure value (#107403)

* SecureValues: Add limit of 24kiB for raw input

Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

* Fix lint

---------

Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>
pull/107433/head
Dana Axinte 3 weeks ago committed by GitHub
parent 0a90b7b5e9
commit d28594d2f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      pkg/apis/secret/v0alpha1/secure_value.go
  2. 3
      pkg/apis/secret/v0alpha1/zz_generated.openapi.go
  3. 3
      pkg/registry/apis/secret/contracts/secure_value.go
  4. 7
      pkg/registry/apis/secret/reststorage/secure_value_rest.go
  5. 12
      pkg/registry/apis/secret/reststorage/secure_value_rest_test.go

@ -59,7 +59,9 @@ type SecureValueSpec struct {
// The raw value is only valid for write. Read/List will always be empty.
// There is no support for mixing `value` and `ref`, you can't create a secret in a third-party keeper with a specified `ref`.
// Minimum and maximum lengths in bytes.
// +k8s:validation:minLength=1
// +k8s:validation:maxLength=24576
Value ExposedSecureValue `json:"value,omitempty"`
// When using a third-party keeper, the `ref` is used to reference a value inside the remote storage.

@ -641,8 +641,9 @@ func schema_pkg_apis_secret_v0alpha1_SecureValueSpec(ref common.ReferenceCallbac
},
"value": {
SchemaProps: spec.SchemaProps{
Description: "The raw value is only valid for write. Read/List will always be empty. There is no support for mixing `value` and `ref`, you can't create a secret in a third-party keeper with a specified `ref`.",
Description: "The raw value is only valid for write. Read/List will always be empty. There is no support for mixing `value` and `ref`, you can't create a secret in a third-party keeper with a specified `ref`. Minimum and maximum lengths in bytes.",
MinLength: ptr.To[int64](1),
MaxLength: ptr.To[int64](24576),
Type: []string{"string"},
Format: "",
},

@ -8,6 +8,9 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
)
// The maximum size of a secure value in bytes when written as raw input.
const SECURE_VALUE_RAW_INPUT_MAX_SIZE_BYTES = 24576 // 24 KiB
type DecryptSecureValue struct {
Keeper *string
Ref string

@ -245,6 +245,13 @@ func ValidateSecureValue(sv, oldSv *secretv0alpha1.SecureValue, operation admiss
}
// General validations.
if len(sv.Spec.Value) > contracts.SECURE_VALUE_RAW_INPUT_MAX_SIZE_BYTES {
errs = append(
errs,
field.TooLong(field.NewPath("spec", "value"), len(sv.Spec.Value), contracts.SECURE_VALUE_RAW_INPUT_MAX_SIZE_BYTES),
)
}
if errs := validateDecrypters(sv.Spec.Decrypters, decryptersAllowList); len(errs) > 0 {
return errs
}

@ -4,12 +4,14 @@ import (
"fmt"
"maps"
"slices"
"strings"
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apiserver/pkg/admission"
secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
)
func TestValidateSecureValue(t *testing.T) {
@ -50,6 +52,16 @@ func TestValidateSecureValue(t *testing.T) {
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
})
t.Run("`value` cannot exceed 24576 bytes", func(t *testing.T) {
sv := validSecureValue.DeepCopy()
sv.Spec.Value = secretv0alpha1.NewExposedSecureValue(strings.Repeat("a", contracts.SECURE_VALUE_RAW_INPUT_MAX_SIZE_BYTES+1))
sv.Spec.Ref = nil
errs := ValidateSecureValue(sv, nil, admission.Create, nil)
require.Len(t, errs, 1)
require.Equal(t, "spec.value", errs[0].Field)
})
})
t.Run("when updating a securevalue", func(t *testing.T) {

Loading…
Cancel
Save