diff --git a/contribs/gnodev/pkg/emitter/middleware.go b/contribs/gnodev/pkg/emitter/middleware.go index 9c53cfe158e..e4def43f919 100644 --- a/contribs/gnodev/pkg/emitter/middleware.go +++ b/contribs/gnodev/pkg/emitter/middleware.go @@ -5,10 +5,10 @@ import ( _ "embed" "encoding/json" "fmt" + "html/template" "net/http" "strings" "sync" - "text/template" "github.com/gnolang/gno/contribs/gnodev/pkg/events" ) diff --git a/contribs/gnodev/pkg/emitter/middleware_test.go b/contribs/gnodev/pkg/emitter/middleware_test.go new file mode 100644 index 00000000000..063e46d0c84 --- /dev/null +++ b/contribs/gnodev/pkg/emitter/middleware_test.go @@ -0,0 +1,43 @@ +package emitter + +import ( + "fmt" + "net/http" + "net/http/httptest" + "regexp" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMiddlewareUsesHTMLTemplate(t *testing.T) { + tests := []struct { + name string + remote string + want string + }{ + {"normal remote", "localhost:9999", "const ws = new WebSocket('ws://localhost:9999');"}, + {"xss'd remote", `localhost:9999');alert('pwned`, "const ws = new WebSocket('ws://localhost:9999');alert('pwned');"}, + } + + // As the code revolves, add more search patterns here. + var reWebsocket = regexp.MustCompile("const ws = new WebSocket[^\n]+") + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rec := httptest.NewRecorder() + mdw := NewMiddleware(tt.remote, http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.Header().Set("Content-Type", "text/html") + fmt.Fprintf(rw, "") + })) + rec.Header().Set("Content-Type", "text/html") + req := httptest.NewRequest("GET", "https://gno.land/example", nil) + mdw.ServeHTTP(rec, req) + + targets := reWebsocket.FindAllString(rec.Body.String(), -1) + require.True(t, len(targets) > 0) + body := targets[0] + require.Equal(t, body, tt.want) + }) + } +}