import * as http from "node:http"; import * as https from "node:https"; import net from "node:net"; import { HttpProxyAgent, HttpsProxyAgent } from "hpagent"; import config from "../config/index.js"; import IPCIDR from "ip-cidr"; import PrivateIp from "private-ip"; function isPrivateIp(ip) { for (const net of config.allowedPrivateNetworks || []){ const cidr = new IPCIDR(net); if (cidr.contains(ip)) { return false; } } return PrivateIp(ip); } function checkConnection(socket) { if (socket instanceof net.Socket) { const address = socket.remoteAddress; if (process.env.NODE_ENV === 'production') { if (address && IPCIDR.isValidAddress(address) && isPrivateIp(address)) { socket.destroy(new Error(`Blocked address: ${address}`)); } } } else { throw "Tried to check connection for type that isn't net.Socket"; } } export class CheckedHttpAgent extends http.Agent { createConnection(options, callback) { const socket = super.createConnection(options, callback ? (err, stream)=>{ if (stream) checkConnection(stream); callback(err, stream); } : undefined)?.on('connect', ()=>{ socket && checkConnection(socket); }); return socket; } } export class CheckedHttpsAgent extends https.Agent { createConnection(options, callback) { const socket = super.createConnection(options, callback ? (err, stream)=>{ if (stream) checkConnection(stream); callback(err, stream); } : undefined)?.on('connect', ()=>{ socket && checkConnection(socket); }); return socket; } } export class CheckedHttpProxyAgent extends HttpProxyAgent { createConnection(options, callback) { const socket = super.createConnection(options, callback ? (err, stream)=>{ if (stream) checkConnection(stream); callback(err, stream); } : undefined)?.on('connect', ()=>{ socket && checkConnection(socket); }); return socket; } } export class CheckedHttpsProxyAgent extends HttpsProxyAgent { createConnection(options, callback) { const socket = super.createConnection(options, callback ? (err, stream)=>{ if (stream) checkConnection(stream); callback(err, stream); } : undefined)?.on('connect', ()=>{ socket && checkConnection(socket); }); return socket; } }