Update host redirect handling for gvisor.dev

We now make sure that the requested domain is a valid domain based on the
custom domain and project ID settings before redirecting.

PiperOrigin-RevId: 548859553
This commit is contained in:
Ian Lewis
2023-07-17 19:03:44 -07:00
committed by gVisor bot
parent 150831fad9
commit 14df01fae6
2 changed files with 58 additions and 13 deletions
+2 -1
View File
@@ -453,7 +453,8 @@ website-build: load-jekyll ## Build the site image locally.
.PHONY: website-build
website-server: website-build ## Run a local server for development.
@docker run -i -p 8080:8080 $(WEBSITE_IMAGE)
@# NOTE: When running locally we use the localhost:8080 as custom domain.
@docker run -i -p 8080:8080 $(WEBSITE_IMAGE) --custom-domain='*'
.PHONY: website-server
website-push: website-build ## Push a new image and update the service.
+56 -12
View File
@@ -143,24 +143,57 @@ func redirectWithQuery(w http.ResponseWriter, r *http.Request, target string) {
http.Redirect(w, r, url, http.StatusFound)
}
// hostRedirectHandler redirects the www. domain to the naked domain.
func hostRedirectHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.Host, "www.") {
// Redirect to the naked domain.
r.URL.Scheme = "https" // Assume https.
r.URL.Host = r.Host[4:] // Remove the 'www.'
http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently)
// domainMatch returns whether the domain is accepted and if we should redirect
// to a custom domain.
func domainMatch(host string) (redirect bool, ok bool) {
if *customHost == "*" {
redirect = false
ok = true
return
}
// Custom Host handling.
if *customHost != "" {
if host == "www."+*customHost {
redirect = true
ok = true
return
}
if *projectID != "" && r.Host == *projectID+".appspot.com" && *customHost != "" {
// Redirect to the custom domain.
if host == *customHost {
ok = true
return
}
}
// Cloud Run App domain handling.
if strings.HasPrefix(host, *projectID+"-") && strings.HasSuffix(host, ".run.app") {
redirect = *customHost != ""
ok = true
return
}
return
}
// hostRedirectHandler redirects the www. domain to the naked domain.
func hostRedirectHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
redirect, ok := domainMatch(r.Host)
if !ok {
// Do not serve on invalid domains.
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
if redirect {
// Redirect to the naked domain.
r.URL.Scheme = "https" // Assume https.
r.URL.Host = *customHost
http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently)
return
}
h.ServeHTTP(w, r)
})
}
@@ -376,14 +409,25 @@ var (
addr = flag.String("http", envFlagString("HTTP", ":"+envFlagString("PORT", "8080")), "HTTP service address")
staticDir = flag.String("static-dir", envFlagString("STATIC_DIR", "_site"), "static files directory")
// Uses the standard GOOGLE_CLOUD_PROJECT environment variable set by App Engine.
projectID = flag.String("project-id", envFlagString("GOOGLE_CLOUD_PROJECT", ""), "The App Engine project ID.")
// NOTE: GOOGLE_CLOUD_PROJECT environment variable does not seem to be used
// anymore by Google Cloud but we can continue to look for it and fall back
// to the default project.
projectID = flag.String("project-id", envFlagString("GOOGLE_PROJECT_ID", "gvisordev"), "The Google Cloud project ID.")
customHost = flag.String("custom-domain", envFlagString("CUSTOM_DOMAIN", "gvisor.dev"), "The application's custom domain.")
)
func main() {
flag.Parse()
if *customHost == "*" {
fmt.Println("WARNING: custom domain of '*' matches anything and is potentially insecure.")
}
if *projectID == "" {
fmt.Fprintf(os.Stderr, "Project ID not set.\n")
os.Exit(1)
}
registerRedirects(http.DefaultServeMux)
registerStatic(http.DefaultServeMux, *staticDir)
registerProfile(http.DefaultServeMux)