Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Fixes:
Enterprise Fixes:
- [data-manager] Fixed editing an event whose key contains `&` creating undeletable duplicate rows in the events table

Security Fixes:
- [core] The SSRF address filter now also rejects the RFC 8215 local-use NAT64 prefix (64:ff9b:1::/48), matching how it already handles the well-known NAT64 prefix

## Version 24.05.51

Fixes:
Expand Down
10 changes: 10 additions & 0 deletions api/utils/ssrf-protection.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ function isBlockedIP(ip) {
return parsed.toIPv4Address().range() !== 'unicast';
}

// ipaddr.js reports the well-known NAT64 prefix (64:ff9b::/96) as 'rfc6052'
// (blocked by the unicast check below), but the RFC 8215 local-use NAT64 prefix
// (64:ff9b:1::/48) as generic unicast. Block it explicitly so a NAT64 gateway
// cannot translate its embedded IPv4 into an internal address. Network-specific
// NAT64 prefixes carved from an operator's own unicast space cannot be told
// apart by prefix and remain out of scope.
if (parsed.kind() === 'ipv6' && parsed.match(ipaddr.parseCIDR('64:ff9b:1::/48'))) {
return true;
}

return range !== 'unicast';
}

Expand Down
7 changes: 7 additions & 0 deletions test/unit-tests/api.utils.ssrf-protection.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ describe("SSRF protection utility", function() {
it("allows a public IP literal", async function() {
(await ssrf.isUrlSafe("http://8.8.8.8/")).safe.should.equal(true);
});

it("blocks the RFC 8215 local-use NAT64 prefix (64:ff9b:1::/48)", async function() {
(await ssrf.isUrlSafe("http://[64:ff9b:1::7f00:1]/")).safe.should.equal(false);
});
it("allows a public IPv6 literal", async function() {
(await ssrf.isUrlSafe("http://[2001:4860:4860::8888]/")).safe.should.equal(true);
});
});

describe("safeLookup (connect-time DNS pinning)", function() {
Expand Down
Loading