diff --git a/transport/internet/browser_dialer/dialer.go b/transport/internet/browser_dialer/dialer.go index 1784855f..960c9470 100644 --- a/transport/internet/browser_dialer/dialer.go +++ b/transport/internet/browser_dialer/dialer.go @@ -35,6 +35,7 @@ var dialerServers map[string]*dialerServer var mu sync.RWMutex const browserDialerSubprotocol = "browser-dialer" +const uuidPathLength = 37 var upgrader = &websocket.Upgrader{ ReadBufferSize: 0, @@ -96,6 +97,9 @@ func parseBrowserDialerAddress(addr string) (*browserDialerAddress, bool) { if cleanPath == "." || cleanPath == "/" || cleanPath != path { return nil, false } + if !isUUIDPath(cleanPath) { + return nil, false + } return &browserDialerAddress{ listenAddr: listenAddr, @@ -103,6 +107,30 @@ func parseBrowserDialerAddress(addr string) (*browserDialerAddress, bool) { }, true } +func isUUIDPath(path string) bool { + if len(path) != uuidPathLength || path[0] != '/' || strings.Count(path, "/") != 1 { + return false + } + + u := path[1:] + for i := 0; i < len(u); i++ { + c := u[i] + switch i { + case 8, 13, 18, 23: + if c != '-' { + return false + } + default: + isHex := (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') + if !isHex { + return false + } + } + } + + return true +} + func newDialerInstance(path string) *dialerInstance { page := bytes.ReplaceAll(webpage, []byte("dialerPath"), []byte(strings.TrimPrefix(path, "/"))) dialer := &dialerInstance{ diff --git a/transport/internet/browser_dialer/dialer_test.go b/transport/internet/browser_dialer/dialer_test.go new file mode 100644 index 00000000..506ee2a2 --- /dev/null +++ b/transport/internet/browser_dialer/dialer_test.go @@ -0,0 +1,22 @@ +package browser_dialer + +import "testing" + +func TestParseBrowserDialerAddressRequireUUIDPath(t *testing.T) { + valid := "127.0.0.1:8080/123e4567-e89b-12d3-a456-426614174000" + if _, ok := parseBrowserDialerAddress(valid); !ok { + t.Fatalf("expected valid browser dialer address: %s", valid) + } + + invalid := []string{ + "127.0.0.1:8080/example", + "127.0.0.1:8080/short", + "127.0.0.1:8080/123e4567e89b12d3a456426614174000", + "127.0.0.1:8080/123e4567-e89b-12d3-a456-426614174000/extra", + } + for _, addr := range invalid { + if _, ok := parseBrowserDialerAddress(addr); ok { + t.Fatalf("expected invalid browser dialer address: %s", addr) + } + } +}