traffic-guard 0.2.0 → 0.2.1
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.
- package/dist/src/battery.d.ts +19 -0
- package/dist/src/crypto.d.ts +16 -0
- package/dist/src/gate.d.ts +15 -0
- package/dist/src/index.d.ts +32 -0
- package/dist/src/normalizer.d.ts +6 -0
- package/dist/src/policy.d.ts +4 -0
- package/dist/src/types.d.ts +96 -0
- package/package.json +4 -4
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AssessmentResult, NormalizedRequest, RequestContext } from './types.js';
|
|
2
|
+
export declare function loadTypeSafePrimitives(): Promise<{
|
|
3
|
+
choice: any;
|
|
4
|
+
noul: any;
|
|
5
|
+
score: any;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function createBotGateBattery(): {
|
|
8
|
+
is_bot: any;
|
|
9
|
+
is_attack: any;
|
|
10
|
+
is_spoofed: any;
|
|
11
|
+
traffic_type: any;
|
|
12
|
+
risk_level: any;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Computes Shannon entropy of a string using Uint8Array frequency table.
|
|
16
|
+
* Useful for detecting obfuscated attack strings and random scanner paths.
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateShannonEntropy(str: string): number;
|
|
19
|
+
export declare function heuristicAssessment(request: NormalizedRequest, context: RequestContext): AssessmentResult;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface BotCookiePayload {
|
|
2
|
+
h: string;
|
|
3
|
+
c: number;
|
|
4
|
+
ws: number;
|
|
5
|
+
v?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function createClientHash(ip?: string, userAgent?: string): string;
|
|
8
|
+
export declare function signBotToken(payload: BotCookiePayload, secret?: string): string;
|
|
9
|
+
export declare function verifyBotToken(token: string, secret?: string): BotCookiePayload | null;
|
|
10
|
+
export declare function parseCookies(cookieHeader?: string): Record<string, string>;
|
|
11
|
+
export declare function createPoWChallenge(secret?: string, difficulty?: number): {
|
|
12
|
+
seed: string;
|
|
13
|
+
difficulty: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function verifyPoW(seed: string, nonce: string, minDifficulty?: number, secret?: string): boolean;
|
|
16
|
+
export declare function generateChallengeHtml(seed: string, difficulty: number, returnUrl?: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BotGateDecision, BotGateOptions, RequestInput } from './types.js';
|
|
2
|
+
export declare class BotGate {
|
|
3
|
+
private client;
|
|
4
|
+
private clientInitAttempted;
|
|
5
|
+
private options;
|
|
6
|
+
private battery;
|
|
7
|
+
constructor(options?: BotGateOptions);
|
|
8
|
+
private getClient;
|
|
9
|
+
inspect(input: RequestInput, runtimeOptions?: BotGateOptions): Promise<BotGateDecision>;
|
|
10
|
+
middleware(middlewareOptions?: BotGateOptions): (req: any, res: any, next: (err?: any) => void) => Promise<any>;
|
|
11
|
+
private createAllowedDecision;
|
|
12
|
+
private createBlockedDecision;
|
|
13
|
+
}
|
|
14
|
+
export type TrafficGuard = BotGate;
|
|
15
|
+
export declare const TrafficGuard: typeof BotGate;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BotGate, TrafficGuard } from './gate.js';
|
|
2
|
+
import type { BotGateDecision, RequestInput, TrafficDecision, TrafficGuardOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Inspects an incoming request and returns a bot/attack defense decision in under 30 µs.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import trafficguard from 'traffic-guard';
|
|
9
|
+
*
|
|
10
|
+
* const decision = await trafficguard(req);
|
|
11
|
+
* if (decision.shouldBlock) {
|
|
12
|
+
* return res.status(403).json({ error: 'Forbidden', reasons: decision.reasons });
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare function trafficguard(input: RequestInput, options?: TrafficGuardOptions): Promise<TrafficDecision>;
|
|
17
|
+
declare namespace trafficguard {
|
|
18
|
+
var create: (options?: TrafficGuardOptions) => BotGate;
|
|
19
|
+
var inspect: (input: RequestInput, options?: TrafficGuardOptions) => Promise<BotGateDecision>;
|
|
20
|
+
var middleware: (options?: TrafficGuardOptions) => (req: any, res: any, next: (err?: any) => void) => Promise<any>;
|
|
21
|
+
export { TrafficGuard };
|
|
22
|
+
export { BotGate };
|
|
23
|
+
}
|
|
24
|
+
declare const botgate: typeof trafficguard;
|
|
25
|
+
declare const trafficGuard: typeof trafficguard;
|
|
26
|
+
export { TrafficGuard, BotGate, trafficguard, trafficGuard, botgate };
|
|
27
|
+
export { normalizeRequest, checkHeaderOrderAnomaly } from './normalizer.js';
|
|
28
|
+
export { DEFAULT_POLICIES, evaluateDecision, resolvePolicy } from './policy.js';
|
|
29
|
+
export { createBotGateBattery, heuristicAssessment, calculateShannonEntropy } from './battery.js';
|
|
30
|
+
export { signBotToken, verifyBotToken, createPoWChallenge, verifyPoW, generateChallengeHtml, createClientHash } from './crypto.js';
|
|
31
|
+
export type * from './types.js';
|
|
32
|
+
export default trafficguard;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NormalizedRequest, RequestContext, RequestInput } from './types.js';
|
|
2
|
+
export declare function checkHeaderOrderAnomaly(rawHeaders: string[] | undefined, userAgent: string): boolean;
|
|
3
|
+
export declare function normalizeRequest(input: RequestInput): {
|
|
4
|
+
request: NormalizedRequest;
|
|
5
|
+
context: RequestContext;
|
|
6
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AssessmentResult, BotGateDecision, GatePolicy, PolicyName, BotGateOptions, RequestContext } from './types.js';
|
|
2
|
+
export declare const DEFAULT_POLICIES: Record<PolicyName, GatePolicy>;
|
|
3
|
+
export declare function resolvePolicy(policy?: PolicyName | Partial<GatePolicy>): GatePolicy;
|
|
4
|
+
export declare function evaluateDecision(assessment: AssessmentResult, policy: GatePolicy, options: BotGateOptions, durationMs: number, context?: RequestContext): BotGateDecision;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export type PolicyName = 'balanced' | 'strict' | 'permissive';
|
|
2
|
+
export type ActionType = 'allow' | 'challenge' | 'block' | 'tarpit' | 'monitor';
|
|
3
|
+
export type TrafficCategory = 'human' | 'good_bot' | 'bad_bot' | 'attack';
|
|
4
|
+
export interface NormalizedRequest {
|
|
5
|
+
method: string;
|
|
6
|
+
path: string;
|
|
7
|
+
query: Record<string, string | string[]>;
|
|
8
|
+
headers: Record<string, string>;
|
|
9
|
+
rawHeaders?: string[];
|
|
10
|
+
body?: string | Record<string, unknown> | null;
|
|
11
|
+
ip?: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
cookies?: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
export interface RequestContext {
|
|
16
|
+
missingBrowserHeaders: string[];
|
|
17
|
+
suspiciousSignatures: string[];
|
|
18
|
+
claimsBrowser: boolean;
|
|
19
|
+
isKnownSearchBot: boolean;
|
|
20
|
+
headerOrderAnomaly: boolean;
|
|
21
|
+
shannonEntropy: number;
|
|
22
|
+
rateCount?: number;
|
|
23
|
+
isHoneypot?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface GatePolicy {
|
|
26
|
+
attackThreshold: number;
|
|
27
|
+
botThreshold: number;
|
|
28
|
+
challengeThreshold: number;
|
|
29
|
+
riskBlock: number;
|
|
30
|
+
riskChallenge: number;
|
|
31
|
+
spoofThreshold: number;
|
|
32
|
+
velocityBurstLimit: number;
|
|
33
|
+
}
|
|
34
|
+
export interface BotGateOptions {
|
|
35
|
+
policy?: PolicyName | Partial<GatePolicy>;
|
|
36
|
+
apiKey?: string;
|
|
37
|
+
endpoint?: string;
|
|
38
|
+
model?: string;
|
|
39
|
+
timeout?: number;
|
|
40
|
+
allowGoodBots?: boolean;
|
|
41
|
+
whitelistedPaths?: (string | RegExp)[];
|
|
42
|
+
whitelistedIps?: string[];
|
|
43
|
+
honeypotPaths?: string[];
|
|
44
|
+
secretKey?: string;
|
|
45
|
+
tarpitMs?: number;
|
|
46
|
+
enablePoWChallenge?: boolean;
|
|
47
|
+
fallback?: 'heuristic' | 'allow' | 'block';
|
|
48
|
+
onBlock?: (decision: BotGateDecision, req: unknown, res: unknown) => void;
|
|
49
|
+
onChallenge?: (decision: BotGateDecision, req: unknown, res: unknown) => void;
|
|
50
|
+
onTarpit?: (decision: BotGateDecision, req: unknown, res: unknown) => void;
|
|
51
|
+
}
|
|
52
|
+
export interface AssessmentResult {
|
|
53
|
+
isBotProbability: number;
|
|
54
|
+
isAttackProbability: number;
|
|
55
|
+
isSpoofedProbability: number;
|
|
56
|
+
trafficType: TrafficCategory;
|
|
57
|
+
trafficTypeConfidence: number;
|
|
58
|
+
trafficTypeDistribution: Record<string, number>;
|
|
59
|
+
riskScore: number;
|
|
60
|
+
riskConfidence: number;
|
|
61
|
+
riskLevelDistribution: Record<string, number>;
|
|
62
|
+
}
|
|
63
|
+
export interface BotGateDecision {
|
|
64
|
+
action: ActionType;
|
|
65
|
+
shouldBlock: boolean;
|
|
66
|
+
shouldChallenge: boolean;
|
|
67
|
+
shouldTarpit: boolean;
|
|
68
|
+
isBot: boolean;
|
|
69
|
+
isAttack: boolean;
|
|
70
|
+
category: TrafficCategory;
|
|
71
|
+
riskScore: number;
|
|
72
|
+
confidence: number;
|
|
73
|
+
reasons: string[];
|
|
74
|
+
assessment: AssessmentResult;
|
|
75
|
+
durationMs: number;
|
|
76
|
+
setCookieHeader?: string;
|
|
77
|
+
challengeHtml?: string;
|
|
78
|
+
respond?: (res: any) => Promise<boolean> | boolean;
|
|
79
|
+
}
|
|
80
|
+
export type TrafficGuardOptions = BotGateOptions;
|
|
81
|
+
export type TrafficDecision = BotGateDecision;
|
|
82
|
+
export type RequestInput = string | NormalizedRequest | {
|
|
83
|
+
method?: string;
|
|
84
|
+
url?: string;
|
|
85
|
+
path?: string;
|
|
86
|
+
originalUrl?: string;
|
|
87
|
+
headers?: Record<string, string | string[] | undefined>;
|
|
88
|
+
rawHeaders?: string[];
|
|
89
|
+
query?: Record<string, unknown>;
|
|
90
|
+
body?: unknown;
|
|
91
|
+
ip?: string;
|
|
92
|
+
socket?: {
|
|
93
|
+
remoteAddress?: string;
|
|
94
|
+
};
|
|
95
|
+
cookies?: Record<string, string>;
|
|
96
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "traffic-guard",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "High-throughput traffic and attack defense gate with zero required dependencies, wire-order analysis, and TypeSafe System One acceleration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"@typesafe-ai/sdk": "^0.6.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@types/node": "^
|
|
49
|
+
"@types/node": "^26.6.4",
|
|
50
50
|
"@typesafe-ai/sdk": "^0.6.0",
|
|
51
|
-
"esbuild": "^0.
|
|
52
|
-
"typescript": "^5.8.
|
|
51
|
+
"esbuild": "^0.28.2",
|
|
52
|
+
"typescript": "^5.8.3"
|
|
53
53
|
}
|
|
54
54
|
}
|