From 5f00c3474892d9fdd2e4f2ea68db93b96ead41dc Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Tue, 10 Dec 2024 10:29:22 -0800 Subject: [PATCH] test(AtomicLevel): demonstrate Handler is not vulnerable to XSS (#1477) Adds a unit test and a fuzz test to demonstrate that the AtomicLevel handler is not vulnerable to XSS. I ran the fuzz test on my computer for 10 minutes on my laptop with no cases where `<...>` was present in the response body. ``` ... fuzz: elapsed: 9m57s, execs: 43145040 (95839/sec), new interesting: 442 (total: 445) fuzz: elapsed: 10m0s, execs: 43396113 (83690/sec), new interesting: 442 (total: 445) ``` Refs #1476 --- http_handler_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/http_handler_test.go b/http_handler_test.go index 9da3dc7b5..a4e9bcdf7 100644 --- a/http_handler_test.go +++ b/http_handler_test.go @@ -23,6 +23,7 @@ package zap_test import ( "encoding/json" "errors" + "io" "net/http" "net/http/httptest" "strings" @@ -215,3 +216,44 @@ type brokenHTTPResponseWriter struct { func (w *brokenHTTPResponseWriter) Write([]byte) (int, error) { return 0, errors.New("great sadness") } + +func TestAtomicLevelServeHTTPBadLevel(t *testing.T) { + srv := httptest.NewServer(zap.NewAtomicLevel()) + defer srv.Close() + + req, err := http.NewRequest(http.MethodPut, srv.URL, strings.NewReader(`{"level":""}`)) + require.NoError(t, err, "Error constructing request.") + + res, err := http.DefaultClient.Do(req) + require.NoError(t, err, "Error making request.") + defer func() { + assert.NoError(t, res.Body.Close(), "Error closing response body.") + }() + + assert.Equal(t, http.StatusBadRequest, res.StatusCode, "Unexpected status code.") + resBody, err := io.ReadAll(res.Body) + require.NoError(t, err, "Error reading response body.") + + assert.Contains(t, string(resBody), "unrecognized level", "Unexpected error message.") + assert.NotContains(t, string(resBody), ""}`) + f.Fuzz(func(t *testing.T, input string) { + lvl := zap.NewAtomicLevel() + + resw := httptest.NewRecorder() + req, err := http.NewRequest(http.MethodPut, "http://localhost:9999/log/level", strings.NewReader(input)) + require.NoError(t, err, "Error constructing request.") + + lvl.ServeHTTP(resw, req) + + require.NotEqual(t, http.StatusInternalServerError, resw.Code, "Unexpected status code.") + + // Response body must never contain HTML tags. + assert.NotRegexp(t, `<[^>]+>`, resw.Body.String(), "Unexpected HTML tag in response body.") + }) +}