From 30b1f4b2f9cff6735e0bb1e22b32a08a5c5bfd1a Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 27 May 2024 09:51:34 +0200 Subject: [PATCH] Raise RequestParameterInvalidException if url can't be verified Kind of a followup to https://github.com/galaxyproject/galaxy/pull/18155. Fixes: ``` ValueError invalid literal for int() with base 10: 'sequences' ``` For the attempted url `"http://emp-single-end-sequences:sequences"`. --- lib/galaxy/files/uris.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/galaxy/files/uris.py b/lib/galaxy/files/uris.py index 42b502d77fdc..d35e51d696c4 100644 --- a/lib/galaxy/files/uris.py +++ b/lib/galaxy/files/uris.py @@ -6,6 +6,7 @@ from typing import ( List, Optional, + Tuple, ) from urllib.parse import urlparse @@ -78,6 +79,18 @@ def validate_uri_access(uri: str, is_admin: bool, ip_allowlist: List[IpAllowedLi raise AdminRequiredException() +def split_port(parsed_url: str, url: str) -> Tuple[str, int]: + try: + idx = parsed_url.rindex(":") + # We parse as an int and let this fail ungracefully if parsing + # fails because we desire to fail closed rather than open. + port = int(parsed_url[idx + 1 :]) + parsed_url = parsed_url[:idx] + return (parsed_url, port) + except Exception: + raise RequestParameterInvalidException(f"Could not verify url '{url}'.") + + def validate_non_local(uri: str, ip_allowlist: List[IpAllowedListEntryT]) -> str: # If it doesn't look like a URL, ignore it. if not (uri.lstrip().startswith("http://") or uri.lstrip().startswith("https://")): @@ -106,22 +119,14 @@ def validate_non_local(uri: str, ip_allowlist: List[IpAllowedListEntryT]) -> str # However if it ends with a ']' then there is no port after it and # they've wrapped it in brackets just for fun. if "]" in parsed_url and not parsed_url.endswith("]"): - # If this +1 throws a range error, we don't care, their url - # shouldn't end with a colon. - idx = parsed_url.rindex(":") - # We parse as an int and let this fail ungracefully if parsing - # fails because we desire to fail closed rather than open. - port = int(parsed_url[idx + 1 :]) - parsed_url = parsed_url[:idx] + parsed_url, port = split_port(parsed_url=parsed_url, url=url) else: # Plain ipv6 without port pass else: # This should finally be ipv4 with port. It cannot be IPv6 as that # was caught by earlier cases, and it cannot be due to credentials. - idx = parsed_url.rindex(":") - port = int(parsed_url[idx + 1 :]) - parsed_url = parsed_url[:idx] + parsed_url, port = split_port(parsed_url=parsed_url, url=url) # safe to log out, no credentials/request path, just an IP + port log.debug("parsed url %s, port: %s", parsed_url, port)