diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs index 143980dfa5..3a58ad8401 100644 --- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs +++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs @@ -23,6 +23,9 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport private SimpleWebSocket _pendingSocket; private bool _disposed; private object _lock = new object(); + private Uri _listenUri; + private Guid _secretCookie; + private bool _isFirstMessage = true; private AutoResetEvent _wakeup = new AutoResetEvent(false); private FrameMessage _lastFrameMessage = null; private FrameMessage _lastSentFrameMessage = null; @@ -42,6 +45,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport if (listenUri.Scheme != "http") throw new ArgumentException("URI scheme is not HTTP.", nameof(listenUri)); + _listenUri = listenUri; var resourcePrefix = "Avalonia.DesignerSupport.Remote.HtmlTransport.webapp.build."; _resources = typeof(HtmlWebSocketTransport).Assembly.GetManifestResourceNames() .Where(r => r.StartsWith(resourcePrefix, StringComparison.OrdinalIgnoreCase) @@ -57,10 +61,21 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport { var ms = new MemoryStream(); s.CopyTo(ms); - return ms.ToArray(); + var currentIndexBytes = ms.ToArray(); + if (r == resourcePrefix + "index.html.gz" && ms.CanWrite) + { + _secretCookie = Guid.NewGuid(); + var resultIndexString = Encoding.Default.GetString(currentIndexBytes) + .Replace("PREVIEWER_SECURITY_COOKIE", _secretCookie.ToString()); + var resultIndexBytes = Encoding.UTF8.GetBytes(resultIndexString); + + ms.Write(resultIndexBytes, 0, resultIndexBytes.Length); + return resultIndexBytes; + } + return currentIndexBytes; } }); - + _signalTransport = signalTransport; var address = IPAddress.Parse(listenUri.Host); @@ -98,12 +113,19 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport } else { - var socket = await req.AcceptWebSocket(); - SocketReceiveWorker(socket); - lock (_lock) + if (req.Headers.TryGetValue("Origin", out var origin) && origin == _listenUri.OriginalString) { - _pendingSocket?.Dispose(); - _pendingSocket = socket; + var socket = await req.AcceptWebSocket(); + SocketReceiveWorker(socket); + lock (_lock) + { + _pendingSocket?.Dispose(); + _pendingSocket = socket; + } + } + else + { + throw new Exception("Origin doesen't match Url"); } } } @@ -114,13 +136,19 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport { try { + if(_isFirstMessage && (await socket.ReceiveMessage().ConfigureAwait(false)).AsString() != _secretCookie.ToString()) + { + socket.Dispose(); + return; + } + _isFirstMessage = false; while (true) { var msg = await socket.ReceiveMessage().ConfigureAwait(false); if(msg != null && msg.IsText) { var message = ParseMessage(msg.AsString()); - if (message != null) + if (message != null) _onMessage?.Invoke(this, message); } } diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/PreviewerServerConnection.ts b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/PreviewerServerConnection.ts index 7f1ab84f99..d9ace9857f 100644 --- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/PreviewerServerConnection.ts +++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/PreviewerServerConnection.ts @@ -41,7 +41,7 @@ export class PreviewerServerConnection { const onMessage = this.onMessage; conn.onmessage = msg => onMessage(msg); - + conn.onopen = open => this.onOpen(open); const onClose = () => this.setFrame(null); conn.onclose = () => onClose(); conn.onerror = (err: Event) => { @@ -50,6 +50,10 @@ export class PreviewerServerConnection { } } + private onOpen(open: Event) { + this.conn.send(window["avaloniaPreviewerSecurityCookie"]); + } + private onMessage = (msg: MessageEvent) => { if (typeof msg.data == 'string' || msg.data instanceof String) { const parts = msg.data.split(':'); diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/index.html b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/index.html index 9b1be377ed..35c17185e8 100644 --- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/index.html +++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/index.html @@ -10,6 +10,9 @@