Skip to content

Commit b00a0fc

Browse files
committed
Web UI: Remove CORS headers
THe idea was that other applications could use the websockets to display the information their own way, but I'm not sure this is really used in practice
1 parent 1a3ace9 commit b00a0fc

1 file changed

Lines changed: 23 additions & 18 deletions

File tree

dnscrypt-proxy/monitoring_ui.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"html"
88
"net"
99
"net/http"
10+
"net/url"
1011
"os"
1112
"runtime"
1213
"sort"
@@ -192,14 +193,12 @@ func NewMonitoringUI(proxy *Proxy) *MonitoringUI {
192193
if origin == "" {
193194
return true // Allow requests without Origin header (direct connections)
194195
}
195-
host := r.Host
196-
if host == "" {
196+
originURL, err := url.Parse(origin)
197+
if err != nil || originURL.User != nil || originURL.Host == "" ||
198+
originURL.Path != "" || originURL.RawQuery != "" || originURL.Fragment != "" {
197199
return false
198200
}
199-
// Allow same-origin requests and localhost variations
200-
return origin == "http://"+host || origin == "https://"+host ||
201-
origin == "http://localhost:8080" || origin == "https://localhost:8080" ||
202-
origin == "http://127.0.0.1:8080" || origin == "https://127.0.0.1:8080"
201+
return originURL.Scheme == requestScheme(r) && strings.EqualFold(originURL.Host, r.Host)
203202
},
204203
},
205204
clients: make(map[*websocket.Conn]bool),
@@ -1021,11 +1020,24 @@ func (mc *MetricsCollector) GetMetrics() map[string]any {
10211020
return metrics
10221021
}
10231022

1024-
// setCORSHeaders - Sets standard CORS headers for all responses
1025-
func setCORSHeaders(w http.ResponseWriter) {
1026-
w.Header().Set("Access-Control-Allow-Origin", "*")
1027-
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
1028-
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
1023+
// requestScheme - Returns the scheme the client used, which a TLS-terminating
1024+
// proxy reports in X-Forwarded-Proto. Browsers cannot forge that header on a
1025+
// WebSocket handshake.
1026+
func requestScheme(r *http.Request) string {
1027+
forwarded := r.Header.Get("X-Forwarded-Proto")
1028+
if comma := strings.IndexByte(forwarded, ','); comma >= 0 {
1029+
forwarded = forwarded[:comma]
1030+
}
1031+
switch strings.ToLower(strings.TrimSpace(forwarded)) {
1032+
case "http":
1033+
return "http"
1034+
case "https":
1035+
return "https"
1036+
}
1037+
if r.TLS != nil {
1038+
return "https"
1039+
}
1040+
return "http"
10291041
}
10301042

10311043
// setDynamicCacheHeaders - Sets cache headers for dynamic content (metrics, API)
@@ -1070,9 +1082,6 @@ func (ui *MonitoringUI) handleTestQuery(w http.ResponseWriter, r *http.Request)
10701082

10711083
// handleRoot - Handles the root path
10721084
func (ui *MonitoringUI) handleRoot(w http.ResponseWriter, r *http.Request) {
1073-
// Set CORS headers
1074-
setCORSHeaders(w)
1075-
10761085
// Handle preflight OPTIONS request
10771086
if r.Method == "OPTIONS" {
10781087
w.WriteHeader(http.StatusOK)
@@ -1127,9 +1136,6 @@ func (ui *MonitoringUI) handleMetrics(w http.ResponseWriter, r *http.Request) {
11271136

11281137
// handleWebSocket - Handles WebSocket connections
11291138
func (ui *MonitoringUI) handleWebSocket(w http.ResponseWriter, r *http.Request) {
1130-
// Set CORS headers for WebSocket
1131-
setCORSHeaders(w)
1132-
11331139
// Handle preflight OPTIONS request
11341140
if r.Method == "OPTIONS" {
11351141
w.WriteHeader(http.StatusOK)
@@ -1223,7 +1229,6 @@ func (ui *MonitoringUI) handleStatic(w http.ResponseWriter, r *http.Request) {
12231229

12241230
// handleStaticJS - Serves the JavaScript for the monitoring UI
12251231
func (ui *MonitoringUI) handleStaticJS(w http.ResponseWriter, r *http.Request) {
1226-
setCORSHeaders(w)
12271232
// JavaScript is static - cache for 1 hour
12281233
setStaticCacheHeaders(w, 3600)
12291234
w.Header().Set("Content-Type", "application/javascript")

0 commit comments

Comments
 (0)