校验 URL 合法性,防 SSRF
(url: str, allowed_schemes=('https',), allowed_domains=None)
| 46 | |
| 47 | |
| 48 | def validate_url(url: str, allowed_schemes=('https',), allowed_domains=None) -> bool: |
| 49 | """校验 URL 合法性,防 SSRF""" |
| 50 | from urllib.parse import urlparse |
| 51 | try: |
| 52 | parsed = urlparse(url) |
| 53 | if parsed.scheme not in allowed_schemes: |
| 54 | return False |
| 55 | if allowed_domains and parsed.hostname not in allowed_domains: |
| 56 | return False |
| 57 | if not parsed.hostname: |
| 58 | return False |
| 59 | # 禁止内网地址 |
| 60 | import ipaddress |
| 61 | try: |
| 62 | ip = ipaddress.ip_address(parsed.hostname) |
| 63 | if ip.is_private or ip.is_loopback or ip.is_reserved: |
| 64 | return False |
| 65 | except ValueError: |
| 66 | pass # hostname 不是 IP,放行 |
| 67 | return True |
| 68 | except Exception: |
| 69 | return False |
no outgoing calls
no test coverage detected