@@ -18,19 +18,8 @@ public UrlValidateUtil(OpenAIConfig config) {
1818 }
1919
2020
21- public void validateFinalUrl (String finalUrl ) {
22- if (finalUrl == null || finalUrl .isEmpty ()) {
23- throw new ServiceException ("400" , "baseUrl cannot be null or empty" );
24- }
25-
26- URI uri ;
27- try {
28- uri = new URI (finalUrl );
29- } catch (URISyntaxException e ) {
30- throw new ServiceException ("400" , "Invalid baseUrl format" );
31- }
21+ public void validateHost (String host ) {
3222
33- String host = uri .getHost ();
3423 if (host == null || host .isEmpty ()) {
3524 throw new ServiceException ("400" , "Invalid baseUrl: missing host" );
3625 }
@@ -44,7 +33,6 @@ public void validateFinalUrl(String finalUrl) {
4433 throw new ServiceException ("500" , "No AI allowed hosts configured" );
4534 }
4635
47- enforceHttpsAndIpCheck (uri , host );
4836 return ;
4937 }
5038
@@ -59,94 +47,9 @@ public void validateFinalUrl(String finalUrl) {
5947 throw new ServiceException ("400" , "Loopback addresses are not allowed for custom baseUrl" );
6048 }
6149
62- enforceHttpsAndIpCheck (uri , host );
63- }
64-
65- void enforceHttpsAndIpCheck (URI uri , String host ) {
66- String scheme = uri .getScheme ();
67- if (scheme == null || !"https" .equalsIgnoreCase (scheme )) {
68- throw new ServiceException ("400" , "Only HTTPS protocol is allowed for custom baseUrl" );
69- }
70-
71- try {
72- InetAddress [] addresses = resolveHostAddresses (host );
73- boolean hasBlockedAddress = Arrays .stream (addresses ).anyMatch (this ::isBlockedAddress );
74- if (hasBlockedAddress ) {
75- throw new ServiceException ("400" , "Internal network addresses are not allowed" );
76- }
77- } catch (UnknownHostException e ) {
78- throw new ServiceException ("400" , "Unable to resolve host: " + host );
79- }
80- }
81-
82- InetAddress [] resolveHostAddresses (String host ) throws UnknownHostException {
83- return InetAddress .getAllByName (host );
84- }
85-
86- boolean isBlockedAddress (InetAddress address ) {
87- if (address .isLoopbackAddress ()
88- || address .isSiteLocalAddress ()
89- || address .isLinkLocalAddress ()
90- || address .isAnyLocalAddress ()
91- || address .isMulticastAddress ()) {
92- return true ;
93- }
94-
95- if (address instanceof Inet4Address ) {
96- return isBlockedIpv4 ((Inet4Address ) address );
97- }
98- if (address instanceof Inet6Address ) {
99- return isBlockedIpv6 ((Inet6Address ) address );
100- }
101- return false ;
10250 }
10351
104- private boolean isBlockedIpv4 (Inet4Address address ) {
105- byte [] octets = address .getAddress ();
106- int first = octets [0 ] & 0xFF ;
107- int second = octets [1 ] & 0xFF ;
108- int third = octets [2 ] & 0xFF ;
10952
110- if (first == 0 ) {
111- return true ;
112- }
113- if (first == 100 && second >= 64 && second <= 127 ) {
114- return true ;
115- }
116- if (first == 192 && second == 0 && third == 0 ) {
117- return true ;
118- }
119- if (first == 192 && second == 0 && third == 2 ) {
120- return true ;
121- }
122- if (first == 198 && (second == 18 || second == 19 )) {
123- return true ;
124- }
125- if (first == 198 && second == 51 && third == 100 ) {
126- return true ;
127- }
128- if (first == 203 && second == 0 && third == 113 ) {
129- return true ;
130- }
131- return first >= 240 ;
132- }
13353
134- private boolean isBlockedIpv6 (Inet6Address address ) {
135- byte [] octets = address .getAddress ();
136- int first = octets [0 ] & 0xFF ;
137- int second = octets [1 ] & 0xFF ;
138-
139- if ((first & 0xFE ) == 0xFC ) {
140- return true ;
141- }
142- if (first == 0x20 && second == 0x01 ) {
143- int third = octets [2 ] & 0xFF ;
144- int fourth = octets [3 ] & 0xFF ;
145- if (third == 0x0D && fourth == 0xB8 ) {
146- return true ;
147- }
148- }
149- return first == 0xFF ;
150- }
15154
15255}
0 commit comments