From 0f2bdffba0c80a8d81629e828fc9c28d5817cc05 Mon Sep 17 00:00:00 2001 From: WofWca Date: Fri, 30 Aug 2024 16:36:32 +0400 Subject: [PATCH] hardening(proxy): only accept `ws` & `wss` relays --- proxy/lib/proxy-go_test.go | 11 +++++------ proxy/lib/snowflake.go | 5 +++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/proxy/lib/proxy-go_test.go b/proxy/lib/proxy-go_test.go index 91ed3e1..7e2f4e1 100644 --- a/proxy/lib/proxy-go_test.go +++ b/proxy/lib/proxy-go_test.go @@ -537,9 +537,9 @@ func TestUtilityFuncs(t *testing.T) { {pattern: "$", allowNonTLS: false, targetURL: "wss://1.1.1.1/test?test=test#test", expects: nil}, // Weird / invalid / ambiguous URL - // {pattern: "$", allowNonTLS: true, targetURL: "snowflake.torproject.net", expects: fmt.Errorf("")}, - // {pattern: "$", allowNonTLS: true, targetURL: "//snowflake.torproject.net", expects: fmt.Errorf("")}, - // {pattern: "$", allowNonTLS: true, targetURL: "/path", expects: fmt.Errorf("")}, + {pattern: "$", allowNonTLS: true, targetURL: "snowflake.torproject.net", expects: fmt.Errorf("")}, + {pattern: "$", allowNonTLS: true, targetURL: "//snowflake.torproject.net", expects: fmt.Errorf("")}, + {pattern: "$", allowNonTLS: true, targetURL: "/path", expects: fmt.Errorf("")}, {pattern: "$", allowNonTLS: true, targetURL: "wss://snowflake.torproject .net", expects: fmt.Errorf("")}, {pattern: "$", allowNonTLS: true, targetURL: "wss://😀", expects: nil}, {pattern: "$", allowNonTLS: true, targetURL: "wss://пример.рф", expects: nil}, @@ -547,9 +547,8 @@ func TestUtilityFuncs(t *testing.T) { // Non-websocket protocols {pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "https://snowflake.torproject.net", expects: fmt.Errorf("")}, {pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "ftp://snowflake.torproject.net", expects: fmt.Errorf("")}, - // These are failing for now - // {pattern: "snowflake.torproject.net$", allowNonTLS: true, targetURL: "https://snowflake.torproject.net", expects: fmt.Errorf("")}, - // {pattern: "snowflake.torproject.net$", allowNonTLS: true, targetURL: "ftp://snowflake.torproject.net", expects: fmt.Errorf("")}, + {pattern: "snowflake.torproject.net$", allowNonTLS: true, targetURL: "https://snowflake.torproject.net", expects: fmt.Errorf("")}, + {pattern: "snowflake.torproject.net$", allowNonTLS: true, targetURL: "ftp://snowflake.torproject.net", expects: fmt.Errorf("")}, } for _, v := range testingVector { err := checkIsRelayURLAcceptable(v.pattern, v.allowNonTLS, v.targetURL) diff --git a/proxy/lib/snowflake.go b/proxy/lib/snowflake.go index 69ae9c2..e652eb6 100644 --- a/proxy/lib/snowflake.go +++ b/proxy/lib/snowflake.go @@ -651,6 +651,11 @@ func checkIsRelayURLAcceptable( if err != nil { return fmt.Errorf("bad Relay URL %w", err) } + // FYI our websocket library also rejects other protocols + // https://github.com/gorilla/websocket/blob/5e002381133d322c5f1305d171f3bdd07decf229/client.go#L174-L181 + if parsedRelayURL.Scheme != "wss" && parsedRelayURL.Scheme != "ws" { + return fmt.Errorf("rejected Relay URL protocol") + } matcher := namematcher.NewNameMatcher(allowedHostNamePattern) if !matcher.IsMember(parsedRelayURL.Hostname()) || (!allowNonTLSRelay && parsedRelayURL.Scheme != "wss") { return fmt.Errorf("rejected Relay URL")