Skip to content

Commit 91b6477

Browse files
committed
fix(security): also block IPv4-compatible IPv6 with Class E embedded IPv4
1 parent 8b34eb2 commit 91b6477

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

apps/sim/lib/core/security/input-validation.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function isPrivateOrReservedIP(ip: string): boolean {
4444
const v6 = addr as ipaddr.IPv6
4545
const parts = v6.parts
4646
const firstSixZero = parts.slice(0, 6).every((p) => p === 0)
47-
if (firstSixZero && parts[6] !== 0xffff) {
47+
if (firstSixZero) {
4848
const embedded = ipaddr.fromByteArray([
4949
(parts[6] >> 8) & 0xff,
5050
parts[6] & 0xff,

apps/sim/lib/core/security/input-validation.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,15 @@ describe('isPrivateOrReservedIP', () => {
645645
])('allows IPv4-compatible IPv6 with embedded public IPv4 %s — %s', (ip) => {
646646
expect(isPrivateOrReservedIP(ip)).toBe(false)
647647
})
648+
649+
it.concurrent.each([
650+
['::ffff:1', 'embedded 255.255.0.1 (Class E reserved) via parts[6]=0xffff'],
651+
['::ffff:0', 'embedded 255.255.0.0 (Class E reserved)'],
652+
['::ffff:abcd', 'embedded 255.255.171.205 (Class E reserved)'],
653+
['::f000:1', 'embedded 240.0.0.1 (Class E reserved)'],
654+
])('blocks IPv4-compatible IPv6 with Class E embedded IPv4 %s — %s', (ip) => {
655+
expect(isPrivateOrReservedIP(ip)).toBe(true)
656+
})
648657
})
649658

650659
describe('non-IPv4-compat unicast IPv6 (must not over-block)', () => {

0 commit comments

Comments
 (0)