@@ -2,8 +2,13 @@ import { LRUMap } from "../../ratelimiting/LRUMap";
22import type { Context } from "../../agent/Context" ;
33import { isWebScanner } from "./isWebScanner" ;
44
5+ export type SuspiciousRequest = {
6+ method : string ;
7+ url : string ;
8+ } ;
9+
510export class AttackWaveDetector {
6- private suspiciousRequestsMap : LRUMap < string , number > ;
11+ private suspiciousRequestsMap : LRUMap < string , SuspiciousRequest [ ] > ;
712 private sentEventsMap : LRUMap < string , number > ;
813
914 // How many suspicious requests are allowed before triggering an alert
@@ -57,19 +62,33 @@ export class AttackWaveDetector {
5762 return false ;
5863 }
5964
65+ // In isWebScanner we use `context.route`, `context.route` is always created from `context.url`
66+ if ( ! context . method || ! context . url ) {
67+ return false ;
68+ }
69+
6070 if ( ! isWebScanner ( context ) ) {
6171 return false ;
6272 }
6373
64- const suspiciousRequests = ( this . suspiciousRequestsMap . get ( ip ) || 0 ) + 1 ;
74+ const suspiciousRequests = this . suspiciousRequestsMap . get ( ip ) || [ ] ;
75+ suspiciousRequests . push ( {
76+ method : context . method ,
77+ url : context . url ,
78+ } ) ;
79+
6580 this . suspiciousRequestsMap . set ( ip , suspiciousRequests ) ;
6681
67- if ( suspiciousRequests < this . attackWaveThreshold ) {
82+ if ( suspiciousRequests . length < this . attackWaveThreshold ) {
6883 return false ;
6984 }
7085
7186 this . sentEventsMap . set ( ip , performance . now ( ) ) ;
7287
7388 return true ;
7489 }
90+
91+ getSamplesForIP ( ip : string ) {
92+ return this . suspiciousRequestsMap . get ( ip ) || [ ] ;
93+ }
7594}
0 commit comments