T09 · Insecure Skill Coding Practices
- Location
scripts/site_card.py:42- Finding
DNS Rebinding Can Bypass the Public-IP SSRF Restriction
- Content
View full analysis
bool: try: infos = socket.getaddrinfo(host, 443, type=socket.SOCK_STREAM) except OSError: return False for info in infos: try: ip = ipaddress.ip_address(info[4][0]) except ValueError: return False if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved or ip.is_multicast: return False return True def allowed_url(url: str) -> bool: if not https_only(url): return False host = (urlparse(url).hostname or "").lower() if host in {"localhost"}: return False return _public_host(host) class _AllowRedirect(urllib.request.HTTPRedirectHandler): def redirect_request(self, req, fp, code, msg, headers, newurl): if not allowed_url(newurl): raise urllib.error.HTTPError(newurl, code, "redirect blocked", headers, fp) return urllib.request.HTTPRedirectHandler.redirect_request( self, req, fp, code, msg, headers, newurl ) def get(url: str, timeout: int = 16) -> dict[str, Any]: if not allowed_url(url): return {"ok": False, "url": url, "error": "blocked_host", "status": None, "headers": {}, "body": b""} req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "*/*"}) opener = urllib.request.build_opener(_AllowRedirect) try: with opener.open(req, timeout=timeout) as r: raw = r.read(MAX_BODY) headers = {k.lower(): v for k, v in r.headers.items()} return { "ok": True, "url": r.geturl() or url, "status": getattr(r, "status", 200), "headers": headers, "body": ...[truncated 2480 chars]- Remediation
View remediation
