Skip to content

Commit daadf0b

Browse files
1 parent ee31bd2 commit daadf0b

1 file changed

Lines changed: 190 additions & 0 deletions

File tree

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-5jh9-2h63-pw4q",
4+
"modified": "2026-05-29T20:21:12Z",
5+
"published": "2026-05-29T20:21:12Z",
6+
"aliases": [
7+
"CVE-2026-47695"
8+
],
9+
"summary": "CC-Tweaked has an SSRF Protection Bypass with NAT64",
10+
"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::<ipv4-as-hex>]/` 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::<hex(a)><hex(b)>:<hex(c)><hex(d)>\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.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"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"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Maven",
21+
"name": "cc.tweaked:cc-tweaked-1.21-core"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "1.119.0"
32+
}
33+
]
34+
}
35+
]
36+
},
37+
{
38+
"package": {
39+
"ecosystem": "Maven",
40+
"name": "cc.tweaked:cc-tweaked-1.20.1-core"
41+
},
42+
"ranges": [
43+
{
44+
"type": "ECOSYSTEM",
45+
"events": [
46+
{
47+
"introduced": "0"
48+
},
49+
{
50+
"fixed": "1.119.0"
51+
}
52+
]
53+
}
54+
]
55+
},
56+
{
57+
"package": {
58+
"ecosystem": "Maven",
59+
"name": "cc.tweaked:cc-tweaked-1.20.4-core"
60+
},
61+
"ranges": [
62+
{
63+
"type": "ECOSYSTEM",
64+
"events": [
65+
{
66+
"introduced": "0"
67+
},
68+
{
69+
"fixed": "1.119.0"
70+
}
71+
]
72+
}
73+
]
74+
},
75+
{
76+
"package": {
77+
"ecosystem": "Maven",
78+
"name": "cc.tweaked:cc-tweaked-1.20.5-core"
79+
},
80+
"ranges": [
81+
{
82+
"type": "ECOSYSTEM",
83+
"events": [
84+
{
85+
"introduced": "0"
86+
},
87+
{
88+
"fixed": "1.119.0"
89+
}
90+
]
91+
}
92+
]
93+
},
94+
{
95+
"package": {
96+
"ecosystem": "Maven",
97+
"name": "cc.tweaked:cc-tweaked-1.20.6-core"
98+
},
99+
"ranges": [
100+
{
101+
"type": "ECOSYSTEM",
102+
"events": [
103+
{
104+
"introduced": "0"
105+
},
106+
{
107+
"fixed": "1.119.0"
108+
}
109+
]
110+
}
111+
]
112+
},
113+
{
114+
"package": {
115+
"ecosystem": "Maven",
116+
"name": "cc.tweaked:cc-tweaked-1.19.3-core"
117+
},
118+
"ranges": [
119+
{
120+
"type": "ECOSYSTEM",
121+
"events": [
122+
{
123+
"introduced": "0"
124+
},
125+
{
126+
"fixed": "1.119.0"
127+
}
128+
]
129+
}
130+
]
131+
},
132+
{
133+
"package": {
134+
"ecosystem": "Maven",
135+
"name": "cc.tweaked:cc-tweaked-1.19.4-core"
136+
},
137+
"ranges": [
138+
{
139+
"type": "ECOSYSTEM",
140+
"events": [
141+
{
142+
"introduced": "0"
143+
},
144+
{
145+
"fixed": "1.119.0"
146+
}
147+
]
148+
}
149+
]
150+
},
151+
{
152+
"package": {
153+
"ecosystem": "Maven",
154+
"name": "cc.tweaked:cc-tweaked-1.20-core"
155+
},
156+
"ranges": [
157+
{
158+
"type": "ECOSYSTEM",
159+
"events": [
160+
{
161+
"introduced": "0"
162+
},
163+
{
164+
"fixed": "1.119.0"
165+
}
166+
]
167+
}
168+
]
169+
}
170+
],
171+
"references": [
172+
{
173+
"type": "WEB",
174+
"url": "https://github.com/cc-tweaked/CC-Tweaked/security/advisories/GHSA-5jh9-2h63-pw4q"
175+
},
176+
{
177+
"type": "PACKAGE",
178+
"url": "https://github.com/cc-tweaked/CC-Tweaked"
179+
}
180+
],
181+
"database_specific": {
182+
"cwe_ids": [
183+
"CWE-918"
184+
],
185+
"severity": "HIGH",
186+
"github_reviewed": true,
187+
"github_reviewed_at": "2026-05-29T20:21:12Z",
188+
"nvd_published_at": null
189+
}
190+
}

0 commit comments

Comments
 (0)