From a375000ae9f1e9c5648a09438f47f01dd53b5915 Mon Sep 17 00:00:00 2001 From: dumbmoron <136796770+dumbmoron@users.noreply.github.com> Date: Tue, 25 Jul 2023 19:46:25 +0000 Subject: [PATCH] api: use req.ip instead of cloudflare headers, ratelimit ipv6 by prefix allows for more versatile configurations that do not necessarily have to use cloudflare also ratelimits IPv6 addresses by prefix instead of individual addresses currently set at /56, which should not be too strict (yet allows a /48 holder to make 256 as many requests instead of 2^80 as many requests), change if needed --- package.json | 1 + src/core/api.js | 6 ++++-- src/modules/sub/utils.js | 12 +++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ab8a4f0c..587db058 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "express-rate-limit": "^6.3.0", "ffmpeg-static": "^5.1.0", "hls-parser": "^0.10.7", + "ipaddr.js": "2.1.0", "nanoid": "^4.0.2", "node-cache": "^5.1.2", "psl": "1.9.0", diff --git a/src/core/api.js b/src/core/api.js index 71ce8d3e..4ec36c34 100644 --- a/src/core/api.js +++ b/src/core/api.js @@ -24,7 +24,7 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { max: 20, standardHeaders: true, legacyHeaders: false, - keyGenerator: (req, res) => sha256(getIP(req), ipSalt), + keyGenerator: req => sha256(getIP(req), ipSalt), handler: (req, res, next, opt) => { return res.status(429).json({ "status": "rate-limit", @@ -37,7 +37,7 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { max: 25, standardHeaders: true, legacyHeaders: false, - keyGenerator: (req, res) => sha256(getIP(req), ipSalt), + keyGenerator: req => sha256(getIP(req), ipSalt), handler: (req, res, next, opt) => { return res.status(429).json({ "status": "rate-limit", @@ -49,6 +49,8 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { const startTime = new Date(); const startTimestamp = Math.floor(startTime.getTime()); + app.set('trust proxy', ['loopback', 'uniquelocal']); + app.use('/api/:type', cors(corsConfig)); app.use('/api/json', apiLimiter); app.use('/api/stream', apiLimiterStream); diff --git a/src/modules/sub/utils.js b/src/modules/sub/utils.js index 8b5a2c84..a6071c28 100644 --- a/src/modules/sub/utils.js +++ b/src/modules/sub/utils.js @@ -1,5 +1,6 @@ import { normalizeURL } from "../processing/url.js"; import { createStream } from "../stream/manage.js"; +import ipaddr from "ipaddr.js"; const apiVar = { allowed: { @@ -111,7 +112,16 @@ export function checkJSONPost(obj) { } } export function getIP(req) { - return req.header('cf-connecting-ip') ? req.header('cf-connecting-ip') : req.ip; + const strippedIP = req.ip.replace(/^::ffff:/, ''); + const ip = ipaddr.parse(strippedIP); + if (ip.kind() === 'ipv4') + return strippedIP; + + const PREFIX = 56; + const v6Bytes = ip.toByteArray(); + v6Bytes.fill(0, PREFIX / 8); + + return ipaddr.fromByteArray(v6Bytes).toString(); } export function cleanHTML(html) { let clean = html.replace(/ {4}/g, '');