@@ -319,21 +319,25 @@ def _fetch_single_catalog(
319319 except (json .JSONDecodeError , OSError ):
320320 pass
321321
322- # Fetch from URL — validate scheme before opening
322+ # Fetch from URL — validate scheme before opening and after redirects
323323 from urllib .parse import urlparse
324324 from urllib .request import urlopen
325325
326- parsed = urlparse (entry .url )
327- is_localhost = parsed .hostname in ("localhost" , "127.0.0.1" , "::1" )
328- if parsed .scheme != "https" and not (
329- parsed .scheme == "http" and is_localhost
330- ):
331- raise WorkflowCatalogError (
332- f"Refusing to fetch catalog from non-HTTPS URL: { entry .url } "
333- )
326+ def _validate_catalog_url (url : str ) -> None :
327+ parsed = urlparse (url )
328+ is_localhost = parsed .hostname in ("localhost" , "127.0.0.1" , "::1" )
329+ if parsed .scheme != "https" and not (
330+ parsed .scheme == "http" and is_localhost
331+ ):
332+ raise WorkflowCatalogError (
333+ f"Refusing to fetch catalog from non-HTTPS URL: { url } "
334+ )
335+
336+ _validate_catalog_url (entry .url )
334337
335338 try :
336339 with urlopen (entry .url , timeout = 30 ) as resp : # noqa: S310
340+ _validate_catalog_url (resp .geturl ())
337341 data = json .loads (resp .read ().decode ("utf-8" ))
338342 except Exception as exc :
339343 # Fall back to cache if available
0 commit comments