From b437a872665236f2b7b6ea2d1c8204a2aff5f751 Mon Sep 17 00:00:00 2001
From: Philipp Heckel <pheckel@datto.com>
Date: Wed, 8 Dec 2021 22:13:59 -0500
Subject: [PATCH] Disallow subscribing to /docs

---
 server/server.go |  8 ++++++--
 util/util.go     | 10 ++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/server/server.go b/server/server.go
index 654725fe..c8db3fc5 100644
--- a/server/server.go
+++ b/server/server.go
@@ -81,8 +81,9 @@ var (
 	sseRegex   = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/sse$`)
 	rawRegex   = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/raw$`)
 
-	staticRegex = regexp.MustCompile(`^/static/.+`)
-	docsRegex   = regexp.MustCompile(`^/docs(|/.*)$`)
+	staticRegex      = regexp.MustCompile(`^/static/.+`)
+	docsRegex        = regexp.MustCompile(`^/docs(|/.*)$`)
+	disallowedTopics = []string{"docs", "static"}
 
 	//go:embed "index.gohtml"
 	indexSource   string
@@ -496,6 +497,9 @@ func (s *Server) topicsFromIDs(ids ...string) ([]*topic, error) {
 	defer s.mu.Unlock()
 	topics := make([]*topic, 0)
 	for _, id := range ids {
+		if util.InStringList(disallowedTopics, id) {
+			return nil, errHTTPBadRequest
+		}
 		if _, ok := s.topics[id]; !ok {
 			if len(s.topics) >= s.config.GlobalTopicLimit {
 				return nil, errHTTPTooManyRequests
diff --git a/util/util.go b/util/util.go
index 742ca31e..331f8c5e 100644
--- a/util/util.go
+++ b/util/util.go
@@ -23,6 +23,16 @@ func FileExists(filename string) bool {
 	return stat != nil
 }
 
+// InStringList returns true if needle is contained in haystack
+func InStringList(haystack []string, needle string) bool {
+	for _, s := range haystack {
+		if s == needle {
+			return true
+		}
+	}
+	return false
+}
+
 // RandomString returns a random string with a given length
 func RandomString(length int) string {
 	randomMutex.Lock() // Who would have thought that random.Intn() is not thread-safe?!