remove private-ip
Matching IP addresses against Regex does not seem like a smart idea. Also it depends on ipaddr.js so that is already in the dependency tree for us anyway.
This commit is contained in:
parent
c504091c61
commit
6ee8a369b3
|
@ -52,6 +52,7 @@
|
||||||
"got": "12.3.1",
|
"got": "12.3.1",
|
||||||
"hpagent": "0.1.2",
|
"hpagent": "0.1.2",
|
||||||
"ioredis": "4.28.5",
|
"ioredis": "4.28.5",
|
||||||
|
"ipaddr.js": "2.1.0",
|
||||||
"ip-cidr": "3.0.10",
|
"ip-cidr": "3.0.10",
|
||||||
"is-svg": "4.3.2",
|
"is-svg": "4.3.2",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
|
@ -80,7 +81,6 @@
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
"parse5": "7.0.0",
|
"parse5": "7.0.0",
|
||||||
"pg": "8.7.3",
|
"pg": "8.7.3",
|
||||||
"private-ip": "2.3.3",
|
|
||||||
"probe-image-size": "7.2.3",
|
"probe-image-size": "7.2.3",
|
||||||
"promise-limit": "2.7.0",
|
"promise-limit": "2.7.0",
|
||||||
"pug": "3.0.2",
|
"pug": "3.0.2",
|
||||||
|
|
|
@ -3,8 +3,6 @@ import * as stream from 'node:stream';
|
||||||
import * as util from 'node:util';
|
import * as util from 'node:util';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import got, * as Got from 'got';
|
import got, * as Got from 'got';
|
||||||
import IPCIDR from 'ip-cidr';
|
|
||||||
import PrivateIp from 'private-ip';
|
|
||||||
import { SECOND, MINUTE } from '@/const.js';
|
import { SECOND, MINUTE } from '@/const.js';
|
||||||
import config from '@/config/index.js';
|
import config from '@/config/index.js';
|
||||||
import Logger from '@/services/logger.js';
|
import Logger from '@/services/logger.js';
|
||||||
|
@ -42,13 +40,6 @@ export async function downloadUrl(url: string, path: string): Promise<void> {
|
||||||
limit: 0,
|
limit: 0,
|
||||||
},
|
},
|
||||||
}).on('response', (res: Got.Response) => {
|
}).on('response', (res: Got.Response) => {
|
||||||
if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) {
|
|
||||||
if (isPrivateIp(res.ip)) {
|
|
||||||
logger.warn(`Blocked address: ${res.ip}`);
|
|
||||||
req.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentLength = res.headers['content-length'];
|
const contentLength = res.headers['content-length'];
|
||||||
if (contentLength != null) {
|
if (contentLength != null) {
|
||||||
const size = Number(contentLength);
|
const size = Number(contentLength);
|
||||||
|
@ -76,14 +67,3 @@ export async function downloadUrl(url: string, path: string): Promise<void> {
|
||||||
|
|
||||||
logger.succ(`Download finished: ${chalk.cyan(url)}`);
|
logger.succ(`Download finished: ${chalk.cyan(url)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPrivateIp(ip: string): boolean {
|
|
||||||
for (const net of config.allowedPrivateNetworks || []) {
|
|
||||||
const cidr = new IPCIDR(net);
|
|
||||||
if (cidr.contains(ip)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return PrivateIp(ip);
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ import * as dns from 'node:dns';
|
||||||
import CacheableLookup from 'cacheable-lookup';
|
import CacheableLookup from 'cacheable-lookup';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
|
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
|
||||||
|
import ipaddr from 'ipaddr.js';
|
||||||
|
import IPCIDR from 'ip-cidr';
|
||||||
import { SECOND } from '@/const.js';
|
import { SECOND } from '@/const.js';
|
||||||
import config from '@/config/index.js';
|
import config from '@/config/index.js';
|
||||||
|
|
||||||
|
@ -101,7 +103,32 @@ const cacheLookup = (host, _2, _3) => {
|
||||||
options.hints = dns.V4MAPPED;
|
options.hints = dns.V4MAPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache.lookup(host, options, callback);
|
// callback wrapper that checks whether an IP is private.
|
||||||
|
// Private IPs will not be returned in the first place.
|
||||||
|
const wrapper = (err, address, family) => {
|
||||||
|
// mimics dns.lookup behaviour as if no result was found
|
||||||
|
const fakeErr = new Error("private IP");
|
||||||
|
fakeErr.code = 'ENOTFOUND';
|
||||||
|
|
||||||
|
if (err != null) {
|
||||||
|
return callback(err, address, family);
|
||||||
|
} else if (options.all) {
|
||||||
|
const results = address.filter(({ address, family }) => isPublicIp(address));
|
||||||
|
if (results.length === 0) {
|
||||||
|
return callback(fakeErr);
|
||||||
|
} else {
|
||||||
|
return callback(err, results);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isPublicIp(address)) {
|
||||||
|
return callback(err, address, family);
|
||||||
|
} else {
|
||||||
|
return callback(fakeErr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return cache.lookup(host, options, wrapper);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,3 +205,27 @@ export class StatusError extends Error {
|
||||||
this.isClientError = typeof this.statusCode === 'number' && this.statusCode >= 400 && this.statusCode < 500;
|
this.isClientError = typeof this.statusCode === 'number' && this.statusCode >= 400 && this.statusCode < 500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPublicIp(ip: string): boolean {
|
||||||
|
for (const net of config.allowedPrivateNetworks || []) {
|
||||||
|
const cidr = new IPCIDR(net);
|
||||||
|
if (cidr.contains(ip)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround because ipaddr.js in the installed version cannot cope
|
||||||
|
// with v4mapped addresses. a fix has been submitted and merged, but a new
|
||||||
|
// version was not yet released.
|
||||||
|
// FIXME: update ipaddr.js and remove workaround
|
||||||
|
ip = ip.replace(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i, '$1');
|
||||||
|
|
||||||
|
try {
|
||||||
|
let range = ipaddr.process(ip).range();
|
||||||
|
// only unicast or multicast addresses are allowed by default
|
||||||
|
// this does not include e.g. loopback addresses
|
||||||
|
return ['unicast', 'multicast'].includes(range);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3697,6 +3697,7 @@ __metadata:
|
||||||
hpagent: 0.1.2
|
hpagent: 0.1.2
|
||||||
ioredis: 4.28.5
|
ioredis: 4.28.5
|
||||||
ip-cidr: 3.0.10
|
ip-cidr: 3.0.10
|
||||||
|
ipaddr.js: 2.1.0
|
||||||
is-svg: 4.3.2
|
is-svg: 4.3.2
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsdom: 20.0.0
|
jsdom: 20.0.0
|
||||||
|
@ -9087,6 +9088,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"ipaddr.js@npm:2.1.0":
|
||||||
|
version: 2.1.0
|
||||||
|
resolution: "ipaddr.js@npm:2.1.0"
|
||||||
|
checksum: 807a054f2bd720c4d97ee479d6c9e865c233bea21f139fb8dabd5a35c4226d2621c42e07b4ad94ff3f82add926a607d8d9d37c625ad0319f0e08f9f2bd1968e2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"ipaddr.js@npm:^2.0.1":
|
"ipaddr.js@npm:^2.0.1":
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
resolution: "ipaddr.js@npm:2.0.1"
|
resolution: "ipaddr.js@npm:2.0.1"
|
||||||
|
|
Loading…
Reference in a new issue