{"record":{"id":"9503240f268f4f77","repo":"lfnovo/open-notebook","slug":"hostname-hostname-resolves-to-the-aws-imdsv6-m","errorCode":null,"errorMessage":"Hostname '{hostname}' resolves to the AWS IMDSv6 metadata address (fd00:ec2::254), which is not allowed for security reasons.","messagePattern":"Hostname '(.+?)' resolves to the AWS IMDSv6 metadata address \\(fd00:ec2::254\\), which is not allowed for security reasons\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"open_notebook/utils/url_validation.py","lineNumber":245,"sourceCode":"                f\"Hostname '{hostname}' resolves to a link-local address (169.254.x.x) \"\n                \"which is not allowed for security reasons. These addresses are used \"\n                \"for cloud metadata endpoints.\"\n            )\n        raise ValueError(\n            \"Link-local addresses (169.254.x.x) are not allowed for security reasons. \"\n            \"These addresses are used for cloud metadata endpoints.\"\n        )\n\n    # Block AWS's IMDSv6 metadata address - a Unique Local Address, not\n    # link-local, so it needs its own explicit check. Compare without scope\n    # ID so scoped forms (fd00:ec2::254%eth0) cannot bypass the sentinel.\n    is_aws_imds_v6 = (\n        isinstance(ip, ipaddress.IPv6Address)\n        and int(ip) == int(_AWS_IMDS_V6_ADDRESS)\n    )\n    if is_aws_imds_v6:\n        if resolved:\n            raise ValueError(\n                f\"Hostname '{hostname}' resolves to the AWS IMDSv6 metadata address \"\n                \"(fd00:ec2::254), which is not allowed for security reasons.\"\n            )\n        raise ValueError(\n            \"The AWS IMDSv6 metadata address (fd00:ec2::254) is not allowed for \"\n            \"security reasons.\"\n        )\n","sourceCodeStart":227,"sourceCodeEnd":253,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/open_notebook/utils/url_validation.py#L227-L253","documentation":"A hostname in the config resolved to fd00:ec2::254, AWS's IPv6 IMDS endpoint. This is a Unique Local Address (not link-local), so it needs an explicit check; discovering it via DNS triggers this hostname-specific message. It exists to close the SSRF path where an attacker routes a friendly name to the IPv6 metadata service.","triggerScenarios":"Provider base_url set to a hostname whose AAAA record is fd00:ec2::254, then running discover_with_config or any connection-test helper that pins the outbound target.","commonSituations":"DNS rebinding / SSRF test payloads pointing at AWS IMDSv6; attacker-controlled endpoint in a multi-tenant setup; accidental wildcard DNS record.","solutions":["Remove the offending hostname from the config; requests to the AWS IPv6 metadata endpoint are blocked by design","Audit how that DNS record got created if it wasn't intentional","For legitimate AWS API access use the public service hostnames"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import ipaddress, socket\nfrom urllib.parse import urlparse\n\nAWS_IMDS_V6 = ipaddress.IPv6Address(\"fd00:ec2::254\")\n\ndef resolves_to_imds_v6(url: str) -> bool:\n    host = urlparse(url).hostname or \"\"\n    try:\n        if ipaddress.ip_address(host) == AWS_IMDS_V6:\n            return True\n    except ValueError:\n        pass\n    try:\n        return any(ipaddress.ip_address(ai[4][0]) == AWS_IMDS_V6 for ai in socket.getaddrinfo(host, None))\n    except socket.gaierror:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    target = await prepare_pinned_http_target(url, provider)\nexcept ValueError as e:\n    if \"IMDSv6\" in str(e):\n        log_security_event(url)\n    raise","preventionTips":["Only use public AWS service hostnames in configs","Audit DNS records for wildcard names pointing at fd00:ec2::254"],"tags":["ssrf","security","aws-imds","ipv6"],"backgroundTag":"ssrf-metadata-endpoint-blocked","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}