Repository: google/go-safeweb
Pull request #197 (2020-10-09 09:09:56)

htmlinject: added rule for styles and exported useful constants.
It was previously hard and brittle to use htmlinject as some constants were not exported (the ones to use as map keys in funcmap).

Moreover we were not noncing syles because our CSP plugin does not set the style-src directive, but users might want to use a different, stricter, CSP implementation.


Patch:
diff --git a/safehttp/mux.go b/safehttp/mux.go
index d95f1bf..4b4345a 100644
--- a/safehttp/mux.go
+++ b/safehttp/mux.go
@@ -151,7 +151,7 @@ func (m *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 }
 
 // ServeMuxBuilder is a builder for ServeMux.
-type ServeMuxConfig struct {
+type ServeMuxBuilder struct {
 	dispatcher   Dispatcher
 	handlers     []handlerRegistration
 	interceptors []Interceptor
@@ -172,48 +172,36 @@ type handlerRegistration struct {
 // corresponding Interceptor was not installed will produce no effect. If
 // multiple configurations are passed for the same Interceptor, only the first
 // one will take effect.
-func (s *ServeMuxConfig) Handle(pattern string, method string, h Handler, cfgs ...InterceptorConfig) {
-	s.handlers = append(s.handlers, handlerRegistration{
+func (b *ServeMuxBuilder) Handle(pattern string, method string, h Handler, cfgs ...InterceptorConfig) *ServeMuxBuilder {
+	b.handlers = append(b.handlers, handlerRegistration{
 		pattern: pattern,
 		method:  method,
 		handler: h,
 		cfgs:    cfgs,
 	})
+	return b
 }
 
-// Intercept installs an Interceptor.
+// Install installs an Interceptor.
 //
 // Interceptors order is undetermined and should not be relied on.
-func (s *ServeMuxConfig) Intercept(i Interceptor) {
-	s.interceptors = append(s.interceptors, i)
+func (b *ServeMuxBuilder) Install(i Interceptor) *ServeMuxBuilder {
+	b.interceptors = append(b.interceptors, i)
+	return b
 }
 
-// Mux returns the ServeMux with a copy of the current configuration.
-func (s *ServeMuxConfig) Mux() *ServeMux {
-	m := newServeMux(s.dispatcher)
-	for _, it := range s.interceptors {
+// Build builds the ServeMux.
+func (b *ServeMuxBuilder) Build() *ServeMux {
+	m := newServeMux(b.dispatcher)
+	for _, it := range b.interceptors {
 		m.install(it)
 	}
-	for _, hr := range s.handlers {
+	for _, hr := range b.handlers {
 		m.handle(hr.pattern, hr.method, hr.handler, hr.cfgs...)
 	}
 	return m
 }
 
-// Clone creates a copy of the current config.
-// This can be used to create several instances of Mux that share the same set of
-// plugins and some common handlers.
-func (s *ServeMuxConfig) Clone() *ServeMuxConfig {
-	c := &ServeMuxConfig{
-		dispatcher:   s.dispatcher,
-		handlers:     make([]handlerRegistration, len(s.handlers)),
-		interceptors: make([]Interceptor, len(s.interceptors)),
-	}
-	copy(c.handlers, s.handlers)
-	copy(c.interceptors, s.interceptors)
-	return c
-}
-
 // standardHandler is a collection of handler based on the request method.
 type standardHandler struct {
 	// Maps an HTTP method to its handler
diff --git a/safehttp/plugins/htmlinject/htmlinject.go b/safehttp/plugins/htmlinject/htmlinject.go
index 192a1c6..c7dbc89 100644
--- a/safehttp/plugins/htmlinject/htmlinject.go
+++ b/safehttp/plugins/htmlinject/htmlinject.go
@@ -48,9 +48,12 @@ func (r Rule) String() string { return r.Name }
 // Config is a slice of Rules that are somehow related to each other.
 type Config []Rule
 
+// CSPNoncesDefaultFuncName is the default func name for the func that generates CSP nonces.
+const CSPNoncesDefaultFuncName = "CSPNonce"
+
 // CSPNoncesDefault is the default config for CSP Nonces. The rewritten template
 // expects the CSPNonce Func to be available in the template to provide nonces.
-var CSPNoncesDefault = CSPNonces(`nonce="{{CSPNonce}}"`)
+var CSPNoncesDefault = CSPNonces(`nonce="{{` + CSPNoncesDefaultFuncName + `}}"`)
 
 // CSPNonces constructs a Config to add CSP nonces to a template. The given nonce
 // attribute will be automatically prefixed with the required empty space.
@@ -68,13 +71,21 @@ func CSPNonces(nonceAttr string) Config {
 			WithAttributes: map[string]string{"rel": "preload", "as": "script"},
 			AddAttributes:  []string{nonceAttr},
 		},
+		Rule{
+			Name:          "Nonces for styles",
+			OnTag:         "style",
+			AddAttributes: []string{nonceAttr},
+		},
 	}
 }
 
+// XSRFTokensDefaultFuncName is the default func name for the func that generates XSRF tokens.
+const XSRFTokensDefaultFuncName = `XSRFToken`
+
 // XSRFTokensDefault is the default config to add hidden inputs to forms to provide
 // an anti-XSRF token. The rewritten template expects the XSRFToken Func to be available
 // in the template to provide tokens and sets the name for the sent value to be "xsrf-token".
-var XSRFTokensDefault = XSRFTokens(`<input type="hidden" name="xsrf-token" value="{{XSRFToken}}">`)
+var XSRFTokensDefault = XSRFTokens(`<input type="hidden" name="xsrf-token" value="{{` + XSRFTokensDefaultFuncName + `}}">`)
 
 // XSRFTokens constructs a Config to add the given string as a child node to forms.
 func XSRFTokens(inputTag string) Config {


Test patch:
diff --git a/safehttp/mux_test.go b/safehttp/mux_test.go
index c740734..274ccf0 100644
--- a/safehttp/mux_test.go
+++ b/safehttp/mux_test.go
@@ -59,7 +59,7 @@ func TestMuxOneHandlerOneRequest(t *testing.T) {
 
 	for _, tt := range test {
 		t.Run(tt.name, func(t *testing.T) {
-			mb := &safehttp.ServeMuxConfig{}
+			mb := &safehttp.ServeMuxBuilder{}
 
 			h := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
@@ -69,7 +69,7 @@ func TestMuxOneHandlerOneRequest(t *testing.T) {
 			b := &strings.Builder{}
 			rw := safehttptest.NewTestResponseWriter(b)
 
-			mux := mb.Mux()
+			mux := mb.Build()
 			mux.ServeHTTP(rw, tt.req)
 
 			if rw.Status() != tt.wantStatus {
@@ -122,10 +122,10 @@ func TestMuxServeTwoHandlers(t *testing.T) {
 		},
 	}
 
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	mb.Handle("/bar", safehttp.MethodGet, tests[0].hf)
 	mb.Handle("/bar", safehttp.MethodPost, tests[1].hf)
-	mux := mb.Mux()
+	mux := mb.Build()
 
 	for _, test := range tests {
 		b := &strings.Builder{}
@@ -146,7 +146,7 @@ func TestMuxServeTwoHandlers(t *testing.T) {
 }
 
 func TestMuxHandleSameMethodTwice(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 
 	registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
@@ -160,7 +160,7 @@ func TestMuxHandleSameMethodTwice(t *testing.T) {
 	}()
 
 	mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
-	mb.Mux()
+	mb.Build()
 }
 
 type setHeaderInterceptor struct {
@@ -252,8 +252,8 @@ func TestMuxInterceptors(t *testing.T) {
 		{
 			name: "Install ServeMux Interceptor before handler registration",
 			mux: func() *safehttp.ServeMux {
-				mb := &safehttp.ServeMuxConfig{}
-				mb.Intercept(setHeaderInterceptor{
+				mb := &safehttp.ServeMuxBuilder{}
+				mb.Install(setHeaderInterceptor{
 					name:  "Foo",
 					value: "bar",
 				})
@@ -262,7 +262,7 @@ func TestMuxInterceptors(t *testing.T) {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
-				return mb.Mux()
+				return mb.Build()
 			}(),
 			wantStatus: safehttp.StatusOK,
 			wantHeaders: map[string][]string{
@@ -274,15 +274,15 @@ func TestMuxInterceptors(t *testing.T) {
 		{
 			name: "Install Interrupting Interceptor",
 			mux: func() *safehttp.ServeMux {
-				mb := &safehttp.ServeMuxConfig{}
-				mb.Intercept(internalErrorInterceptor{})
+				mb := &safehttp.ServeMuxBuilder{}
+				mb.Install(internalErrorInterceptor{})
 
 				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
 
-				return mb.Mux()
+				return mb.Build()
 			}(),
 			wantStatus: safehttp.StatusInternalServerError,
 			wantHeaders: map[string][]string{
@@ -294,8 +294,8 @@ func TestMuxInterceptors(t *testing.T) {
 		{
 			name: "Handler Communication With ServeMux Interceptor",
 			mux: func() *safehttp.ServeMux {
-				mb := &safehttp.ServeMuxConfig{}
-				mb.Intercept(&claimHeaderInterceptor{headerToClaim: "Foo"})
+				mb := &safehttp.ServeMuxBuilder{}
+				mb.Install(&claimHeaderInterceptor{headerToClaim: "Foo"})
 
 				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					claimInterceptorSetHeader(w, r, "bar")
@@ -303,7 +303,7 @@ func TestMuxInterceptors(t *testing.T) {
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
 
-				return mb.Mux()
+				return mb.Build()
 			}(),
 			wantStatus: safehttp.StatusOK,
 			wantHeaders: map[string][]string{
@@ -315,15 +315,15 @@ func TestMuxInterceptors(t *testing.T) {
 		{
 			name: "Panicking interceptor recovered by ServeMux",
 			mux: func() *safehttp.ServeMux {
-				mb := &safehttp.ServeMuxConfig{}
-				mb.Intercept(panickingInterceptor{})
+				mb := &safehttp.ServeMuxBuilder{}
+				mb.Install(panickingInterceptor{})
 
 				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
 
-				return mb.Mux()
+				return mb.Build()
 			}(),
 			wantStatus: safehttp.StatusInternalServerError,
 			wantHeaders: map[string][]string{
@@ -335,15 +335,15 @@ func TestMuxInterceptors(t *testing.T) {
 		{
 			name: "Commit phase sets header",
 			mux: func() *safehttp.ServeMux {
-				mb := &safehttp.ServeMuxConfig{}
-				mb.Intercept(committerInterceptor{})
+				mb := &safehttp.ServeMuxBuilder{}
+				mb.Install(committerInterceptor{})
 
 				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
 
-				return mb.Mux()
+				return mb.Build()
 			}(),
 			wantStatus: safehttp.StatusOK,
 			wantHeaders: map[string][]string{
@@ -452,8 +452,8 @@ func TestMuxInterceptorConfigs(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			mb := &safehttp.ServeMuxConfig{}
-			mb.Intercept(setHeaderConfigInterceptor{})
+			mb := &safehttp.ServeMuxBuilder{}
+			mb.Install(setHeaderConfigInterceptor{})
 
 			registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
@@ -465,7 +465,7 @@ func TestMuxInterceptorConfigs(t *testing.T) {
 
 			req := httptest.NewRequest("GET", "http://foo.com/bar", nil)
 
-			mux := mb.Mux()
+			mux := mb.Build()
 			mux.ServeHTTP(rw, req)
 
 			if rw.Status() != tt.wantStatus {
@@ -535,10 +535,10 @@ func (interceptorThree) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingR
 }
 
 func TestMuxDeterministicInterceptorOrder(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
-	mb.Intercept(interceptorOne{})
-	mb.Intercept(interceptorTwo{})
-	mb.Intercept(interceptorThree{})
+	mb := &safehttp.ServeMuxBuilder{}
+	mb.Install(interceptorOne{})
+	mb.Install(interceptorTwo{})
+	mb.Install(interceptorThree{})
 
 	registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
@@ -550,7 +550,7 @@ func TestMuxDeterministicInterceptorOrder(t *testing.T) {
 
 	req := httptest.NewRequest("GET", "http://foo.com/bar", nil)
 
-	mux := mb.Mux()
+	mux := mb.Build()
 	mux.ServeHTTP(rw, req)
 
 	if want := safehttp.StatusOK; rw.Status() != want {
@@ -574,7 +574,7 @@ func TestMuxDeterministicInterceptorOrder(t *testing.T) {
 }
 
 func TestMuxHandlerReturnsNotWritten(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	h := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return safehttp.NotWritten()
 	})
@@ -584,7 +584,7 @@ func TestMuxHandlerReturnsNotWritten(t *testing.T) {
 	b := &strings.Builder{}
 	rw := safehttptest.NewTestResponseWriter(b)
 
-	mux := mb.Mux()
+	mux := mb.Build()
 	mux.ServeHTTP(rw, req)
 
 	if want := safehttp.StatusNoContent; rw.Status() != want {
diff --git a/safehttp/plugins/hostcheck/hostcheck_test.go b/safehttp/plugins/hostcheck/hostcheck_test.go
index 5fb968f..c7e7d6d 100644
--- a/safehttp/plugins/hostcheck/hostcheck_test.go
+++ b/safehttp/plugins/hostcheck/hostcheck_test.go
@@ -46,8 +46,8 @@ func TestInterceptor(t *testing.T) {
 
 	for _, tt := range test {
 		t.Run(tt.name, func(t *testing.T) {
-			mb := &safehttp.ServeMuxConfig{}
-			mb.Intercept(hostcheck.New("foo.com"))
+			mb := &safehttp.ServeMuxBuilder{}
+			mb.Install(hostcheck.New("foo.com"))
 
 			h := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
@@ -56,7 +56,7 @@ func TestInterceptor(t *testing.T) {
 
 			b := &strings.Builder{}
 			rw := safehttptest.NewTestResponseWriter(b)
-			mux := mb.Mux()
+			mux := mb.Build()
 			mux.ServeHTTP(rw, tt.req)
 
 			if rw.Status() != tt.wantStatus {
diff --git a/safehttp/plugins/htmlinject/htmlinject_test.go b/safehttp/plugins/htmlinject/htmlinject_test.go
index 894bf94..80e2d88 100644
--- a/safehttp/plugins/htmlinject/htmlinject_test.go
+++ b/safehttp/plugins/htmlinject/htmlinject_test.go
@@ -148,6 +148,11 @@ Hello world
 <html>
 <head>
 <link rel=preload as="script" src="gopher.js">
+<style>
+h1 {
+  border: 5px solid yellow;
+}
+</style>
 </head>
 <body>
 <script type="application/javascript">alert("script")</script>
@@ -158,6 +163,11 @@ Hello world
 <html>
 <head>
 <link nonce="{{CSPNonce}}" rel=preload as="script" src="gopher.js">
+<style nonce="{{CSPNonce}}">
+h1 {
+  border: 5px solid yellow;
+}
+</style>
 </head>
 <body>
 <script nonce="{{CSPNonce}}" type="application/javascript">alert("script")</script>
diff --git a/tests/integration/csp/csp_test.go b/tests/integration/csp/csp_test.go
index 827b0f8..b3a2f29 100644
--- a/tests/integration/csp/csp_test.go
+++ b/tests/integration/csp/csp_test.go
@@ -27,9 +27,9 @@ import (
 )
 
 func TestServeMuxInstallCSP(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	it := csp.Default("")
-	mb.Intercept(&it)
+	mb.Install(&it)
 
 	var nonce string
 	var err error
@@ -53,7 +53,7 @@ func TestServeMuxInstallCSP(t *testing.T) {
 
 	req := httptest.NewRequest(safehttp.MethodGet, "https://foo.com/bar", nil)
 
-	mux := mb.Mux()
+	mux := mb.Build()
 	mux.ServeHTTP(rr, req)
 
 	if err != nil {
diff --git a/tests/integration/header/header_test.go b/tests/integration/header/header_test.go
index 68f16ad..a3fd571 100644
--- a/tests/integration/header/header_test.go
+++ b/tests/integration/header/header_test.go
@@ -29,7 +29,7 @@ import (
 )
 
 func TestAccessIncomingHeaders(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		if got, want := ir.Header.Get("A"), "B"; got != want {
 			t.Errorf(`ir.Header.Get("A") got: %v want: %v`, got, want)
@@ -48,12 +48,12 @@ func TestAccessIncomingHeaders(t *testing.T) {
 	b := &strings.Builder{}
 	rw := safehttptest.NewTestResponseWriter(b)
 
-	mux := mb.Mux()
+	mux := mb.Build()
 	mux.ServeHTTP(rw, req)
 }
 
 func TestChangingResponseHeaders(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		rw.Header().Set("pIZZA", "Pasta")
 		return rw.Write(safehtml.HTMLEscaped("hello"))
@@ -64,7 +64,7 @@ func TestChangingResponseHeaders(t *testing.T) {
 	b := &strings.Builder{}
 	rw := safehttptest.NewTestResponseWriter(b)
 
-	mux := mb.Mux()
+	mux := mb.Build()
 	mux.ServeHTTP(rw, req)
 
 	want := []string{"Pasta"}
diff --git a/tests/integration/hsts/hsts_test.go b/tests/integration/hsts/hsts_test.go
index 9dd46b3..3627f81 100644
--- a/tests/integration/hsts/hsts_test.go
+++ b/tests/integration/hsts/hsts_test.go
@@ -29,9 +29,9 @@ import (
 )
 
 func TestHSTSServeMuxInstall(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 
-	mb.Intercept(hsts.Default())
+	mb.Install(hsts.Default())
 	handler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
@@ -42,7 +42,7 @@ func TestHSTSServeMuxInstall(t *testing.T) {
 
 	req := httptest.NewRequest(http.MethodGet, "https://foo.com/asdf", nil)
 
-	mb.Mux().ServeHTTP(rw, req)
+	mb.Build().ServeHTTP(rw, req)
 
 	if want := safehttp.StatusOK; rw.Status() != want {
 		t.Errorf("rw.Status() got: %v want: %v", rw.Status(), want)
diff --git a/tests/integration/mux/mux_test.go b/tests/integration/mux/mux_test.go
index f4c874b..6f93d2c 100644
--- a/tests/integration/mux/mux_test.go
+++ b/tests/integration/mux/mux_test.go
@@ -73,13 +73,13 @@ func TestMuxDefaultDispatcher(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			mb := &safehttp.ServeMuxConfig{}
+			mb := &safehttp.ServeMuxBuilder{}
 			mb.Handle("/pizza", safehttp.MethodGet, tt.handler)
 			req := httptest.NewRequest(safehttp.MethodGet, "http://foo.com/pizza", nil)
 			b := &strings.Builder{}
 			rw := safehttptest.NewTestResponseWriter(b)
 
-			mb.Mux().ServeHTTP(rw, req)
+			mb.Build().ServeHTTP(rw, req)
 
 			if wantStatus := safehttp.StatusOK; rw.Status() != wantStatus {
 				t.Errorf("rw.Status(): got %v want %v", rw.Status(), wantStatus)
@@ -132,9 +132,9 @@ func TestMuxDefaultDispatcherUnsafeResponses(t *testing.T) {
 			b := &strings.Builder{}
 			rw := safehttptest.NewTestResponseWriter(b)
 
-			mb := &safehttp.ServeMuxConfig{}
+			mb := &safehttp.ServeMuxBuilder{}
 			mb.Handle("/pizza", safehttp.MethodGet, tt.handler)
-			mux := mb.Mux()
+			mux := mb.Build()
 			mux.ServeHTTP(rw, req)
 
 			if wantStatus := safehttp.StatusInternalServerError; rw.Status() != wantStatus {
diff --git a/tests/integration/safehtml/safehtml_test.go b/tests/integration/safehtml/safehtml_test.go
index a8303a3..efa74a2 100644
--- a/tests/integration/safehtml/safehtml_test.go
+++ b/tests/integration/safehtml/safehtml_test.go
@@ -27,7 +27,7 @@ import (
 )
 
 func TestHandleRequestWrite(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		return rw.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 	}))
@@ -37,7 +37,7 @@ func TestHandleRequestWrite(t *testing.T) {
 	b := &strings.Builder{}
 	rw := safehttptest.NewTestResponseWriter(b)
 
-	mb.Mux().ServeHTTP(rw, req)
+	mb.Build().ServeHTTP(rw, req)
 
 	body := b.String()
 
@@ -47,7 +47,7 @@ func TestHandleRequestWrite(t *testing.T) {
 }
 
 func TestHandleRequestWriteTemplate(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		return rw.WriteTemplate(template.Must(template.New("name").Parse("<h1>{{ . }}</h1>")), "This is an actual heading, though.")
 	}))
@@ -57,7 +57,7 @@ func TestHandleRequestWriteTemplate(t *testing.T) {
 	b := &strings.Builder{}
 	rw := safehttptest.NewTestResponseWriter(b)
 
-	mb.Mux().ServeHTTP(rw, req)
+	mb.Build().ServeHTTP(rw, req)
 
 	body := b.String()
 
diff --git a/tests/integration/staticheaders/staticheaders_test.go b/tests/integration/staticheaders/staticheaders_test.go
index c64950c..fc083e0 100644
--- a/tests/integration/staticheaders/staticheaders_test.go
+++ b/tests/integration/staticheaders/staticheaders_test.go
@@ -29,9 +29,9 @@ import (
 )
 
 func TestServeMuxInstallStaticHeaders(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 
-	mb.Intercept(staticheaders.Interceptor{})
+	mb.Install(staticheaders.Interceptor{})
 	handler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
@@ -42,7 +42,7 @@ func TestServeMuxInstallStaticHeaders(t *testing.T) {
 
 	req := httptest.NewRequest(http.MethodGet, "https://foo.com/asdf", nil)
 
-	mb.Mux().ServeHTTP(rw, req)
+	mb.Build().ServeHTTP(rw, req)
 
 	if want := safehttp.StatusOK; rw.Status() != want {
 		t.Errorf("rw.Status() got: %v want: %v", rw.Status(), want)
diff --git a/tests/integration/xsrf/xsrf_test.go b/tests/integration/xsrf/xsrf_test.go
index 85f92d8..cad2547 100644
--- a/tests/integration/xsrf/xsrf_test.go
+++ b/tests/integration/xsrf/xsrf_test.go
@@ -26,9 +26,9 @@ import (
 )
 
 func TestServeMuxInstallXSRF(t *testing.T) {
-	mb := &safehttp.ServeMuxConfig{}
+	mb := &safehttp.ServeMuxBuilder{}
 	it := xsrf.Interceptor{SecretAppKey: "testSecretAppKey"}
-	mb.Intercept(&it)
+	mb.Install(&it)
 
 	var token string
 	var err error
@@ -52,7 +52,7 @@ func TestServeMuxInstallXSRF(t *testing.T) {
 
 	req := httptest.NewRequest(safehttp.MethodGet, "https://foo.com/bar", nil)
 
-	mb.Mux().ServeHTTP(rr, req)
+	mb.Build().ServeHTTP(rr, req)
 
 	if err != nil {
 		t.Fatalf("xsrf.Token: got error %v", err)