From 355bb5c93dcdf85b5aca69a4c11517f4eb4a276a Mon Sep 17 00:00:00 2001 From: Greninja44 Date: Tue, 18 Aug 2026 15:35:13 +0000 Subject: [PATCH 1/2] DroneCAN: fix GetParameters() enumeration skipping parameters Fix two bugs in DroneCAN.GetParameters() that caused parameter enumeration to stop before retrieving all parameters: 1. SemaphoreSlim(1) allowed the while loop to send duplicate GetSet requests before receiving responses. When both duplicate responses arrived, the index was incremented twice, skipping intermediate parameter indices. Changed to SemaphoreSlim(0) so the loop blocks until each response arrives. 2. Message filter used a single AND condition that failed to filter out service messages from wrong nodes. A stray GetSet_res with name_len==0 from another node could trigger premature end-of-enumeration. Fixed to use two separate conditions matching the proven pattern in SetParameter(). --- ExtLibs/DroneCAN/DroneCAN.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ExtLibs/DroneCAN/DroneCAN.cs b/ExtLibs/DroneCAN/DroneCAN.cs index 0c4fea4842..93bdee70a5 100644 --- a/ExtLibs/DroneCAN/DroneCAN.cs +++ b/ExtLibs/DroneCAN/DroneCAN.cs @@ -537,11 +537,13 @@ public bool ExecuteOpCode(byte node, byte dronecan_PROTOCOL_PARAM_EXECUTEOPCODE) ushort index = 0; var timeout = DateTime.Now.AddSeconds(2); - SemaphoreSlim wait = new SemaphoreSlim(1); + SemaphoreSlim wait = new SemaphoreSlim(0); MessageRecievedDel paramdelegate = (frame, msg, transferID) => { - if (frame.IsServiceMsg && frame.SvcDestinationNode != SourceNode && frame.SourceNode == node) + if (frame.IsServiceMsg && frame.SvcDestinationNode != SourceNode) + return; + if (frame.SourceNode != node) return; if (msg.GetType() == typeof(DroneCAN.uavcan_protocol_param_GetSet_res)) From 29c47108ae392affd9adfa556b95cfc6def41c42 Mon Sep 17 00:00:00 2001 From: Greninja44 Date: Thu, 20 Aug 2026 12:47:23 +0000 Subject: [PATCH 2/2] httpserver: restrict /websocket/raw to localhost connections The /websocket/raw WebSocket endpoint accepts unauthenticated connections from any network interface, allowing remote hosts to inject arbitrary MAVLink commands into the active vehicle link. Add an IPAddress.IsLoopback() check on the TCP remote endpoint before completing the WebSocket handshake, consistent with the existing protections on /guided? and POST /guide. Fixes #3757 --- ExtLibs/Xamarin/Xamarin/Linked/httpserver.cs | 10 ++++++++++ Utilities/httpserver.cs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/ExtLibs/Xamarin/Xamarin/Linked/httpserver.cs b/ExtLibs/Xamarin/Xamarin/Linked/httpserver.cs index b0b0f192d9..0bfaaab69d 100644 --- a/ExtLibs/Xamarin/Xamarin/Linked/httpserver.cs +++ b/ExtLibs/Xamarin/Xamarin/Linked/httpserver.cs @@ -400,6 +400,16 @@ public void ProcessClient(object clientobj) ///////////////////////////////////////////////////////////////// else if (url.Contains(" /websocket/raw")) { + var remoteWsEp = client.Client.RemoteEndPoint as System.Net.IPEndPoint; + if (remoteWsEp == null || !IPAddress.IsLoopback(remoteWsEp.Address)) + { + string rejectHeader = "HTTP/1.1 403 Forbidden\r\n\r\nForbidden"; + byte[] rejectTemp = asciiEncoding.GetBytes(rejectHeader); + stream.Write(rejectTemp, 0, rejectTemp.Length); + stream.Close(); + return; + } + using (var writer = new StreamWriter(stream, Encoding.Default)) { writer.WriteLine("HTTP/1.1 101 WebSocket Protocol Handshake"); diff --git a/Utilities/httpserver.cs b/Utilities/httpserver.cs index 3a5db085f7..9c261a99cf 100644 --- a/Utilities/httpserver.cs +++ b/Utilities/httpserver.cs @@ -401,6 +401,16 @@ public void ProcessClient(object clientobj) ///////////////////////////////////////////////////////////////// else if (url.Contains(" /websocket/raw") || url.Contains(" / ") && head.Contains("Upgrade: websocket")) { + var remoteWsEp = client.Client.RemoteEndPoint as System.Net.IPEndPoint; + if (remoteWsEp == null || !IPAddress.IsLoopback(remoteWsEp.Address)) + { + string rejectHeader = "HTTP/1.1 403 Forbidden\r\n\r\nForbidden"; + byte[] rejectTemp = asciiEncoding.GetBytes(rejectHeader); + stream.Write(rejectTemp, 0, rejectTemp.Length); + stream.Close(); + return; + } + using (var writer = new StreamWriter(stream, Encoding.ASCII)) { writer.WriteLine("HTTP/1.1 101 WebSocket Protocol Handshake");