@@ -186,11 +186,27 @@ private AwsCredentialsProvider resolveCredentialsProvider(AwsCredentialsInput cr
186186
187187 private static final int MAX_PRESIGNED_REDIRECTS = 5 ;
188188
189+ private boolean isAllowedPresignedHost (String host ) {
190+ if (host == null || host .isBlank ()) {
191+ return false ;
192+ }
193+ String normalized = host .toLowerCase (java .util .Locale .ROOT );
194+ return normalized .equals ("s3.amazonaws.com" )
195+ || normalized .endsWith (".s3.amazonaws.com" )
196+ || normalized .matches (".*\\ .s3\\ .[a-z0-9-]+\\ .amazonaws\\ .com" )
197+ || normalized .matches (".*\\ .s3-[a-z0-9-]+\\ .amazonaws\\ .com" )
198+ || normalized .equals ("s3.amazonaws.com.cn" )
199+ || normalized .endsWith (".s3.amazonaws.com.cn" )
200+ || normalized .matches (".*\\ .s3\\ .[a-z0-9-]+\\ .amazonaws\\ .com\\ .cn" )
201+ || normalized .matches (".*\\ .s3-[a-z0-9-]+\\ .amazonaws\\ .com\\ .cn" );
202+ }
203+
189204 /**
190205 * Validates and rebuilds a presigned fetch URL: https only, to a public
191- * address. Returns a URI reconstructed from checked components rather than
192- * the input, so no unvalidated part of the caller's string survives into
193- * the request (java/ssrf). The initial URL and every redirect hop pass here.
206+ * address, and restricted to known S3 endpoint host patterns. Returns a URI
207+ * reconstructed from checked components rather than the input, so no
208+ * unvalidated part of the caller's string survives into the request
209+ * (java/ssrf). The initial URL and every redirect hop pass here.
194210 */
195211 private URI assertFetchableUrl (URI uri ) {
196212 String scheme = uri .getScheme ();
@@ -202,6 +218,9 @@ private URI assertFetchableUrl(URI uri) {
202218 if (host == null || host .isBlank ()) {
203219 throw new IllegalArgumentException ("Presigned log URL has no host" );
204220 }
221+ if (!isAllowedPresignedHost (host )) {
222+ throw new IllegalArgumentException ("Presigned log URL host is not an allowed S3 endpoint" );
223+ }
205224 java .net .InetAddress blocked =
206225 OutboundHostGuard .findBlockedAddress (OutboundHostGuard .normalize (host ));
207226 if (blocked != null ) {
0 commit comments