{"record":{"id":"0e385601b601dafb","repo":"lfnovo/open-notebook","slug":"link-local-addresses-169-254-x-x-are-not-allowed","errorCode":null,"errorMessage":"Link-local addresses (169.254.x.x) are not allowed for security reasons. These addresses are used for cloud metadata endpoints.","messagePattern":"Link-local addresses \\(169\\.254\\.x\\.x\\) are not allowed for security reasons\\. These addresses are used for cloud metadata endpoints\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"open_notebook/utils/url_validation.py","lineNumber":231,"sourceCode":"    hostname: str,\n    resolved: bool = False,\n) -> None:\n    \"\"\"Raise ValueError if `ip` is a link-local or cloud-metadata address.\"\"\"\n    is_ipv4_mapped_link_local = (\n        hasattr(ip, \"ipv4_mapped\") and ip.ipv4_mapped and ip.ipv4_mapped.is_link_local\n    )\n\n    # Block link-local addresses (169.254.x.x / fe80::/10) - used for cloud\n    # metadata - including IPv4-mapped IPv6 addresses pointing to link-local\n    # (e.g. ::ffff:169.254.169.254 bypasses IPv6 is_link_local check).\n    if ip.is_link_local or is_ipv4_mapped_link_local:\n        if resolved:\n            raise ValueError(\n                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(","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/open_notebook/utils/url_validation.py#L213-L249","documentation":"The URL contained a literal link-local IP (169.254.x.x, fe80::/10, or an IPv4-mapped form like ::ffff:169.254.169.254) rather than a hostname. Because these addresses serve cloud metadata endpoints, they are unconditionally rejected regardless of how they were written. The 'resolved' variant of the message is used when the value came from DNS; this one fires for direct literals.","triggerScenarios":"Passing 'http://169.254.169.254/latest/meta-data/' or 'http://[fe80::1]/' directly as a base_url to validate_url or prepare_pinned_http_target (and thus to any discover/connection-test call).","commonSituations":"SSRF probing of instance metadata; debugging scripts that copied the metadata endpoint; test suites deliberately probing the guardrail.","solutions":["Use the real service endpoint instead of the link-local metadata address","If writing tests, assert that ValueError is raised — don't try to make the call succeed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import ipaddress\nfrom urllib.parse import urlparse\n\ndef is_literal_link_local(url: str) -> bool:\n    host = urlparse(url).hostname or \"\"\n    try:\n        ip = ipaddress.ip_address(host)\n    except ValueError:\n        return False\n    return ip.is_link_local or (ip.version == 6 and int(ip) == int(ipaddress.IPv6Address(\"::ffff:169.254.169.254\")))","typeGuard":null,"tryCatchPattern":"try:\n    validate_url(url)\nexcept ValueError as e:\n    if \"Link-local\" in str(e):\n        return {\"allowed\": False, \"reason\": \"cloud-metadata-blocked\"}\n    raise","preventionTips":["Block literal link-local IPs at the form layer for faster feedback","In tests, assert the block rather than trying to bypass it"],"tags":["ssrf","security","cloud-metadata","link-local"],"backgroundTag":"ssrf-metadata-endpoint-blocked","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}