api-security-shield 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,750 @@
1
+ import { z } from 'zod';
2
+ import { RequestHandler } from 'express';
3
+
4
+ /**
5
+ * Shared primitive and domain types for API Security Shield.
6
+ */
7
+ type ShieldEnvironment = "development" | "test" | "production";
8
+ type ThreatCategory = "sqli" | "xss" | "bot" | "brute_force" | "honeypot" | "reputation" | "rate_limit" | "geo" | "openapi" | "custom";
9
+ type ThreatSeverity = "low" | "medium" | "high" | "critical";
10
+ type ThreatLevel = "low" | "watch" | "warning" | "high" | "critical";
11
+ type ShieldActionType = "allow" | "warn" | "throttle" | "challenge" | "block" | "ban";
12
+ type RequestLocation = "query" | "body" | "headers" | "params" | "path" | "ip" | "fingerprint";
13
+ type JsonPrimitive = string | number | boolean | null;
14
+ type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
15
+ interface JsonObject {
16
+ readonly [key: string]: JsonValue;
17
+ }
18
+ interface RedactedEvidence {
19
+ readonly location: RequestLocation;
20
+ readonly sample?: string;
21
+ readonly patternId?: string;
22
+ }
23
+ interface AuthContext {
24
+ readonly userIdHash?: string;
25
+ readonly accountIdHash?: string;
26
+ readonly apiKeyHash?: string;
27
+ readonly roles?: readonly string[];
28
+ }
29
+ interface FingerprintResult {
30
+ readonly strict: string;
31
+ readonly loose: string;
32
+ readonly components: readonly string[];
33
+ }
34
+ interface DetectorFinding {
35
+ readonly id: string;
36
+ readonly category: ThreatCategory;
37
+ readonly severity: ThreatSeverity;
38
+ readonly confidence: number;
39
+ readonly score: number;
40
+ readonly location?: RequestLocation;
41
+ readonly evidence?: RedactedEvidence;
42
+ readonly message: string;
43
+ }
44
+ interface ThreatScore {
45
+ readonly value: number;
46
+ readonly level: ThreatLevel;
47
+ readonly reasons: readonly string[];
48
+ readonly findings: readonly DetectorFinding[];
49
+ }
50
+ interface RequestContext {
51
+ readonly requestId: string;
52
+ readonly method: string;
53
+ readonly path: string;
54
+ readonly route?: string;
55
+ readonly ip: string;
56
+ readonly headers: Readonly<Record<string, string | readonly string[] | undefined>>;
57
+ readonly query: unknown;
58
+ readonly body: unknown;
59
+ readonly params: Readonly<Record<string, string>>;
60
+ readonly fingerprint?: FingerprintResult;
61
+ readonly auth?: AuthContext;
62
+ readonly findings: readonly DetectorFinding[];
63
+ readonly score?: ThreatScore;
64
+ }
65
+ interface ShieldDecision {
66
+ readonly action: ShieldActionType;
67
+ readonly score: ThreatScore;
68
+ readonly statusCode?: number;
69
+ readonly reason: string;
70
+ }
71
+ interface ActionResult {
72
+ readonly handled: boolean;
73
+ readonly statusCode?: number;
74
+ readonly headers?: Readonly<Record<string, string>>;
75
+ readonly body?: JsonValue;
76
+ }
77
+ interface StorageHealth {
78
+ readonly ok: boolean;
79
+ readonly latencyMs?: number;
80
+ readonly message?: string;
81
+ }
82
+
83
+ interface FingerprintEngineOptions {
84
+ readonly salt?: string;
85
+ }
86
+ /**
87
+ * Basic deterministic fingerprint engine.
88
+ */
89
+ declare class FingerprintEngine {
90
+ private readonly salt;
91
+ /**
92
+ * Creates a fingerprint engine.
93
+ */
94
+ constructor(options?: FingerprintEngineOptions);
95
+ /**
96
+ * Generates strict and loose fingerprints for a request context.
97
+ */
98
+ generate(context: RequestContext): FingerprintResult;
99
+ private collectStrictComponents;
100
+ private collectLooseComponents;
101
+ private header;
102
+ private normalizeUserAgent;
103
+ private hash;
104
+ }
105
+
106
+ /**
107
+ * Runtime configuration schema for API Security Shield.
108
+ */
109
+ declare const securityShieldConfigSchema: z.ZodObject<{
110
+ enabled: z.ZodDefault<z.ZodBoolean>;
111
+ environment: z.ZodDefault<z.ZodEnum<["development", "test", "production"]>>;
112
+ trustProxy: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodArray<z.ZodString, "many">]>>;
113
+ threatEngine: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
114
+ fingerprinting: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
115
+ adaptiveRateLimit: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
116
+ botDetection: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
117
+ bruteForce: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
118
+ sqli: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
119
+ xss: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
120
+ reputation: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
121
+ logger: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
122
+ redis: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
123
+ dashboard: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
124
+ webhooks: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
125
+ plugins: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
126
+ }, "strip", z.ZodTypeAny, {
127
+ sqli: boolean | Record<string, unknown>;
128
+ xss: boolean | Record<string, unknown>;
129
+ reputation: boolean | Record<string, unknown>;
130
+ enabled: boolean;
131
+ environment: "development" | "test" | "production";
132
+ threatEngine: boolean | Record<string, unknown>;
133
+ fingerprinting: boolean | Record<string, unknown>;
134
+ adaptiveRateLimit: boolean | Record<string, unknown>;
135
+ botDetection: boolean | Record<string, unknown>;
136
+ bruteForce: boolean | Record<string, unknown>;
137
+ logger: boolean | Record<string, unknown>;
138
+ trustProxy?: boolean | string[] | undefined;
139
+ redis?: Record<string, unknown> | undefined;
140
+ dashboard?: boolean | Record<string, unknown> | undefined;
141
+ webhooks?: Record<string, unknown>[] | undefined;
142
+ plugins?: unknown[] | undefined;
143
+ }, {
144
+ sqli?: boolean | Record<string, unknown> | undefined;
145
+ xss?: boolean | Record<string, unknown> | undefined;
146
+ reputation?: boolean | Record<string, unknown> | undefined;
147
+ enabled?: boolean | undefined;
148
+ environment?: "development" | "test" | "production" | undefined;
149
+ trustProxy?: boolean | string[] | undefined;
150
+ threatEngine?: boolean | Record<string, unknown> | undefined;
151
+ fingerprinting?: boolean | Record<string, unknown> | undefined;
152
+ adaptiveRateLimit?: boolean | Record<string, unknown> | undefined;
153
+ botDetection?: boolean | Record<string, unknown> | undefined;
154
+ bruteForce?: boolean | Record<string, unknown> | undefined;
155
+ logger?: boolean | Record<string, unknown> | undefined;
156
+ redis?: Record<string, unknown> | undefined;
157
+ dashboard?: boolean | Record<string, unknown> | undefined;
158
+ webhooks?: Record<string, unknown>[] | undefined;
159
+ plugins?: unknown[] | undefined;
160
+ }>;
161
+ type SecurityShieldConfigInput = z.input<typeof securityShieldConfigSchema>;
162
+ type SecurityShieldConfig = z.output<typeof securityShieldConfigSchema>;
163
+
164
+ interface DetectorScanOptions {
165
+ readonly maxDepth?: number;
166
+ readonly maxValues?: number;
167
+ readonly maxStringLength?: number;
168
+ readonly headers?: readonly string[];
169
+ }
170
+ interface ScannedValue {
171
+ readonly location: RequestLocation;
172
+ readonly path: string;
173
+ readonly value: string;
174
+ }
175
+ /**
176
+ * Collects bounded string values from request locations detectors are allowed to inspect.
177
+ */
178
+ declare function collectScannedValues(context: RequestContext, options?: DetectorScanOptions): readonly ScannedValue[];
179
+ /**
180
+ * Produces a short redacted evidence sample.
181
+ */
182
+ declare function evidenceSample(value: string): string;
183
+ /**
184
+ * Safely URL-decodes a value a bounded number of times.
185
+ */
186
+ declare function decodeSafely(value: string, attempts?: number): string;
187
+
188
+ type ConsoleLoggerFormat = "json" | "pretty";
189
+ interface ConsoleLoggerOptions {
190
+ readonly minSeverity?: SecurityEventSeverity;
191
+ readonly format?: ConsoleLoggerFormat;
192
+ readonly includeData?: boolean;
193
+ }
194
+ /**
195
+ * Console-backed event logger for development and basic production setups.
196
+ */
197
+ declare class ConsoleLoggerAdapter implements SecurityEventHandler {
198
+ private readonly minSeverity;
199
+ private readonly format;
200
+ private readonly includeData;
201
+ /**
202
+ * Creates a console logger adapter.
203
+ */
204
+ constructor(options?: ConsoleLoggerOptions);
205
+ /**
206
+ * Handles a security event by writing it to the appropriate console method.
207
+ */
208
+ handle(event: SecurityEvent): void;
209
+ private shouldLog;
210
+ private formatEvent;
211
+ }
212
+
213
+ type EventBusHandler = (event: SecurityEvent) => void | Promise<void>;
214
+ interface EventBusSubscriptionOptions {
215
+ readonly signal?: AbortSignal;
216
+ }
217
+ /**
218
+ * Typed event bus for security events.
219
+ */
220
+ declare class EventBus {
221
+ private readonly emitter;
222
+ private emittingDiagnostic;
223
+ /**
224
+ * Creates an event bus instance.
225
+ */
226
+ constructor();
227
+ /**
228
+ * Subscribes to an event and returns an unsubscribe function.
229
+ */
230
+ on(event: SecurityEventType, handler: EventBusHandler, options?: EventBusSubscriptionOptions): () => void;
231
+ /**
232
+ * Subscribes to a single event occurrence.
233
+ */
234
+ once(event: SecurityEventType, handler: EventBusHandler): () => void;
235
+ /**
236
+ * Removes an event handler.
237
+ */
238
+ off(event: SecurityEventType, handler: EventBusHandler): void;
239
+ /**
240
+ * Emits an event synchronously through EventEmitter.
241
+ */
242
+ emit(event: SecurityEvent): boolean;
243
+ /**
244
+ * Emits an event and catches synchronous or asynchronous listener failures.
245
+ */
246
+ emitSafe(event: SecurityEvent): Promise<void>;
247
+ /**
248
+ * Returns the number of listeners for an event.
249
+ */
250
+ listenerCount(event: SecurityEventType): number;
251
+ private emitHandlerError;
252
+ }
253
+
254
+ /**
255
+ * Public event names emitted by the security platform.
256
+ */
257
+ type SecurityEventType = "request.received" | "request.analyzed" | "threat.detected" | "threat.scored" | "action.enforced" | "rate_limit.triggered" | "rate_limit.exceeded" | "brute_force.detected" | "ip.blacklisted" | "security.alert" | "fingerprint.changed" | "honeypot.triggered" | "bot.detected" | "webhook.triggered" | "threat.blocked" | "plugin.registered" | "plugin.error" | "storage.error";
258
+ type SecurityEventSeverity = "debug" | "info" | "warn" | "error" | "critical";
259
+ interface SecurityEvent {
260
+ readonly id: string;
261
+ readonly type: SecurityEventType;
262
+ readonly timestamp: string;
263
+ readonly requestId?: string;
264
+ readonly severity: SecurityEventSeverity;
265
+ readonly data: JsonObject;
266
+ }
267
+ interface SecurityEventHandler {
268
+ /**
269
+ * Handles a security event emitted by the platform.
270
+ */
271
+ handle(event: SecurityEvent): void | Promise<void>;
272
+ }
273
+ interface ThreatDetectedEventData extends JsonObject {
274
+ readonly category: ThreatSeverity | string;
275
+ readonly detector: string;
276
+ }
277
+
278
+ /**
279
+ * Contract for request detectors that produce security findings.
280
+ */
281
+ declare abstract class AbstractDetector {
282
+ readonly name: string;
283
+ readonly category: string;
284
+ readonly priority: number;
285
+ /**
286
+ * Creates a detector contract.
287
+ */
288
+ constructor(name: string, category: string, priority?: number);
289
+ /**
290
+ * Analyzes a request context and returns detector findings.
291
+ */
292
+ abstract analyze(context: RequestContext): Promise<readonly DetectorFinding[]> | readonly DetectorFinding[];
293
+ }
294
+ /**
295
+ * Contract for custom enforcement actions.
296
+ */
297
+ declare abstract class AbstractAction {
298
+ readonly name: string;
299
+ /**
300
+ * Creates an action contract.
301
+ */
302
+ constructor(name: string);
303
+ /**
304
+ * Executes an action after the shield resolves a decision.
305
+ */
306
+ abstract execute(context: RequestContext, decision: ShieldDecision): Promise<ActionResult> | ActionResult;
307
+ }
308
+ /**
309
+ * Contract for scoring rules that can adjust a threat decision.
310
+ */
311
+ declare abstract class AbstractScoringRule {
312
+ readonly name: string;
313
+ /**
314
+ * Creates a scoring rule contract.
315
+ */
316
+ constructor(name: string);
317
+ /**
318
+ * Calculates a score contribution for the request context.
319
+ */
320
+ abstract score(context: RequestContext): Promise<number> | number;
321
+ }
322
+ /**
323
+ * Contract for platform storage adapters.
324
+ */
325
+ declare abstract class AbstractStorage {
326
+ readonly name: string;
327
+ /**
328
+ * Creates a storage adapter contract.
329
+ */
330
+ constructor(name: string);
331
+ /**
332
+ * Reads a value from storage.
333
+ */
334
+ abstract get<T>(key: string): Promise<T | null>;
335
+ /**
336
+ * Writes a value to storage.
337
+ */
338
+ abstract set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
339
+ /**
340
+ * Increments a numeric value in storage.
341
+ */
342
+ abstract increment(key: string, ttlSeconds: number): Promise<number>;
343
+ /**
344
+ * Deletes a value from storage.
345
+ */
346
+ abstract delete(key: string): Promise<void>;
347
+ /**
348
+ * Reports storage health.
349
+ */
350
+ abstract health(): Promise<StorageHealth>;
351
+ }
352
+ /**
353
+ * Contract for plugins that extend the platform.
354
+ */
355
+ declare abstract class AbstractPlugin {
356
+ readonly name: string;
357
+ readonly version: string;
358
+ /**
359
+ * Creates a plugin contract.
360
+ */
361
+ constructor(name: string, version: string);
362
+ /**
363
+ * Registers plugin capabilities with the host context.
364
+ */
365
+ abstract register(context: PluginContext): void | Promise<void>;
366
+ }
367
+ interface PluginContext {
368
+ /**
369
+ * Adds a detector to the detector pipeline.
370
+ */
371
+ addDetector(detector: AbstractDetector): void;
372
+ /**
373
+ * Adds a custom action to the action registry.
374
+ */
375
+ addAction(action: AbstractAction): void;
376
+ /**
377
+ * Adds a custom scoring rule to the scoring pipeline.
378
+ */
379
+ addScoringRule(rule: AbstractScoringRule): void;
380
+ /**
381
+ * Subscribes to a platform event.
382
+ */
383
+ on(event: SecurityEventType, handler: (event: SecurityEvent) => void | Promise<void>): void;
384
+ }
385
+
386
+ interface SqlInjectionPattern {
387
+ readonly id: string;
388
+ readonly pattern: RegExp;
389
+ readonly score: number;
390
+ readonly confidence: number;
391
+ readonly severity: DetectorFinding["severity"];
392
+ readonly message: string;
393
+ }
394
+ interface SqlInjectionDetectorOptions extends DetectorScanOptions {
395
+ readonly patterns?: readonly SqlInjectionPattern[];
396
+ }
397
+ /**
398
+ * Detects common SQL injection payloads in bounded request fields.
399
+ */
400
+ declare class SqlInjectionDetector extends AbstractDetector {
401
+ private readonly options;
402
+ private readonly patterns;
403
+ /**
404
+ * Creates a SQL injection detector.
405
+ */
406
+ constructor(options?: SqlInjectionDetectorOptions);
407
+ /**
408
+ * Analyzes request values for SQL injection patterns.
409
+ */
410
+ analyze(context: RequestContext): readonly DetectorFinding[];
411
+ }
412
+
413
+ interface XssPattern {
414
+ readonly id: string;
415
+ readonly pattern: RegExp;
416
+ readonly score: number;
417
+ readonly confidence: number;
418
+ readonly severity: DetectorFinding["severity"];
419
+ readonly message: string;
420
+ }
421
+ interface XssDetectorOptions extends DetectorScanOptions {
422
+ readonly patterns?: readonly XssPattern[];
423
+ }
424
+ /**
425
+ * Detects common cross-site scripting payloads in bounded request fields.
426
+ */
427
+ declare class XssDetector extends AbstractDetector {
428
+ private readonly options;
429
+ private readonly patterns;
430
+ /**
431
+ * Creates an XSS detector.
432
+ */
433
+ constructor(options?: XssDetectorOptions);
434
+ /**
435
+ * Analyzes request values for XSS patterns.
436
+ */
437
+ analyze(context: RequestContext): readonly DetectorFinding[];
438
+ }
439
+
440
+ interface BasicThreatEngineOptions {
441
+ readonly detectors?: readonly AbstractDetector[];
442
+ readonly warnAt?: number;
443
+ readonly blockAt?: number;
444
+ readonly criticalAt?: number;
445
+ readonly eventBus?: EventBus;
446
+ }
447
+ interface ThreatEngineResult {
448
+ readonly context: RequestContext;
449
+ readonly findings: readonly DetectorFinding[];
450
+ readonly score: ThreatScore;
451
+ readonly decision: ShieldDecision;
452
+ }
453
+ /**
454
+ * Basic deterministic threat engine for Phase 1 detection and enforcement.
455
+ */
456
+ declare class BasicThreatEngine {
457
+ private readonly detectors;
458
+ private readonly warnAt;
459
+ private readonly blockAt;
460
+ private readonly criticalAt;
461
+ private readonly eventBus?;
462
+ /**
463
+ * Creates a basic threat engine.
464
+ */
465
+ constructor(options?: BasicThreatEngineOptions);
466
+ /**
467
+ * Runs detectors, calculates score, resolves action, and emits security events.
468
+ */
469
+ analyze(context: RequestContext): Promise<ThreatEngineResult>;
470
+ private calculateScore;
471
+ private resolveLevel;
472
+ private resolveDecision;
473
+ private eventSeverity;
474
+ }
475
+
476
+ interface BruteForceProtectionOptions {
477
+ readonly storage?: AbstractStorage;
478
+ readonly eventBus?: EventBus;
479
+ readonly loginRoutes?: readonly string[];
480
+ readonly maxAttempts?: number;
481
+ readonly windowSeconds?: number;
482
+ readonly lockSeconds?: number;
483
+ readonly accountResolver?: (context: RequestContext) => string | null;
484
+ }
485
+ interface BruteForceResult {
486
+ readonly allowed: boolean;
487
+ readonly routeMatched: boolean;
488
+ readonly identity: string;
489
+ readonly attempts: number;
490
+ readonly locked: boolean;
491
+ readonly retryAfterSeconds: number;
492
+ readonly reason: string;
493
+ }
494
+ /**
495
+ * Tracks repeated login attempts by account and IP and applies temporary locks.
496
+ */
497
+ declare class BruteForceProtection {
498
+ private readonly storage;
499
+ private readonly eventBus?;
500
+ private readonly loginRoutes;
501
+ private readonly maxAttempts;
502
+ private readonly windowSeconds;
503
+ private readonly lockSeconds;
504
+ private readonly accountResolver;
505
+ /**
506
+ * Creates brute force protection.
507
+ */
508
+ constructor(options?: BruteForceProtectionOptions);
509
+ /**
510
+ * Checks whether the request is currently locked by brute force policy.
511
+ */
512
+ check(context: RequestContext): Promise<BruteForceResult>;
513
+ /**
514
+ * Records a login attempt and locks identity after too many attempts.
515
+ */
516
+ recordAttempt(context: RequestContext): Promise<BruteForceResult>;
517
+ /**
518
+ * Records a failed authentication attempt for host application integrations.
519
+ */
520
+ recordFailure(context: RequestContext): Promise<BruteForceResult>;
521
+ /**
522
+ * Clears brute force counters after successful authentication.
523
+ */
524
+ recordSuccess(context: RequestContext): Promise<void>;
525
+ private isLoginRoute;
526
+ private identity;
527
+ private safe;
528
+ private attemptKey;
529
+ private lockKey;
530
+ private result;
531
+ private emitDetected;
532
+ }
533
+
534
+ interface RouteRateLimitPolicy {
535
+ readonly route: string;
536
+ readonly limit: number;
537
+ readonly windowSeconds: number;
538
+ }
539
+ interface AdaptiveRateLimiterOptions {
540
+ readonly storage?: AbstractStorage;
541
+ readonly eventBus?: EventBus;
542
+ readonly defaultLimit?: number;
543
+ readonly windowSeconds?: number;
544
+ readonly blockDurationSeconds?: number;
545
+ readonly highRiskLimit?: number;
546
+ readonly highRiskScore?: number;
547
+ readonly identityResolver?: (context: RequestContext) => string;
548
+ readonly routePolicies?: readonly RouteRateLimitPolicy[];
549
+ }
550
+ interface RateLimitResult {
551
+ readonly allowed: boolean;
552
+ readonly identity: string;
553
+ readonly key: string;
554
+ readonly limit: number;
555
+ readonly remaining: number;
556
+ readonly count: number;
557
+ readonly resetAt: string;
558
+ readonly retryAfterSeconds: number;
559
+ readonly blocked: boolean;
560
+ readonly reason: string;
561
+ }
562
+ /**
563
+ * Adaptive rate limiter with route-aware and risk-aware limits.
564
+ */
565
+ declare class AdaptiveRateLimiter {
566
+ private readonly storage;
567
+ private readonly eventBus?;
568
+ private readonly defaultLimit;
569
+ private readonly windowSeconds;
570
+ private readonly blockDurationSeconds;
571
+ private readonly highRiskLimit;
572
+ private readonly highRiskScore;
573
+ private readonly identityResolver;
574
+ private readonly routePolicies;
575
+ /**
576
+ * Creates an adaptive rate limiter.
577
+ */
578
+ constructor(options?: AdaptiveRateLimiterOptions);
579
+ /**
580
+ * Evaluates and records a request against the adaptive rate-limit policy.
581
+ */
582
+ evaluate(context: RequestContext, score?: ThreatScore): Promise<RateLimitResult>;
583
+ /**
584
+ * Converts a denied rate-limit result into a shield decision.
585
+ */
586
+ toDecision(result: RateLimitResult): ShieldDecision;
587
+ private resolvePolicy;
588
+ private result;
589
+ private safeIdentity;
590
+ private emitTriggered;
591
+ }
592
+
593
+ interface RedisStorageOptions {
594
+ readonly url?: string;
595
+ readonly keyPrefix?: string;
596
+ readonly client?: RedisLike;
597
+ readonly connectTimeoutMs?: number;
598
+ }
599
+ interface RedisLike {
600
+ get(key: string): Promise<string | null>;
601
+ set(key: string, value: string, mode?: "EX", ttlSeconds?: number): Promise<unknown>;
602
+ incr(key: string): Promise<number>;
603
+ expire(key: string, ttlSeconds: number): Promise<unknown>;
604
+ del(key: string): Promise<unknown>;
605
+ ping(): Promise<string>;
606
+ }
607
+
608
+ interface MemoryStorageOptions {
609
+ readonly now?: () => number;
610
+ }
611
+ /**
612
+ * Error thrown when memory storage receives invalid input.
613
+ */
614
+ declare class MemoryStorageError extends Error {
615
+ /**
616
+ * Creates a memory storage error.
617
+ */
618
+ constructor(message: string);
619
+ }
620
+ /**
621
+ * In-memory storage adapter for development, tests, and single-process deployments.
622
+ */
623
+ declare class MemoryStorageAdapter extends AbstractStorage {
624
+ private readonly entries;
625
+ private readonly now;
626
+ /**
627
+ * Creates a memory storage adapter.
628
+ */
629
+ constructor(options?: MemoryStorageOptions);
630
+ /**
631
+ * Reads a value from storage if the key exists and has not expired.
632
+ */
633
+ get<T>(key: string): Promise<T | null>;
634
+ /**
635
+ * Writes a value to storage with an optional TTL.
636
+ */
637
+ set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
638
+ /**
639
+ * Increments a numeric value, initializing missing values at zero.
640
+ */
641
+ increment(key: string, ttlSeconds: number): Promise<number>;
642
+ /**
643
+ * Deletes a value from storage.
644
+ */
645
+ delete(key: string): Promise<void>;
646
+ /**
647
+ * Reports memory storage health.
648
+ */
649
+ health(): Promise<StorageHealth>;
650
+ /**
651
+ * Removes all values from storage.
652
+ */
653
+ clear(): void;
654
+ /**
655
+ * Returns the number of non-expired values.
656
+ */
657
+ size(): number;
658
+ private validateKey;
659
+ private validateTtl;
660
+ private resolveExpiresAt;
661
+ private isExpired;
662
+ private pruneExpired;
663
+ }
664
+
665
+ interface IpReputationOptions {
666
+ readonly storage?: AbstractStorage;
667
+ readonly eventBus?: EventBus;
668
+ readonly historyTtlSeconds?: number;
669
+ readonly blacklistTtlSeconds?: number;
670
+ readonly blacklistScore?: number;
671
+ readonly scoreDecay?: number;
672
+ }
673
+ interface IpReputationRecord {
674
+ readonly ip: string;
675
+ readonly score: number;
676
+ readonly firstSeen: string;
677
+ readonly lastSeen: string;
678
+ readonly requests: number;
679
+ readonly threats: number;
680
+ }
681
+ interface IpReputationResult {
682
+ readonly ip: string;
683
+ readonly score: number;
684
+ readonly allowed: boolean;
685
+ readonly whitelisted: boolean;
686
+ readonly blacklisted: boolean;
687
+ readonly reason: string;
688
+ }
689
+ /**
690
+ * Tracks IP behavior, reputation score, and allow/block state.
691
+ */
692
+ declare class IpReputationService {
693
+ private readonly storage;
694
+ private readonly eventBus?;
695
+ private readonly historyTtlSeconds;
696
+ private readonly blacklistTtlSeconds;
697
+ private readonly blacklistScore;
698
+ private readonly scoreDecay;
699
+ /**
700
+ * Creates an IP reputation service.
701
+ */
702
+ constructor(options?: IpReputationOptions);
703
+ /**
704
+ * Assesses whether an IP is currently allowed.
705
+ */
706
+ assess(context: RequestContext): Promise<IpReputationResult>;
707
+ /**
708
+ * Records threat activity and blacklists IPs that exceed the threshold.
709
+ */
710
+ recordThreat(context: RequestContext, score: ThreatScore, findings: readonly DetectorFinding[]): Promise<IpReputationRecord>;
711
+ /**
712
+ * Adds an IP to the whitelist.
713
+ */
714
+ whitelist(ip: string, ttlSeconds?: number): Promise<void>;
715
+ /**
716
+ * Adds an IP to the blacklist.
717
+ */
718
+ blacklist(ip: string, reason: string, ttlSeconds?: number, requestId?: string): Promise<void>;
719
+ private touch;
720
+ private getRecord;
721
+ private result;
722
+ private normalizeIp;
723
+ private recordKey;
724
+ private allowKey;
725
+ private blockKey;
726
+ }
727
+
728
+ type SecurityShieldMiddlewareOptions = SecurityShieldConfigInput & {
729
+ readonly eventBus?: EventBus;
730
+ readonly loggerOptions?: ConsoleLoggerOptions;
731
+ readonly storage?: AbstractStorage;
732
+ readonly detectors?: readonly AbstractDetector[];
733
+ readonly fingerprintOptions?: FingerprintEngineOptions;
734
+ readonly threatEngineOptions?: Omit<BasicThreatEngineOptions, "detectors" | "eventBus">;
735
+ readonly sqliOptions?: SqlInjectionDetectorOptions;
736
+ readonly xssOptions?: XssDetectorOptions;
737
+ readonly redisStorageOptions?: RedisStorageOptions;
738
+ readonly rateLimiter?: AdaptiveRateLimiter;
739
+ readonly rateLimiterOptions?: Omit<AdaptiveRateLimiterOptions, "storage" | "eventBus">;
740
+ readonly ipReputation?: IpReputationService;
741
+ readonly ipReputationOptions?: Omit<IpReputationOptions, "storage" | "eventBus">;
742
+ readonly bruteForceProtection?: BruteForceProtection;
743
+ readonly bruteForceOptions?: Omit<BruteForceProtectionOptions, "storage" | "eventBus">;
744
+ };
745
+ /**
746
+ * Creates Express middleware for Phase 1 API security analysis.
747
+ */
748
+ declare function securityShield(options?: SecurityShieldMiddlewareOptions): RequestHandler;
749
+
750
+ export { AbstractAction, AbstractDetector, AbstractPlugin, AbstractScoringRule, AbstractStorage, type ActionResult, type AuthContext, BasicThreatEngine, type BasicThreatEngineOptions, ConsoleLoggerAdapter, type ConsoleLoggerFormat, type ConsoleLoggerOptions, type DetectorFinding, type DetectorScanOptions, EventBus, type EventBusHandler, type EventBusSubscriptionOptions, FingerprintEngine, type FingerprintEngineOptions, type FingerprintResult, type JsonObject, type JsonPrimitive, type JsonValue, MemoryStorageAdapter, MemoryStorageError, type MemoryStorageOptions, type PluginContext, type RedactedEvidence, type RequestContext, type RequestLocation, type ScannedValue, type SecurityEvent, type SecurityEventHandler, type SecurityEventSeverity, type SecurityEventType, type SecurityShieldConfig, type SecurityShieldConfigInput, type SecurityShieldMiddlewareOptions, type ShieldActionType, type ShieldDecision, type ShieldEnvironment, SqlInjectionDetector, type SqlInjectionDetectorOptions, type StorageHealth, type ThreatCategory, type ThreatDetectedEventData, type ThreatEngineResult, type ThreatLevel, type ThreatScore, type ThreatSeverity, XssDetector, type XssDetectorOptions, collectScannedValues, decodeSafely, evidenceSample, securityShield, securityShieldConfigSchema };