Skip to content

Commit 4aa13d7

Browse files
committed
Improve local address detection in McpDistributionSettings with comprehensive IP range checks
Replace simple string-based localhost/127.0.0.1 checks with robust IsLocalAddress method that validates loopback addresses, private IPv4 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16), IPv6 link-local and loopback addresses, and .local hostnames using proper URI parsing and IPAddress validation.
1 parent 83dd9c0 commit 4aa13d7

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

MCPForUnity/Editor/Config/McpDistributionSettings.cs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Net;
3+
using System.Net.Sockets;
24
using UnityEngine;
35

46
namespace MCPForUnity.Editor.Config
@@ -14,8 +16,7 @@ public class McpDistributionSettings : ScriptableObject
1416

1517
internal bool IsRemoteDefault =>
1618
!string.IsNullOrWhiteSpace(defaultHttpBaseUrl)
17-
&& !defaultHttpBaseUrl.Contains("localhost", StringComparison.OrdinalIgnoreCase)
18-
&& !defaultHttpBaseUrl.Contains("127.0.0.1", StringComparison.OrdinalIgnoreCase);
19+
&& !IsLocalAddress(defaultHttpBaseUrl);
1920
}
2021

2122
internal static class McpDistribution
@@ -44,5 +45,61 @@ internal static McpDistributionSettings Settings
4445
return _cached;
4546
}
4647
}
48+
49+
private static bool IsLocalAddress(string url)
50+
{
51+
if (string.IsNullOrWhiteSpace(url))
52+
{
53+
return true;
54+
}
55+
56+
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
57+
{
58+
return false;
59+
}
60+
61+
string host = uri.Host;
62+
63+
if (string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase))
64+
{
65+
return true;
66+
}
67+
68+
if (IPAddress.TryParse(host, out var ip))
69+
{
70+
if (IPAddress.IsLoopback(ip))
71+
{
72+
return true;
73+
}
74+
75+
if (ip.AddressFamily == AddressFamily.InterNetwork)
76+
{
77+
var bytes = ip.GetAddressBytes();
78+
// 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16
79+
if (bytes[0] == 10) return true;
80+
if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) return true;
81+
if (bytes[0] == 192 && bytes[1] == 168) return true;
82+
if (bytes[0] == 169 && bytes[1] == 254) return true;
83+
}
84+
else if (ip.AddressFamily == AddressFamily.InterNetworkV6)
85+
{
86+
// ::1 loopback or fe80::/10 link-local
87+
if (ip.IsIPv6LinkLocal || ip.Equals(IPAddress.IPv6Loopback))
88+
{
89+
return true;
90+
}
91+
}
92+
93+
return false;
94+
}
95+
96+
// Hostname: treat *.local as local network; otherwise assume remote.
97+
if (host.EndsWith(".local", StringComparison.OrdinalIgnoreCase))
98+
{
99+
return true;
100+
}
101+
102+
return false;
103+
}
47104
}
48105
}

0 commit comments

Comments
 (0)