From 9a4e3f3ef3b233b5089fa9de5ede426dac8265be Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Fri, 9 Jan 2026 11:49:53 -0800 Subject: [PATCH] Fix special characters in admin-generated secret keys Fixes #7990 The issue was that the Charset constant used for generating secret keys included the '/' character, which is URL-unsafe. When secret keys containing '/' were used in HTTP requests, they would be URL-encoded, causing a mismatch during signature verification. Changes: - Removed '/' from the Charset constant in weed/iam/constants.go - Added TestGenerateSecretAccessKey_URLSafe to verify generated keys don't contain URL-unsafe characters like '/' or '+' This ensures all newly generated secret keys are URL-safe and will work correctly with S3 authentication. Existing keys continue to work. --- weed/iam/constants.go | 2 +- weed/iam/helpers_test.go | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/weed/iam/constants.go b/weed/iam/constants.go index 7dea524e8..974645be7 100644 --- a/weed/iam/constants.go +++ b/weed/iam/constants.go @@ -3,7 +3,7 @@ package iam // Character sets for credential generation const ( CharsetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - Charset = CharsetUpper + "abcdefghijklmnopqrstuvwxyz/" + Charset = CharsetUpper + "abcdefghijklmnopqrstuvwxyz" ) // Policy document version diff --git a/weed/iam/helpers_test.go b/weed/iam/helpers_test.go index f2da389c3..6b39a3779 100644 --- a/weed/iam/helpers_test.go +++ b/weed/iam/helpers_test.go @@ -58,6 +58,23 @@ func TestGenerateSecretAccessKey(t *testing.T) { assert.Len(t, secretKey, SecretAccessKeyLength) } +func TestGenerateSecretAccessKey_URLSafe(t *testing.T) { + // Generate multiple keys to increase probability of catching unsafe chars + for i := 0; i < 100; i++ { + secretKey, err := GenerateSecretAccessKey() + assert.NoError(t, err) + + // Verify no URL-unsafe characters that would cause authentication issues + assert.NotContains(t, secretKey, "/", "Secret key should not contain /") + assert.NotContains(t, secretKey, "+", "Secret key should not contain +") + + // Verify only expected characters are present + for _, char := range secretKey { + assert.Contains(t, Charset, string(char), "Secret key contains unexpected character: %c", char) + } + } +} + func TestStringSlicesEqual(t *testing.T) { tests := []struct { a []string