summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-04-28 03:53:45 +0200
committerRory& <root@rory.gay>2026-04-28 03:53:45 +0200
commitd9d339882be60c72ffd8b5dd0b5adb163f447229 (patch)
treefbd88470c522e150133e63fae9468c9d883edc61 /src
parentDocument why ImageProxy.ts exists (diff)
downloadserver-ts-d9d339882be60c72ffd8b5dd0b5adb163f447229.tar.xz
Register: cache blocked IPs
Diffstat (limited to 'src')
-rw-r--r--src/api/routes/auth/register.ts48
-rw-r--r--src/api/routes/reporting/index.ts9
2 files changed, 45 insertions, 12 deletions
diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts

index 5c40ce1d..79929f5e 100644 --- a/src/api/routes/auth/register.ts +++ b/src/api/routes/auth/register.ts
@@ -17,7 +17,7 @@ */ import { route, verifyCaptcha } from "@spacebar/api"; -import { Config, FieldErrors, Invite, User, ValidRegistrationToken, generateToken, IpDataClient, AbuseIpDbClient } from "@spacebar/util"; +import { Config, FieldErrors, Invite, User, ValidRegistrationToken, generateToken, IpDataClient, AbuseIpDbClient, TimeSpan } from "@spacebar/util"; import bcrypt from "bcrypt"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; @@ -26,6 +26,15 @@ import { RegisterSchema } from "@spacebar/schemas"; const router: Router = Router({ mergeParams: true }); +const recentlyBlockedIps: { + [ip: string]: { + firstHit: Date; + lastHit: Date; + hits: number; + reason: string; + }; +} = {}; + router.post( "/", route({ @@ -82,7 +91,7 @@ router.post( throw FieldErrors({ email: { code: "DISABLED", - message: "registration is disabled on this instance", + message: "Registration is disabled on this instance", }, }); } @@ -124,20 +133,44 @@ router.post( } } + //region IP checks + const cacheBlockedIp = (ip: string, reason: string) => { + recentlyBlockedIps[ip] = { + firstHit: new Date(), + lastHit: new Date(), + hits: 0, + reason, + }; + console.log(`[Register] ${ip} blocked from registration:`, reason); + }; + + if (!regTokenUsed && recentlyBlockedIps[ip]) { + if (new TimeSpan(recentlyBlockedIps[ip].firstHit.getTime(), new Date().getTime()).totalHours >= 24) delete recentlyBlockedIps[ip]; + else { + recentlyBlockedIps[ip].lastHit = new Date(); + recentlyBlockedIps[ip].hits++; + console.log( + `[Register] ${ip} blocked from registration: blocked since ${recentlyBlockedIps[ip].firstHit} with ${recentlyBlockedIps[ip].hits} hits and reason:`, + recentlyBlockedIps[ip].reason, + ); + throw new HTTPError("Your IP is blocked from registration"); + } + } + if (!regTokenUsed && register.enableAbuseIpDb) { const blacklist = await AbuseIpDbClient.getBlacklist(); if (blacklist) { const entry = blacklist.data.find((e) => e.ipAddress === ip); if (entry && entry.abuseConfidenceScore >= register.blockAbuseIpDbAboveScore) { - console.log(`[Register] ${ip} blocked from registration: AbuseIPDB score ${entry.abuseConfidenceScore} >= ${register.blockAbuseIpDbAboveScore} (BLACKLIST)`); + cacheBlockedIp(ip, `AbuseIPDB score ${entry.abuseConfidenceScore} >= ${register.blockAbuseIpDbAboveScore} (BLACKLIST)`); throw new HTTPError("Your IP is blocked from registration"); } } const checkIp = await AbuseIpDbClient.checkIpAddress(ip); if (checkIp?.data && checkIp.data.abuseConfidenceScore >= register.blockAbuseIpDbAboveScore) { - console.log(`[Register] ${ip} blocked from registration: AbuseIPDB score ${checkIp.data.abuseConfidenceScore} >= ${register.blockAbuseIpDbAboveScore} (CHECK)`); + cacheBlockedIp(ip, `AbuseIPDB score ${checkIp.data.abuseConfidenceScore} >= ${register.blockAbuseIpDbAboveScore} (CHECK)`); throw new HTTPError("Your IP is blocked from registration"); } } @@ -153,25 +186,26 @@ router.post( .map(([key]) => key.replace("is_", "")); const blockedCategories = new Set(categories).intersection(new Set(register.blockIpDataCoThreatTypes)); if (blockedCategories.size > 0) { - console.log(`[Register] ${ip} blocked from registration: IPData.co threat types ${Array.from(blockedCategories).join(", ")}`); + cacheBlockedIp(ip, `IPData.co threat types ${Array.from(blockedCategories).join(", ")}`); throw new HTTPError("Your IP is blocked from registration"); } if (ipData.asn.type && register.blockAsnTypes.includes(ipData.asn.type)) { - console.log(`[Register] ${ip} blocked from registration: IPData.co ASN type ${ipData.asn.type} is blocked`); + cacheBlockedIp(ip, `IPData.co ASN type ${ipData.asn.type} is blocked`); throw new HTTPError("Your IP is blocked from registration"); } else if (!ipData.asn.type) { console.log("[Register] IPData.co response missing asn.type field", ipData); } if (ipData.asn.asn && register.blockAsns.includes(ipData.asn.asn)) { - console.log(`[Register] ${ip} blocked from registration: IPData.co ASN ${ipData.asn.name} is blocked`); + cacheBlockedIp(ip, `IPData.co ASN ${ipData.asn.name} is blocked`); throw new HTTPError("Your IP is blocked from registration"); } else if (!ipData.asn.asn) { console.log("[Register] IPData.co response missing asn.asn field", ipData); } } } + //endregion // TODO: gift_code_sku_id? // TODO: check password strength diff --git a/src/api/routes/reporting/index.ts b/src/api/routes/reporting/index.ts
index 76b5169a..27d284d7 100644 --- a/src/api/routes/reporting/index.ts +++ b/src/api/routes/reporting/index.ts
@@ -16,14 +16,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { route } from "@spacebar/api"; -import { Request, Response, Router } from "express"; -import { ReportMenuType, ReportMenuTypeNames } from "../../../schemas/api/reports/ReportMenu"; +import fs from "node:fs"; import path from "node:path"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; -import { CreateReportSchema } from "../../../schemas/api/reports/CreateReport"; +import { route } from "@spacebar/api"; +import { ReportMenuType, ReportMenuTypeNames, CreateReportSchema } from "@spacebar/schemas"; import { FieldErrors } from "@spacebar/util"; -import fs from "node:fs"; const router = Router({ mergeParams: true }); if (process.env.LOG_ROUTES !== "false") console.log("[Server] Registering reporting menu routes...");