mirror of
https://github.com/wukko/cobalt.git
synced 2025-01-12 11:52:12 +01:00
api: proper rate limiting (including limiting ipv6 by prefix)
merge pull request #163 from dumbmoron/xff
This commit is contained in:
commit
bb04749fc1
3 changed files with 17 additions and 3 deletions
|
@ -34,6 +34,7 @@
|
||||||
"express-rate-limit": "^6.3.0",
|
"express-rate-limit": "^6.3.0",
|
||||||
"ffmpeg-static": "^5.1.0",
|
"ffmpeg-static": "^5.1.0",
|
||||||
"hls-parser": "^0.10.7",
|
"hls-parser": "^0.10.7",
|
||||||
|
"ipaddr.js": "2.1.0",
|
||||||
"nanoid": "^4.0.2",
|
"nanoid": "^4.0.2",
|
||||||
"node-cache": "^5.1.2",
|
"node-cache": "^5.1.2",
|
||||||
"psl": "1.9.0",
|
"psl": "1.9.0",
|
||||||
|
|
|
@ -24,7 +24,7 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||||
max: 20,
|
max: 20,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req, res) => sha256(getIP(req), ipSalt),
|
keyGenerator: req => sha256(getIP(req), ipSalt),
|
||||||
handler: (req, res, next, opt) => {
|
handler: (req, res, next, opt) => {
|
||||||
return res.status(429).json({
|
return res.status(429).json({
|
||||||
"status": "rate-limit",
|
"status": "rate-limit",
|
||||||
|
@ -37,7 +37,7 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||||
max: 25,
|
max: 25,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req, res) => sha256(getIP(req), ipSalt),
|
keyGenerator: req => sha256(getIP(req), ipSalt),
|
||||||
handler: (req, res, next, opt) => {
|
handler: (req, res, next, opt) => {
|
||||||
return res.status(429).json({
|
return res.status(429).json({
|
||||||
"status": "rate-limit",
|
"status": "rate-limit",
|
||||||
|
@ -49,6 +49,8 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
||||||
const startTime = new Date();
|
const startTime = new Date();
|
||||||
const startTimestamp = Math.floor(startTime.getTime());
|
const startTimestamp = Math.floor(startTime.getTime());
|
||||||
|
|
||||||
|
app.set('trust proxy', ['loopback', 'uniquelocal']);
|
||||||
|
|
||||||
app.use('/api/:type', cors(corsConfig));
|
app.use('/api/:type', cors(corsConfig));
|
||||||
app.use('/api/json', apiLimiter);
|
app.use('/api/json', apiLimiter);
|
||||||
app.use('/api/stream', apiLimiterStream);
|
app.use('/api/stream', apiLimiterStream);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { normalizeURL } from "../processing/url.js";
|
import { normalizeURL } from "../processing/url.js";
|
||||||
import { createStream } from "../stream/manage.js";
|
import { createStream } from "../stream/manage.js";
|
||||||
|
import ipaddr from "ipaddr.js";
|
||||||
|
|
||||||
const apiVar = {
|
const apiVar = {
|
||||||
allowed: {
|
allowed: {
|
||||||
|
@ -111,7 +112,17 @@ export function checkJSONPost(obj) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function getIP(req) {
|
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) {
|
export function cleanHTML(html) {
|
||||||
let clean = html.replace(/ {4}/g, '');
|
let clean = html.replace(/ {4}/g, '');
|
||||||
|
|
Loading…
Reference in a new issue