From ecec9758b6f34387c783ca924f550bccea9fa12d Mon Sep 17 00:00:00 2001 From: Jack McCracken Date: Thu, 22 Jun 2017 14:10:02 -0400 Subject: [PATCH 1/2] Address an issue where a toxiproxy can be used to bypass the Same-Origin Policy in web browsers --- api.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/api.go b/api.go index 9bb76982..35be6df1 100644 --- a/api.go +++ b/api.go @@ -7,10 +7,11 @@ import ( "net" "net/http" "os" + "strings" "github.com/Shopify/toxiproxy/toxics" - "github.com/sirupsen/logrus" "github.com/gorilla/mux" + "github.com/sirupsen/logrus" ) type ApiServer struct { @@ -46,6 +47,16 @@ func (server *ApiServer) PopulateConfig(filename string) { } } +func StopBrowsersMiddleware(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.UserAgent(), "Mozilla/") { + http.Error(w, "User agent not allowed", 403) + } else { + h.ServeHTTP(w, r) + } + }) +} + func (server *ApiServer) Listen(host string, port string) { r := mux.NewRouter() r.HandleFunc("/reset", server.ResetState).Methods("POST") @@ -62,7 +73,8 @@ func (server *ApiServer) Listen(host string, port string) { r.HandleFunc("/proxies/{proxy}/toxics/{toxic}", server.ToxicDelete).Methods("DELETE") r.HandleFunc("/version", server.Version).Methods("GET") - http.Handle("/", r) + + http.Handle("/", StopBrowsersMiddleware(r)) logrus.WithFields(logrus.Fields{ "host": host, From 7dae2efe95fa82d77f783c2258af163652a01e07 Mon Sep 17 00:00:00 2001 From: Jack McCracken Date: Thu, 22 Jun 2017 15:06:26 -0400 Subject: [PATCH 2/2] Add tests for expected behaviour of user-agent filter --- api_test.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/api_test.go b/api_test.go index c185f7dd..488f3d1e 100644 --- a/api_test.go +++ b/api_test.go @@ -36,6 +36,36 @@ func WithServer(t *testing.T, f func(string)) { f("http://localhost:8475") } +func TestBrowserGets403(t *testing.T) { + WithServer(t, func(addr string) { + client := http.Client{} + + req, _ := http.NewRequest("GET", "http://localhost:8475/proxies", nil) + req.Header.Add("User-Agent", "Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047") + + resp, _ := client.Do(req) + + if resp.StatusCode != 403 { + t.Fatal("Browser-like UserAgent was not denied access to Toxiproxy") + } + }) +} + +func TestNonBrowserGets200(t *testing.T) { + WithServer(t, func(addr string) { + client := http.Client{} + + req, _ := http.NewRequest("GET", "http://localhost:8475/proxies", nil) + req.Header.Add("User-Agent", "Wget/2.1") + + resp, _ := client.Do(req) + + if resp.StatusCode == 403 { + t.Fatal("Non-Browser-like UserAgent was denied access to Toxiproxy") + } + }) +} + func TestIndexWithNoProxies(t *testing.T) { WithServer(t, func(addr string) { client := tclient.NewClient(addr)