Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
860a7689c5 Add URL scheme validation to prevent command injection via Process.Start
- HelpMenu.cs: Add https/http scheme validation to OpenUrl() to prevent
  custom URI scheme exploitation
- UpdateWindow.cs: Add scheme validation alongside existing IsFile/IsUnc/IsLoopback
  checks to only allow http/https URLs
- ProgramRoot.cs: Add https:// prefix validation for network-fetched downloadUrl
  before passing to Process.Start with UseShellExecute=true

Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com>
2026-02-25 17:36:46 +00:00
copilot-swe-agent[bot]
b65686823c Initial plan 2026-02-25 17:29:05 +00:00
4 changed files with 17 additions and 27 deletions

View File

@@ -64,7 +64,9 @@ namespace mRemoteNG.App
{
try
{
Process.Start(new ProcessStartInfo(fileName: downloadUrl) { UseShellExecute = true });
if (!string.IsNullOrEmpty(downloadUrl) &&
downloadUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
Process.Start(new ProcessStartInfo(fileName: downloadUrl) { UseShellExecute = true });
}
catch (Exception ex)
{

View File

@@ -7,7 +7,6 @@ using mRemoteNG.Messages;
using MSTSCLib;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
using Microsoft.Win32;
namespace mRemoteNG.Connection.Protocol.RDP
{
@@ -39,10 +38,6 @@ namespace mRemoteNG.Connection.Protocol.RDP
_resizeDebounceTimer = new System.Timers.Timer(300);
_resizeDebounceTimer.AutoReset = false;
_resizeDebounceTimer.Elapsed += ResizeDebounceTimer_Elapsed;
// Subscribe to display settings changes so the inner RDP session is resized
// when the outer RDP session (jump-host) reconnects with a different viewport.
SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged;
}
public override bool Initialize()
@@ -158,24 +153,8 @@ namespace mRemoteNG.Connection.Protocol.RDP
Runtime.MessageCollector?.AddMessage(MessageClass.DebugMsg,
$"Debounce timer fired - executing delayed resize to {_pendingResizeSize.Width}x{_pendingResizeSize.Height}");
// Marshal to the UI thread because DoResizeClient() accesses WinForms and COM objects
if (InterfaceControl.InvokeRequired)
{
InterfaceControl.BeginInvoke(new Action(DoResizeClient));
}
else
{
DoResizeClient();
}
}
private void OnDisplaySettingsChanged(object sender, EventArgs e)
{
// When display settings change (e.g., outer RDP session reconnects with a different
// resolution/viewport), schedule a debounced resize so the inner RDP session is
// updated to match the new panel dimensions once the display has settled.
if (!loginComplete) return;
ScheduleDebouncedResize();
// Execute the actual RDP session resize
DoResizeClient();
}
protected override AxHost CreateActiveXRdpClientControl()
@@ -299,9 +278,6 @@ namespace mRemoteNG.Connection.Protocol.RDP
public override void Close()
{
// Unsubscribe from display settings changes to prevent memory leaks
SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
// Clean up debounce timer
if (_resizeDebounceTimer != null)
{

View File

@@ -204,6 +204,11 @@ namespace mRemoteNG.UI.Menu
private static void OpenUrl(string url)
{
if (string.IsNullOrWhiteSpace(url) ||
(!url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) &&
!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase)))
return;
var startInfo = new ProcessStartInfo
{
FileName = url,

View File

@@ -99,6 +99,13 @@ namespace mRemoteNG.UI.Window
return;
}
// Only allow http/https URLs to prevent exploitation via custom URI schemes
if (!linkUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) &&
!linkUri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
{
return;
}
var startInfo = new ProcessStartInfo
{
FileName = linkUri.ToString(),