Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 01:00 UTC
caddyauth: check basic_auth username uniqueness after placeholder expansion (#8315)
Kartik K committed
Nov 1, 2026 at 10:04 UTC
9d2cb35c75bd828114bbb2c4cf75678a5cdb7ba6
2 files changed
+36
-3
modules/caddyhttp/caddyauth/basicauth.go
+3
-3
@@ -102,13 +102,13 @@ func (hba *HTTPBasicAuth) Provision(ctx caddy.Context) error {
102
// load account list
103
hba.Accounts = make(map[string]Account)
104
for i, acct := range hba.AccountList {
105
+ acct.Username = repl.ReplaceKnown(acct.Username, "")
106
+ acct.Password = repl.ReplaceKnown(acct.Password, "")
107
+
108
if _, ok := hba.Accounts[acct.Username]; ok {
109
return fmt.Errorf("account %d: username is not unique: %s", i, acct.Username)
110
}
111
109
- acct.Username = repl.ReplaceKnown(acct.Username, "")
110
- acct.Password = repl.ReplaceKnown(acct.Password, "")
111
-
112
if acct.Username == "" || acct.Password == "" {
113
return fmt.Errorf("account %d: username and password are required", i)
114
}
modules/caddyhttp/caddyauth/basicauth_test.go
+33
@@ -99,6 +99,39 @@ func TestBasicAuthProvisionRejectsBracedPasswordInsteadOfRewritingIt(t *testing.
99
}
100
}
101
102
+func TestBasicAuthProvisionRejectsUsernamesThatCollideAfterExpansion(t *testing.T) {
103
+ t.Setenv("CADDYTEST_BASICAUTH_X", "carol")
104
+ t.Setenv("CADDYTEST_BASICAUTH_Y", "carol")
105
+ t.Setenv("CADDYTEST_BASICAUTH_Z", "dave")
106
+
107
+ for _, tc := range []struct {
108
+ first, second string
109
+ wantErr bool
110
+ }{
111
+ {"carol", "carol", true},
112
+ {"{env.CADDYTEST_BASICAUTH_X}", "{env.CADDYTEST_BASICAUTH_Y}", true},
113
+ {"carol", "{env.CADDYTEST_BASICAUTH_Y}", true},
114
+ {"{env.CADDYTEST_BASICAUTH_X}", "{env.CADDYTEST_BASICAUTH_X}", true},
115
+ {"{env.CADDYTEST_BASICAUTH_X}", "{env.CADDYTEST_BASICAUTH_Z}", false},
116
+ } {
117
+ hba := HTTPBasicAuth{
118
+ AccountList: []Account{
119
+ {Username: tc.first, Password: testBasicAuthHash},
120
+ {Username: tc.second, Password: testBasicAuthHash},
121
+ },
122
+ }
123
+ ctx, cancel := caddy.NewContext(caddy.Context{Context: context.Background()})
124
+ err := hba.Provision(ctx)
125
+ cancel()
126
+ if tc.wantErr && err == nil {
127
+ t.Errorf("%s + %s: expected a duplicate username error, got accounts %q", tc.first, tc.second, accountUsernames(hba))
128
+ }
129
+ if !tc.wantErr && err != nil {
130
+ t.Errorf("%s + %s: unexpected error: %v", tc.first, tc.second, err)
131
+ }
132
+ }
133
+}
134
+
135
func accountUsernames(hba HTTPBasicAuth) []string {
136
names := make([]string, 0, len(hba.Accounts))
137
for name := range hba.Accounts {