Implements quick ip banlist

Debugs IP banlist

Adds explainer for getIP util

Adds collect-events to middleware filter

Fixes middleware
pull/3905/head
zomars 2022-08-23 14:34:10 -07:00
parent b88f0617d8
commit c17e949cd6
3 changed files with 35 additions and 2 deletions

View File

@ -2,6 +2,7 @@ import { collectEvents } from "next-collect/server";
import { NextMiddleware, NextResponse, userAgent } from "next/server";
import { CONSOLE_URL, WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
import { isIpInBanlist } from "@calcom/lib/getIP";
import { extendEventData, nextCollectBasicSettings } from "@calcom/lib/telemetry";
const V2_WHITELIST = ["/settings/admin"];
@ -9,13 +10,14 @@ const V2_WHITELIST = ["/settings/admin"];
const middleware: NextMiddleware = async (req) => {
const url = req.nextUrl;
if (url.pathname.startsWith("/api/auth")) {
if (["/api/collect-events", "/api/auth"].some((p) => url.pathname.startsWith(p))) {
const callbackUrl = url.searchParams.get("callbackUrl");
const { isBot } = userAgent(req);
if (
isBot ||
(callbackUrl && ![CONSOLE_URL, WEBAPP_URL, WEBSITE_URL].some((u) => callbackUrl.startsWith(u)))
(callbackUrl && ![CONSOLE_URL, WEBAPP_URL, WEBSITE_URL].some((u) => callbackUrl.startsWith(u))) ||
isIpInBanlist(req)
) {
// DDOS Prevention: Immediately end request with no response - Avoids a redirect as well initiated by NextAuth on invalid callback
req.nextUrl.pathname = "/api/nope";

30
packages/lib/getIP.ts Normal file
View File

@ -0,0 +1,30 @@
import type { NextApiRequest } from "next";
import z from "zod";
export function parseIpFromHeaders(value: string | string[]) {
return Array.isArray(value) ? value[0] : value.split(",")[0];
}
/**
* Tries to extract IP address from a request
* @see https://github.com/vercel/examples/blob/main/edge-functions/ip-blocking/lib/get-ip.ts
**/
export default function getIP(request: Request | NextApiRequest) {
const xff =
request instanceof Request ? request.headers.get("x-forwarded-for") : request.headers["x-forwarded-for"];
return xff ? parseIpFromHeaders(xff) : "127.0.0.1";
}
const banlistSchema = z.array(z.string());
export function isIpInBanlist(request: Request | NextApiRequest) {
const IP = getIP(request);
const rawBanListJson = process.env.IP_BANLIST || "[]";
const banList = banlistSchema.parse(JSON.parse(rawBanListJson));
if (banList.includes(IP)) {
console.log(`Found banned IP: ${IP} in IP_BANLIST`);
return true;
}
return false;
}

View File

@ -219,6 +219,7 @@
"$HUBSPOT_CLIENT_ID",
"$HUBSPOT_CLIENT_SECRET",
"$INTEGRATION_TEST_MODE",
"$IP_BANLIST",
"$NEXT_PUBLIC_CONSOLE_URL",
"$NEXT_PUBLIC_DEBUG",
"$NEXT_PUBLIC_EMBED_LIB_URL",