import sys import urllib.request from urllib.parse import urlparse # ANSI color codes GREEN = '\033[92m' RED = '\033[91m' ENDC = '\033[0m' explanation = ''' In this application, we have blocked certain URL schemes and hostnames by checking urlparse(input_link).scheme and urlparse(input_link).hostname with the following list: block_schemes = ["file", "gopher", "expect", "php", "dict", "ftp", "glob", "data"] block_host = ["instagram.com", "youtube.com", "tiktok.com"] Due to a flaw in how the urlparse splits the URL, you can bypass this blocklist by simply adding a leading space in the URL. Below are some URLs for you to try. Try them with and without leading spaces: https://youtube.com file://127.0.0.1/etc/passwd data://text/plain, expect://whoami Based on research by Yebo Cao - https://pointernull.com/security/python-url-parse-problem.html Your Python version is {}. ''' def is_vulnerable(): python_version = sys.version_info if python_version >= (3, 12): return False if (3, 11, 4) <= python_version < (3, 12): return False if (3, 10, 12) <= python_version < (3, 11): return False if (3, 9, 17) <= python_version < (3, 10): return False if (3, 8, 17) <= python_version < (3, 9): return False if (3, 7, 17) <= python_version < (3, 8): return False return True def safe_url_opener(input_link): block_schemes = ["file", "gopher", "expect", "php", "dict", "ftp", "glob", "data"] block_host = ["instagram.com", "youtube.com", "tiktok.com"] input_scheme = urlparse(input_link).scheme print("Input scheme is", input_scheme) input_hostname = urlparse(input_link).hostname print("Input hostname is", input_hostname) if input_scheme in block_schemes: print(GREEN+"Input scheme is forbidden"+ENDC) return if input_hostname in block_host: print(GREEN+"Input hostname is forbidden"+ENDC) return try: target = urllib.request.urlopen(input_link) content = target.read() print(content) except Exception as e: print("Error:", e) def main(): python_version = sys.version vuln_status = RED+"vulnerable"+ENDC if is_vulnerable() else GREEN+"not vulnerable"+ENDC print(explanation.format(vuln_status)) num_links = 4 # Number of times to repeat for _ in range(num_links): input_link = input("Enter the link: ") safe_url_opener(input_link) if __name__ == "__main__": main()