Skip to content

Commit 25c0bb0

Browse files
committed
feat: integrated dns lookup for private IP addresses
1 parent 34a7ce1 commit 25c0bb0

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

backend/proxy.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import rateLimit from 'express-rate-limit';
22
import { request as httpsRequest } from 'https';
33
import { URL } from 'url';
44
import net from 'net';
5+
import dns from 'dns/promises';
56

67
function isLocalDomain(hostname) {
78
const localDomains = ['localhost', '127.0.0.1', '::1'];
@@ -23,10 +24,17 @@ function isPrivateIp(ip) {
2324
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true;
2425
// 192.168.0.0/16
2526
if (parts[0] === 192 && parts[1] === 168) return true;
27+
// 127.0.0.0/8 (localhost)
28+
if (parts[0] === 127) return true;
2629
}
2730
if (net.isIPv6(ip)) {
2831
const lowerIp = ip.toLowerCase();
32+
// fc00::/7 (unique local addresses)
2933
if (lowerIp.startsWith('fc') || lowerIp.startsWith('fd')) return true;
34+
// fe80::/10 (link-local addresses)
35+
if (lowerIp.startsWith('fe80:')) return true;
36+
// ::1/128 (localhost)
37+
if (lowerIp === '::1') return true;
3038
}
3139
return false;
3240
}
@@ -61,6 +69,19 @@ async function proxyHandler(req, res) {
6169
return res.status(403).send('Request Forbidden');
6270
}
6371

72+
// Perform DNS resolution to check for private IPs
73+
try {
74+
const addresses = await dns.lookup(parsedUrl.hostname, { all: true });
75+
for (const addr of addresses) {
76+
if (isPrivateIp(addr.address)) {
77+
return res.status(403).send('Request Forbidden');
78+
}
79+
}
80+
} catch (dnsError) {
81+
// If DNS lookup fails, we block the request for safety.
82+
return res.status(403).send('Request Forbidden');
83+
}
84+
6485
const options = {
6586
hostname: parsedUrl.hostname,
6687
port: parsedUrl.port || 443,

0 commit comments

Comments
 (0)