mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-18 18:38:08 -05:00
Merge remote-tracking branch 'remotes/from/ce/main'
Some checks are pending
build / setup (push) Waiting to run
build / Check ce/* Pull Requests (push) Blocked by required conditions
build / ui (push) Blocked by required conditions
build / artifacts-ce (push) Blocked by required conditions
build / artifacts-ent (push) Blocked by required conditions
build / hcp-image (push) Blocked by required conditions
build / test (push) Blocked by required conditions
build / test-hcp-image (push) Blocked by required conditions
build / completed-successfully (push) Blocked by required conditions
CI / setup (push) Waiting to run
CI / Run Autopilot upgrade tool (push) Blocked by required conditions
CI / Run Go tests (push) Blocked by required conditions
CI / Run Go tests tagged with testonly (push) Blocked by required conditions
CI / Run Go tests with data race detection (push) Blocked by required conditions
CI / Run Go tests with FIPS configuration (push) Blocked by required conditions
CI / Test UI (push) Blocked by required conditions
CI / tests-completed (push) Blocked by required conditions
Run linters / Setup (push) Waiting to run
Run linters / Deprecated functions (push) Blocked by required conditions
Run linters / Code checks (push) Blocked by required conditions
Run linters / Protobuf generate delta (push) Blocked by required conditions
Run linters / Format (push) Blocked by required conditions
Run linters / Semgrep (push) Waiting to run
Check Copywrite Headers / copywrite (push) Waiting to run
Security Scan / scan (push) Waiting to run
Some checks are pending
build / setup (push) Waiting to run
build / Check ce/* Pull Requests (push) Blocked by required conditions
build / ui (push) Blocked by required conditions
build / artifacts-ce (push) Blocked by required conditions
build / artifacts-ent (push) Blocked by required conditions
build / hcp-image (push) Blocked by required conditions
build / test (push) Blocked by required conditions
build / test-hcp-image (push) Blocked by required conditions
build / completed-successfully (push) Blocked by required conditions
CI / setup (push) Waiting to run
CI / Run Autopilot upgrade tool (push) Blocked by required conditions
CI / Run Go tests (push) Blocked by required conditions
CI / Run Go tests tagged with testonly (push) Blocked by required conditions
CI / Run Go tests with data race detection (push) Blocked by required conditions
CI / Run Go tests with FIPS configuration (push) Blocked by required conditions
CI / Test UI (push) Blocked by required conditions
CI / tests-completed (push) Blocked by required conditions
Run linters / Setup (push) Waiting to run
Run linters / Deprecated functions (push) Blocked by required conditions
Run linters / Code checks (push) Blocked by required conditions
Run linters / Protobuf generate delta (push) Blocked by required conditions
Run linters / Format (push) Blocked by required conditions
Run linters / Semgrep (push) Waiting to run
Check Copywrite Headers / copywrite (push) Waiting to run
Security Scan / scan (push) Waiting to run
This commit is contained in:
commit
bc33fac9b1
3 changed files with 104 additions and 1 deletions
|
|
@ -190,7 +190,10 @@ func verifyEabPayload(acmeState *acmeState, ac *acmeContext, outer *jwsCtx, expe
|
|||
if !ok {
|
||||
return nil, fmt.Errorf("missing required field 'protected': %w", ErrMalformed)
|
||||
}
|
||||
jwkBase64 := rawProtectedBase64.(string)
|
||||
jwkBase64, ok := rawProtectedBase64.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to parse 'protected' field: %w", ErrMalformed)
|
||||
}
|
||||
|
||||
jwkBytes, err := base64.RawURLEncoding.DecodeString(jwkBase64)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,103 @@ func TestAcmeNonces(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestVerifyEabPayloadProtectedFieldValidation verifies that the verifyEabPayload function
|
||||
// properly validates and rejects malformed 'protected' fields in ACME External Account Binding
|
||||
// (EAB) payloads. It ensures that only string values are accepted and that various non-string
|
||||
// types (object, array, number, boolean) produce appropriate error messages.
|
||||
func TestVerifyEabPayloadProtectedFieldValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
payload map[string]interface{}
|
||||
expectError bool
|
||||
expectMessage string
|
||||
}{
|
||||
{
|
||||
name: "valid string protected field",
|
||||
payload: map[string]interface{}{
|
||||
"protected": "eyJhbGciOiAiSFMyNTYifQ",
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "missing protected field",
|
||||
payload: map[string]interface{}{
|
||||
"payload": "test",
|
||||
"signature": "test",
|
||||
},
|
||||
expectError: true,
|
||||
expectMessage: "missing required field 'protected'",
|
||||
},
|
||||
{
|
||||
name: "protected field as object",
|
||||
payload: map[string]interface{}{
|
||||
"protected": map[string]interface{}{ // should be a string, not an object
|
||||
"alg": "HS256",
|
||||
},
|
||||
"payload": "test",
|
||||
"signature": "test",
|
||||
},
|
||||
expectError: true,
|
||||
expectMessage: "failed to parse 'protected' field",
|
||||
},
|
||||
{
|
||||
name: "protected field as array",
|
||||
payload: map[string]interface{}{
|
||||
"protected": []interface{}{"test"}, // should be a string, not an array
|
||||
"payload": "test",
|
||||
"signature": "test",
|
||||
},
|
||||
expectError: true,
|
||||
expectMessage: "failed to parse 'protected' field",
|
||||
},
|
||||
{
|
||||
name: "protected field as number",
|
||||
payload: map[string]interface{}{
|
||||
"protected": 12345, // should be a string, not a number
|
||||
"payload": "test",
|
||||
"signature": "test",
|
||||
},
|
||||
expectError: true,
|
||||
expectMessage: "failed to parse 'protected' field",
|
||||
},
|
||||
{
|
||||
name: "protected field as boolean",
|
||||
payload: map[string]interface{}{
|
||||
"protected": true, // should be a string, not a boolean
|
||||
"payload": "test",
|
||||
"signature": "test",
|
||||
},
|
||||
expectError: true,
|
||||
expectMessage: "failed to parse 'protected' field",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
acmeState := NewACMEState()
|
||||
acmeCtx := &acmeContext{}
|
||||
outerJws := &jwsCtx{}
|
||||
|
||||
_, err := verifyEabPayload(acmeState, acmeCtx, outerJws, "/new-account", tc.payload)
|
||||
|
||||
if tc.expectError {
|
||||
require.Error(t, err, "expected error but got none")
|
||||
require.Contains(t, err.Error(), tc.expectMessage, "error message does not match")
|
||||
require.NotEmpty(t, err.Error())
|
||||
} else {
|
||||
// For valid protected field, we expect an error later in the flow
|
||||
// (since we don't have real base64 data), but it should NOT be from parsing the protected field
|
||||
if err != nil {
|
||||
require.NotContains(t, err.Error(), "failed to parse 'protected' field",
|
||||
"should not fail at protected field parsing stage")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestErrorResponseNoSubproblems builds the http body that exists in the header of an ACME error response and checks
|
||||
// in a simple case that "type" and "detail" two fields on the body do exist, but that "subproblems" a field which is
|
||||
// optional, is omitted because it does not exist in this case (rather than being included with a value null which can
|
||||
|
|
|
|||
3
changelog/_12260.txt
Normal file
3
changelog/_12260.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
secrets/pki: fix panic during acme account creation with malformed protected field.
|
||||
``
|
||||
Loading…
Reference in a new issue