change: security with ENV

This commit is contained in:
Julian Krauser 2025-02-08 09:30:41 +01:00
parent 2e69f87578
commit ad2232969f
3 changed files with 52 additions and 10 deletions

View file

@ -35,4 +35,11 @@ CLUB_WEBSITE = https://my-club-website-url #optional, muss aber mit http:// oder
BACKUP_INTERVAL = number of days (min 1) # default 1 BACKUP_INTERVAL = number of days (min 1) # default 1
BACKUP_COPIES = number of parallel copies # default 7 BACKUP_COPIES = number of parallel copies # default 7
BACKUP_AUTO_RESTORE = (true|false) # default false BACKUP_AUTO_RESTORE = (true|false) # default ist true
USE_SECURITY_STRICT_LIMIT = (true|false) # default ist true
SECURITY_STRICT_LIMIT_WINDOW = [0-9]*(y|d|h|m|s) # default ist 15
SECURITY_STRICT_LIMIT_REQUEST_COUNT = strict_request_count # default ist 15
USE_SECURITY_LIMIT = (true|false) # default ist true
SECURITY_LIMIT_WINDOW = [0-9]*(y|d|h|m|s) # default ist 1m
SECURITY_LIMIT_REQUEST_COUNT = request_count # default ist 500

View file

@ -28,6 +28,13 @@ export const BACKUP_INTERVAL = Number(process.env.BACKUP_INTERVAL ?? "1");
export const BACKUP_COPIES = Number(process.env.BACKUP_COPIES ?? "7"); export const BACKUP_COPIES = Number(process.env.BACKUP_COPIES ?? "7");
export const BACKUP_AUTO_RESTORE = process.env.BACKUP_AUTO_RESTORE ?? "true"; export const BACKUP_AUTO_RESTORE = process.env.BACKUP_AUTO_RESTORE ?? "true";
export const USE_SECURITY_STRICT_LIMIT = process.env.USE_SECURITY_STRICT_LIMIT ?? "true";
export const SECURITY_STRICT_LIMIT_WINDOW = process.env.SECURITY_STRICT_LIMIT_WINDOW ?? "15m";
export const SECURITY_STRICT_LIMIT_REQUEST_COUNT = Number(process.env.SECURITY_STRICT_LIMIT_REQUEST_COUNT ?? "15");
export const USE_SECURITY_LIMIT = process.env.USE_SECURITY_LIMIT ?? "true";
export const SECURITY_LIMIT_WINDOW = process.env.SECURITY_LIMIT_WINDOW ?? "1m";
export const SECURITY_LIMIT_REQUEST_COUNT = Number(process.env.SECURITY_LIMIT_REQUEST_COUNT ?? "500");
export function configCheck() { export function configCheck() {
if (DB_TYPE != "mysql" && DB_TYPE != "sqlite" && DB_TYPE != "postgres") if (DB_TYPE != "mysql" && DB_TYPE != "sqlite" && DB_TYPE != "postgres")
throw new Error("set valid value to DB_TYPE (mysql|sqlite|postgres)"); throw new Error("set valid value to DB_TYPE (mysql|sqlite|postgres)");
@ -62,15 +69,26 @@ export function configCheck() {
throw new Error("set 'true' or 'false' to BACKUP_AUTO_RESTORE"); throw new Error("set 'true' or 'false' to BACKUP_AUTO_RESTORE");
if (BACKUP_INTERVAL < 1) throw new Error("BACKUP_INTERVAL has to be at least 1"); if (BACKUP_INTERVAL < 1) throw new Error("BACKUP_INTERVAL has to be at least 1");
if (BACKUP_COPIES < 1) throw new Error("BACKUP_COPIES has to be at least 1"); if (BACKUP_COPIES < 1) throw new Error("BACKUP_COPIES has to be at least 1");
if (USE_SECURITY_STRICT_LIMIT != "true" && USE_SECURITY_STRICT_LIMIT != "false")
throw new Error("set 'true' or 'false' to USE_SECURITY_STRICT_LIMIT");
checkMS(SECURITY_STRICT_LIMIT_WINDOW, "SECURITY_STRICT_LIMIT_WINDOW");
if (typeof SECURITY_STRICT_LIMIT_REQUEST_COUNT != "number")
throw new Error("set valid numeric value to SECURITY_STRICT_LIMIT_REQUEST_COUNT");
if (USE_SECURITY_LIMIT != "true" && USE_SECURITY_LIMIT != "false")
throw new Error("set 'true' or 'false' to USE_SECURITY_LIMIT");
checkMS(SECURITY_LIMIT_WINDOW, "SECURITY_LIMIT_WINDOW");
if (typeof SECURITY_LIMIT_REQUEST_COUNT != "number")
throw new Error("set valid numeric value to SECURITY_LIMIT_REQUEST_COUNT");
} }
function checkMS(input: string, origin: string) { function checkMS(input: string, origin: string) {
try { try {
const result = ms(input); const result = ms(input);
if (result === undefined) { if (result === undefined) {
throw new Error(`set valid ms value to ${origin}`); throw new Error(`set valid ms value to ${origin} -> [0-9]*(y|d|h|m|s)`);
} }
} catch (e) { } catch (e) {
throw new Error(`set valid ms value to ${origin}`); throw new Error(`set valid ms value to ${origin} -> [0-9]*(y|d|h|m|s)`);
} }
} }

View file

@ -22,17 +22,34 @@ import authenticateAPI from "../middleware/authenticateAPI";
import server from "./server"; import server from "./server";
import PermissionHelper from "../helpers/permissionHelper"; import PermissionHelper from "../helpers/permissionHelper";
import preventWebapiAccess from "../middleware/preventWebApiAccess"; import preventWebapiAccess from "../middleware/preventWebApiAccess";
import ms from "ms";
import {
SECURITY_LIMIT_REQUEST_COUNT,
SECURITY_LIMIT_WINDOW,
SECURITY_STRICT_LIMIT_REQUEST_COUNT,
SECURITY_STRICT_LIMIT_WINDOW,
USE_SECURITY_LIMIT,
USE_SECURITY_STRICT_LIMIT,
} from "../env.defaults";
const strictLimiter = rateLimit({ const strictLimiter = rateLimit({
windowMs: 15 * 60 * 1000, windowMs: ms(SECURITY_STRICT_LIMIT_WINDOW),
max: 10, max: SECURITY_STRICT_LIMIT_REQUEST_COUNT,
message: "Zu viele Anmeldeversuche innerhalb von 15 Minuten. Bitte warten.", message: `Zu viele Anmeldeversuche innerhalb von ${SECURITY_STRICT_LIMIT_WINDOW}. Bitte warten.`,
skipSuccessfulRequests: true,
skip: () => {
return USE_SECURITY_STRICT_LIMIT == "false";
},
}); });
const generalLimiter = rateLimit({ const generalLimiter = rateLimit({
windowMs: 60 * 1000, windowMs: ms(SECURITY_LIMIT_WINDOW),
max: 500, max: SECURITY_LIMIT_REQUEST_COUNT,
message: "Zu viele Anfragen innerhalb von 1 Minute. Bitte warten.", message: `Zu viele Anfragen innerhalb von ${SECURITY_LIMIT_WINDOW}. Bitte warten.`,
skipSuccessfulRequests: true,
skip: () => {
return USE_SECURITY_LIMIT == "false";
},
}); });
function excludePaths(middleware: RequestHandler, excludedPaths: Array<string>) { function excludePaths(middleware: RequestHandler, excludedPaths: Array<string>) {