@marcel91200 / caddy Mirror · read-only / commits / 9d2cb35c
Fork 0

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 {