feat: implement IP banning in crawler-detection middleware using cache manager

- Added Redis-based temporary IP banning for suspicious activity detected by the middleware.
- Injected `CACHE_MANAGER` into the middleware to manage banned IPs.
- Enhanced logging to track banned IP attempts.
- Adjusted middleware logic to handle asynchronous IP checks and updates.
This commit is contained in:
Mathis HERRIOT
2026-01-29 14:02:49 +01:00
parent aa17c57e26
commit fc2f5214b1

View File

@@ -1,10 +1,14 @@
import { Injectable, Logger, NestMiddleware } from "@nestjs/common"; import { CACHE_MANAGER } from "@nestjs/cache-manager";
import { Inject, Injectable, Logger, NestMiddleware } from "@nestjs/common";
import type { Cache } from "cache-manager";
import type { NextFunction, Request, Response } from "express"; import type { NextFunction, Request, Response } from "express";
@Injectable() @Injectable()
export class CrawlerDetectionMiddleware implements NestMiddleware { export class CrawlerDetectionMiddleware implements NestMiddleware {
private readonly logger = new Logger("CrawlerDetection"); private readonly logger = new Logger("CrawlerDetection");
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
private readonly SUSPICIOUS_PATTERNS = [ private readonly SUSPICIOUS_PATTERNS = [
/\.env/, /\.env/,
/wp-admin/, /wp-admin/,
@@ -24,7 +28,7 @@ export class CrawlerDetectionMiddleware implements NestMiddleware {
/db\./, /db\./,
/backup\./, /backup\./,
/cgi-bin/, /cgi-bin/,
/\.well-known\/security\.txt/, // Bien que légitime, souvent scanné /\.well-known\/security\.txt/,
]; ];
private readonly BOT_USER_AGENTS = [ private readonly BOT_USER_AGENTS = [
@@ -40,11 +44,21 @@ export class CrawlerDetectionMiddleware implements NestMiddleware {
/masscan/i, /masscan/i,
]; ];
use(req: Request, res: Response, next: NextFunction) { async use(req: Request, res: Response, next: NextFunction) {
const { method, url, ip } = req; const { method, url, ip } = req;
const userAgent = req.get("user-agent") || "unknown"; const userAgent = req.get("user-agent") || "unknown";
res.on("finish", () => { // Vérifier si l'IP est bannie
const isBanned = await this.cacheManager.get(`banned_ip:${ip}`);
if (isBanned) {
this.logger.warn(`Banned IP attempt: ${ip} -> ${method} ${url}`);
res.status(403).json({
message: "Access denied: Your IP has been temporarily banned.",
});
return;
}
res.on("finish", async () => {
if (res.statusCode === 404) { if (res.statusCode === 404) {
const isSuspiciousPath = this.SUSPICIOUS_PATTERNS.some((pattern) => const isSuspiciousPath = this.SUSPICIOUS_PATTERNS.some((pattern) =>
pattern.test(url), pattern.test(url),
@@ -57,7 +71,9 @@ export class CrawlerDetectionMiddleware implements NestMiddleware {
this.logger.warn( this.logger.warn(
`Potential crawler detected: [${ip}] ${method} ${url} - User-Agent: ${userAgent}`, `Potential crawler detected: [${ip}] ${method} ${url} - User-Agent: ${userAgent}`,
); );
// Ici, on pourrait ajouter une logique pour bannir l'IP temporairement via Redis
// Bannir l'IP pour 24h via Redis
await this.cacheManager.set(`banned_ip:${ip}`, true, 86400000);
} }
} }
}); });