{"id":"GHSA-5jh9-2h63-pw4q","summary":"CC-Tweaked has an SSRF Protection Bypass with NAT64","details":"### Summary\n\nCC-Tweaked's HTTP API (`http.request`, `http.websocket`) blocks requests to private network ranges to prevent server-side request forgery (SSRF). This protection can be bypassed on IPv6-capable servers using NAT64 well-known prefix addresses (`64:ff9b::/96`). An attacker who can execute Lua code can reach any internal IPv4 service that the filter is intended to block, by addressing it as `http://[64:ff9b::\u003cipv4-as-hex\u003e]/` instead of its direct IPv4 address. This affects any CC-Tweaked deployment on a network with NAT64 routing — a configuration that is standard on AWS, GCP, and other cloud platforms when using IPv6-only subnets.\n\n### Details\n\nThe IP filter in [`PrivatePattern.matches()` (AddressPredicate.java#L121–L130)](https://github.com/cc-tweaked/CC-Tweaked/blob/663ffed4337da0dc3d82ace1e813e3c78b4a8c99/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressPredicate.java#L121-L130) blocks private network ranges by calling Java's standard `InetAddress` classification methods:\n\n```java\npublic boolean matches(InetAddress socketAddress) {\n    return socketAddress.isAnyLocalAddress()\n        || socketAddress.isLoopbackAddress()\n        || socketAddress.isLinkLocalAddress()\n        || socketAddress.isSiteLocalAddress()\n        || socketAddress.isMulticastAddress()\n        || isUniqueLocalAddress(socketAddress)\n        || isCarrierGradeNatAddress(socketAddress)\n        || additionalAddresses.contains(socketAddress);\n}\n```\n\nWhen a NAT64 address such as `64:ff9b::c0a8:0101` (encoding `192.168.1.1`) is resolved via `new InetSocketAddress(\"64:ff9b::c0a8:0101\", 80)`, Java returns an `Inet6Address`. Every method above returns `false` for this address — the `64:ff9b::/96` prefix is not recognised by any of Java's built-in classification methods. The address passes the filter and CC-Tweaked opens a connection.\n\nOn a network with a `64:ff9b::/96 → NAT Gateway` route, that connection is translated at the network level: the embedded IPv4 address is extracted and the packet is forwarded to `192.168.1.1:80`. The internal service receives a normal IPv4 TCP connection.\n\nThe existing 6to4 (`2002::/16`) mitigation in [`AddressRule.java#L74–L75`](https://github.com/cc-tweaked/CC-Tweaked/blob/663ffed4337da0dc3d82ace1e813e3c78b4a8c99/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java#L74-L75) does not cover the NAT64 prefix. No other check catches `64:ff9b::/96`.\n\n### PoC\n\n**Preconditions** (all three required):\n1. The server running CC-Tweaked has an IPv6 address assigned\n2. The network has a NAT Gateway (or equivalent)\n3. The route table contains `64:ff9b::/96 → NAT Gateway` — the standard AWS/GCP configuration for IPv6-only subnets with outbound IPv4 access ([AWS documentation](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-nat64-dns64.html))\n\n**Lua payload** (targets an internal service at `10.0.1.17:8888`):\n```lua\n-- 10.0.1.17 = 0x0a000111, expressed as NAT64: 64:ff9b::0a00:0111\nlocal res = http.request(\"http://[64:ff9b::0a00:0111]:8888/\")\nif res then print(res.readAll()) end\n```\n\n**Conversion formula** — for any blocked IPv4 `a.b.c.d`, the bypass address is:\n```\n64:ff9b::\u003chex(a)\u003e\u003chex(b)\u003e:\u003chex(c)\u003e\u003chex(d)\u003e\n```\n\n### Impact\n\nThis is a server-side request forgery (SSRF) vulnerability. Any user able to execute Lua code on a CC-Tweaked computer — including players on a public server — can use it to send HTTP requests to internal IPv4 services that the HTTP filter is designed to block. On cloud-hosted servers (AWS, GCP, Azure) using IPv6-only subnets with NAT64, which is an [increasingly common configuration following AWS's February 2024 public IPv4 pricing change](https://aws.amazon.com/blogs/aws/new-aws-public-ipv4-address-charge-public-ip-insights/), this includes other instances in the VPC, internal databases, and cloud management APIs.\n\n**Suggested fix:** add a check for the NAT64 well-known prefix in [`PrivatePattern.matches()`](https://github.com/cc-tweaked/CC-Tweaked/blob/663ffed4337da0dc3d82ace1e813e3c78b4a8c99/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressPredicate.java#L121-L130):\n\n```java\n|| isNAT64Address(socketAddress)\n\nprivate boolean isNAT64Address(InetAddress address) {\n    if (!(address instanceof Inet6Address)) return false;\n    byte[] b = address.getAddress();\n    // 64:ff9b::/96 — NAT64 well-known prefix (RFC 6052)\n    return b[0] == 0x00 && b[1] == 0x64 &&\n           b[2] == (byte) 0xff && b[3] == (byte) 0x9b &&\n           b[4] == 0 && b[5] == 0 && b[6] == 0 && b[7] == 0 &&\n           b[8] == 0 && b[9] == 0 && b[10] == 0 && b[11] == 0;\n}\n```\n\nThis vulnerability does not seem to work on servers running on modern versions of MacOS.","aliases":["CVE-2026-47695"],"modified":"2026-05-29T20:41:36.997815Z","published":"2026-05-29T20:21:12Z","database_specific":{"nvd_published_at":null,"cwe_ids":["CWE-918"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-05-29T20:21:12Z"},"references":[{"type":"WEB","url":"https://github.com/cc-tweaked/CC-Tweaked/security/advisories/GHSA-5jh9-2h63-pw4q"},{"type":"PACKAGE","url":"https://github.com/cc-tweaked/CC-Tweaked"}],"affected":[{"package":{"name":"cc.tweaked:cc-tweaked-1.21-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.21-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.20.1-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.20.1-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.20.4-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.20.4-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.20.5-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.20.5-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.20.6-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.20.6-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.19.3-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.19.3-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.19.4-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.19.4-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}},{"package":{"name":"cc.tweaked:cc-tweaked-1.20-core","ecosystem":"Maven","purl":"pkg:maven/cc.tweaked/cc-tweaked-1.20-core"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.119.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-5jh9-2h63-pw4q/GHSA-5jh9-2h63-pw4q.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H"}]}