diff --git a/src/auth.go b/src/auth.go index 015aa3f..433ac98 100644 --- a/src/auth.go +++ b/src/auth.go @@ -185,7 +185,7 @@ func authorizeRequest(r *http.Request, allowWildcard bool) ([]string, error) { causes := []error{AuthError{http.StatusUnauthorized, "unauthorized"}} if InsecureMode() { - log.Println("auth: INSECURE mode: allow any") + log.Println("auth: INSECURE mode: allow *") return nil, nil // for testing only } @@ -195,7 +195,7 @@ func authorizeRequest(r *http.Request, allowWildcard bool) ([]string, error) { } else if err != nil { // bad request return nil, err } else { - log.Println("auth: DNS challenge: allow any") + log.Println("auth: DNS challenge: allow *") return repoURLs, nil } @@ -254,3 +254,22 @@ func AuthorizeRepository(repoURL string, allowRepoURLs []string) error { } } } + +// The purpose of `allowRepoURLs` is to make sure that only authorized content is deployed +// to the site despite the fact that the non-shared-secret authorization methods allow anyone +// to impersonate the legitimate webhook sender. (If switching to another repository URL would +// be catastrophic, then so would be switching to a different branch.) +func AuthorizeBranch(branch string, allowRepoURLs []string) error { + if allowRepoURLs == nil { + return nil // any + } + + if branch == "pages" { + return nil + } else { + return AuthError{ + http.StatusUnauthorized, + fmt.Sprintf("branch %s: password authorization required", branch), + } + } +} diff --git a/src/pages.go b/src/pages.go index d0eb620..2e96bed 100644 --- a/src/pages.go +++ b/src/pages.go @@ -181,9 +181,12 @@ func putPage(w http.ResponseWriter, r *http.Request) error { return err } - branch := r.Header.Get("X-Pages-Branch") - if branch == "" { - branch = "pages" + branch := "pages" + if customBranch := r.Header.Get("X-Pages-Branch"); customBranch != "" { + branch = customBranch + } + if err := AuthorizeBranch(branch, allowedRepoURLs); err != nil { + return err } ctx, cancel := context.WithTimeout(r.Context(), updateTimeout)