@@ -2,6 +2,7 @@ import rateLimit from 'express-rate-limit';
22import { request as httpsRequest } from 'https' ;
33import { URL } from 'url' ;
44import net from 'net' ;
5+ import dns from 'dns/promises' ;
56
67function 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