From a36c7c7e87aef2adcd76b64b261927b182422dab Mon Sep 17 00:00:00 2001 From: Sebastian Hutter Date: Mon, 28 Jan 2019 11:26:22 +0100 Subject: [PATCH] Disable basic authentication for OPTIONS method (#2415) Execute an OPTIONS call and make sure we receive a valid response independently of the provided username or password as the authentication step is ignored * Do not authenticate OPTIONS calls * Add test for OPTIONS call --- caddyhttp/basicauth/basicauth.go | 6 ++++++ caddyhttp/basicauth/basicauth_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/caddyhttp/basicauth/basicauth.go b/caddyhttp/basicauth/basicauth.go index 0496c3e16..59c65418c 100644 --- a/caddyhttp/basicauth/basicauth.go +++ b/caddyhttp/basicauth/basicauth.go @@ -52,6 +52,12 @@ func (a BasicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error var protected, isAuthenticated bool var realm string + // do not check for basic auth on OPTIONS call + if r.Method == http.MethodOptions { + // Pass-through when no paths match + return a.Next.ServeHTTP(w, r) + } + for _, rule := range a.Rules { for _, res := range rule.Resources { if !httpserver.Path(r.URL.Path).Matches(res) { diff --git a/caddyhttp/basicauth/basicauth_test.go b/caddyhttp/basicauth/basicauth_test.go index 71255f763..1182b5226 100644 --- a/caddyhttp/basicauth/basicauth_test.go +++ b/caddyhttp/basicauth/basicauth_test.go @@ -194,3 +194,30 @@ md5:$apr1$l42y8rex$pOA2VJ0x/0TwaFeAF9nX61` } } } + +func TestOptionsMethod(t *testing.T) { + rw := BasicAuth{ + Next: httpserver.HandlerFunc(contentHandler), + Rules: []Rule{ + {Username: "username", Password: PlainMatcher("password"), Resources: []string{"/testing"}}, + }, + } + + req, err := http.NewRequest(http.MethodOptions, "/testing", nil) + if err != nil { + t.Fatalf("Could not create HTTP request: %v", err) + } + + // add basic auth with invalid username + // and password to make sure basic auth is ignored + req.SetBasicAuth("invaliduser", "invalidpassword") + + rec := httptest.NewRecorder() + result, err := rw.ServeHTTP(rec, req) + if err != nil { + t.Fatalf("Could not ServeHTTP: %v", err) + } + if result != http.StatusOK { + t.Errorf("Expected status code %d but was %d", http.StatusOK, result) + } +}