Skip to content

Commit 774d461

Browse files
Autowebassat-blipCodex Microtask Operator
andauthored
Block IPv4-compatible IPv6 feed URLs (#32)
Co-authored-by: Codex Microtask Operator <codex-microtask@example.com>
1 parent 307095d commit 774d461

2 files changed

Lines changed: 11 additions & 0 deletions

File tree

plugins/feed-discovery/src/feed-discovery.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ describe("site probing helpers", () => {
6363
await expect(assertSafeHttpUrl("http://127.0.0.1/feed")).rejects.toThrow(/Blocked internal/);
6464
await expect(assertSafeHttpUrl("http://[::]/feed")).rejects.toThrow(/Blocked internal/);
6565
await expect(assertSafeHttpUrl("http://[::ffff:192.168.1.10]/feed")).rejects.toThrow(/Blocked internal/);
66+
await expect(assertSafeHttpUrl("http://[::192.168.1.10]/feed")).rejects.toThrow(/Blocked internal/);
6667
await expect(assertSafeHttpUrl("file:///etc/passwd")).rejects.toThrow(/Unsupported URL protocol/);
6768
});
6869

plugins/feed-discovery/src/url-safety.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ function isBlockedIp(value: string) {
6767

6868
if (kind === 6) {
6969
const normalized = value.toLowerCase();
70+
const compatibleDottedIpv4 = /^::(\d+\.\d+\.\d+\.\d+)$/.exec(normalized);
71+
if (compatibleDottedIpv4) {
72+
return isBlockedIp(compatibleDottedIpv4[1]);
73+
}
74+
const compatibleHexIpv4 = /^::([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(normalized);
75+
if (compatibleHexIpv4) {
76+
const high = Number.parseInt(compatibleHexIpv4[1], 16);
77+
const low = Number.parseInt(compatibleHexIpv4[2], 16);
78+
return isBlockedIp(`${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`);
79+
}
7080
const mappedDottedIpv4 = /^::ffff:(\d+\.\d+\.\d+\.\d+)$/.exec(normalized);
7181
if (mappedDottedIpv4) {
7282
return isBlockedIp(mappedDottedIpv4[1]);

0 commit comments

Comments
 (0)