monofence-ai 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.
- package/README.md +276 -0
- package/dist/domain/entities/index.d.ts +2 -0
- package/dist/domain/entities/index.d.ts.map +1 -0
- package/dist/domain/entities/index.js +2 -0
- package/dist/domain/entities/index.js.map +1 -0
- package/dist/domain/entities/threat.d.ts +98 -0
- package/dist/domain/entities/threat.d.ts.map +1 -0
- package/dist/domain/entities/threat.js +21 -0
- package/dist/domain/entities/threat.js.map +1 -0
- package/dist/domain/services/allowlist.d.ts +11 -0
- package/dist/domain/services/allowlist.d.ts.map +1 -0
- package/dist/domain/services/allowlist.js +72 -0
- package/dist/domain/services/allowlist.js.map +1 -0
- package/dist/domain/services/context-tracker.d.ts +15 -0
- package/dist/domain/services/context-tracker.d.ts.map +1 -0
- package/dist/domain/services/context-tracker.js +75 -0
- package/dist/domain/services/context-tracker.js.map +1 -0
- package/dist/domain/services/evasion-detector.d.ts +12 -0
- package/dist/domain/services/evasion-detector.d.ts.map +1 -0
- package/dist/domain/services/evasion-detector.js +128 -0
- package/dist/domain/services/evasion-detector.js.map +1 -0
- package/dist/domain/services/index.d.ts +7 -0
- package/dist/domain/services/index.d.ts.map +1 -0
- package/dist/domain/services/index.js +7 -0
- package/dist/domain/services/index.js.map +1 -0
- package/dist/domain/services/output-scanner.d.ts +25 -0
- package/dist/domain/services/output-scanner.d.ts.map +1 -0
- package/dist/domain/services/output-scanner.js +113 -0
- package/dist/domain/services/output-scanner.js.map +1 -0
- package/dist/domain/services/threat-detection-service.d.ts +82 -0
- package/dist/domain/services/threat-detection-service.d.ts.map +1 -0
- package/dist/domain/services/threat-detection-service.js +426 -0
- package/dist/domain/services/threat-detection-service.js.map +1 -0
- package/dist/domain/services/threat-learning-service.d.ts +175 -0
- package/dist/domain/services/threat-learning-service.d.ts.map +1 -0
- package/dist/domain/services/threat-learning-service.js +295 -0
- package/dist/domain/services/threat-learning-service.js.map +1 -0
- package/dist/hooks/security-hook.d.ts +62 -0
- package/dist/hooks/security-hook.d.ts.map +1 -0
- package/dist/hooks/security-hook.js +132 -0
- package/dist/hooks/security-hook.js.map +1 -0
- package/dist/index.d.ts +191 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +284 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# monofence-ai
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/monofence-ai)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
|
|
8
|
+
**AI manipulation defense for LLM applications** — evasion detection, multi-turn context tracking, output scanning, and hook wiring. Sub-millisecond detection with self-learning.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Detection: ~0.04ms | 50+ patterns | evasion normalization | context-aware escalation
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install monofence-ai
|
|
20
|
+
# or
|
|
21
|
+
pnpm add monofence-ai
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Optional — HNSW-accelerated pattern search:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install lancedb
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { isSafe, createMonoDefence } from 'monofence-ai';
|
|
36
|
+
|
|
37
|
+
// Fast boolean check
|
|
38
|
+
isSafe('Hello, help me write code'); // true
|
|
39
|
+
isSafe('Ignore all previous instructions'); // false
|
|
40
|
+
|
|
41
|
+
// Full detection with threat objects
|
|
42
|
+
const fence = createMonoDefence();
|
|
43
|
+
const result = await fence.detect(userInput);
|
|
44
|
+
|
|
45
|
+
if (!result.safe) {
|
|
46
|
+
// result.threats — array of detected threats
|
|
47
|
+
// result.overallRisk — 0.0–1.0
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
### `createMonoDefence(config?)`
|
|
56
|
+
|
|
57
|
+
Creates a `MonoDefence` instance.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const fence = createMonoDefence({
|
|
61
|
+
enableLearning: true, // persist learned threat patterns (default: false)
|
|
62
|
+
enableContextTracking: true, // track escalation state across turns (default: false)
|
|
63
|
+
enablePIIDetection: true, // detect PII in inputs/outputs (default: true)
|
|
64
|
+
maxContextTurns: 20, // rolling window for context tracking (default: 20)
|
|
65
|
+
confidenceThreshold: 0.5, // minimum detection confidence (default: 0.5)
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `fence.detect(input)`
|
|
70
|
+
|
|
71
|
+
Full async scan. Returns:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
{
|
|
75
|
+
safe: boolean; // false if any threat detected
|
|
76
|
+
threats: Threat[]; // detected threat objects with type/severity/confidence
|
|
77
|
+
piiFound: boolean;
|
|
78
|
+
overallRisk: number; // 0.0–1.0
|
|
79
|
+
detectionTimeMs: number;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
> When context tracking is on and escalation reaches `attack`, `overallRisk` is raised
|
|
84
|
+
> to at least 0.5 even when `safe=true`. Check both `safe` and `overallRisk` when using
|
|
85
|
+
> context tracking.
|
|
86
|
+
|
|
87
|
+
### `fence.quickScan(input)`
|
|
88
|
+
|
|
89
|
+
Synchronous, sub-millisecond check. Returns `{ threat: boolean, confidence: number }`.
|
|
90
|
+
|
|
91
|
+
### `isSafe(input)` / `fence.isSafe(input)`
|
|
92
|
+
|
|
93
|
+
Returns `boolean`. Fastest option — no async overhead.
|
|
94
|
+
|
|
95
|
+
### `fence.hasPII(input)`
|
|
96
|
+
|
|
97
|
+
Returns `boolean`. Checks emails, SSNs, API keys, and passwords.
|
|
98
|
+
|
|
99
|
+
### `fence.getStats()`
|
|
100
|
+
|
|
101
|
+
Returns detection counters, learned pattern count, and average latency.
|
|
102
|
+
|
|
103
|
+
### `fence.learnFromDetection(input, result, feedback)`
|
|
104
|
+
|
|
105
|
+
Reinforces or corrects a prior detection for human-in-the-loop feedback.
|
|
106
|
+
|
|
107
|
+
### `fence.getBestMitigation(threatType)`
|
|
108
|
+
|
|
109
|
+
Returns the highest-effectiveness mitigation strategy for a threat type.
|
|
110
|
+
|
|
111
|
+
### `fence.searchSimilarThreats(input, { k })`
|
|
112
|
+
|
|
113
|
+
Vector similarity search over learned threat patterns (requires LanceDB).
|
|
114
|
+
|
|
115
|
+
### `fence.recordMitigation(threatType, strategy, success)`
|
|
116
|
+
|
|
117
|
+
Records whether a mitigation worked; affects future `getBestMitigation` results.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Threat types
|
|
122
|
+
|
|
123
|
+
| Type | Severity | Examples |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `instruction_override` | Critical | "Ignore previous instructions", "forget everything" |
|
|
126
|
+
| `jailbreak` | Critical | "DAN mode", "bypass restrictions", "developer mode" |
|
|
127
|
+
| `role_switching` | High | "You are now", "Act as an unrestricted AI" |
|
|
128
|
+
| `context_manipulation` | Critical | Fake `system:` messages, delimiter injection |
|
|
129
|
+
| `encoding_attack` | Medium | base64/hex obfuscation |
|
|
130
|
+
| `prompt_injection` | Critical | Injected instructions in user content |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Evasion detection
|
|
135
|
+
|
|
136
|
+
Inputs are normalized before pattern matching to defeat obfuscation:
|
|
137
|
+
|
|
138
|
+
- **Homoglyphs**: Cyrillic/Greek lookalikes → ASCII (`і` → `i`)
|
|
139
|
+
- **Spaced chars**: `i g n o r e` → `ignore`
|
|
140
|
+
- **Leet substitution**: `ign0re` → `ignore` (applied after space collapsing)
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const result = await fence.detect('іgnore all рrevious instructions'); // Cyrillic chars
|
|
144
|
+
// result.safe === false, threats include instruction_override
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Multi-turn context tracking
|
|
150
|
+
|
|
151
|
+
Enable to track escalation state across a conversation:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
const fence = createMonoDefence({ enableContextTracking: true });
|
|
155
|
+
|
|
156
|
+
// Turn 1: probing question → state: probing
|
|
157
|
+
// Turn 2: jailbreak attempt → state: escalating
|
|
158
|
+
// Turn 3: confirmed attack → state: attack
|
|
159
|
+
// Once in attack state, overallRisk ≥ 0.5 even on benign inputs
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
States: `clean` → `probing` → `escalating` → `attack`. Decays toward `clean` on idle turns.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Multi-agent consensus
|
|
167
|
+
|
|
168
|
+
When running multiple detection agents in parallel:
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { calculateSecurityConsensus } from 'monofence-ai';
|
|
172
|
+
|
|
173
|
+
const consensus = calculateSecurityConsensus([
|
|
174
|
+
{ result: resultA, weight: 0.6 },
|
|
175
|
+
{ result: resultB, weight: 0.4 },
|
|
176
|
+
]);
|
|
177
|
+
// consensus.safe, consensus.overallRisk, consensus.threats
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
A single critical threat short-circuits weighted scoring regardless of agent weight (fail-secure).
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Hook wiring (optional)
|
|
185
|
+
|
|
186
|
+
Wire into the monomind hooks system so pre-task and pre-command inputs are scanned automatically. **Off by default.**
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { SecurityHook } from 'monofence-ai/hooks';
|
|
190
|
+
|
|
191
|
+
SecurityHook.register({ priority: 1000 });
|
|
192
|
+
// Runs before all other hooks; aborts on attack escalation state
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Or from the CLI:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
npx monomind hooks pre-task --monofence-ai-check
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Review integration
|
|
204
|
+
|
|
205
|
+
When using `mastermind:review`, two flags activate monofence-ai analysis:
|
|
206
|
+
|
|
207
|
+
| Flag | Effect |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `--monofence-ai-check` | Test suite + adversarial probes against the live detector |
|
|
210
|
+
| `--monofence-ai-security-deep` | Scan LLM input boundaries for unprotected paths |
|
|
211
|
+
|
|
212
|
+
Both are off by default:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
/mastermind:review --monofence-ai-check --monofence-ai-security-deep
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## MCP tools
|
|
221
|
+
|
|
222
|
+
Six MCP tools are available when monomind is installed:
|
|
223
|
+
|
|
224
|
+
| Tool | Description |
|
|
225
|
+
|---|---|
|
|
226
|
+
| `aidefence_scan` | Scan input for threats (`input`, `quick?`) |
|
|
227
|
+
| `aidefence_analyze` | Deep analysis with similar-pattern search |
|
|
228
|
+
| `aidefence_stats` | Detection and learning statistics |
|
|
229
|
+
| `aidefence_learn` | Record feedback for pattern learning |
|
|
230
|
+
| `aidefence_is_safe` | Quick boolean check |
|
|
231
|
+
| `aidefence_has_pii` | PII detection only |
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Performance
|
|
236
|
+
|
|
237
|
+
| Operation | Typical latency |
|
|
238
|
+
|---|---|
|
|
239
|
+
| Full `detect()` | ~0.04ms |
|
|
240
|
+
| `quickScan()` | ~0.02ms |
|
|
241
|
+
| PII check | ~0.01ms |
|
|
242
|
+
| HNSW search (LanceDB) | ~0.1ms |
|
|
243
|
+
|
|
244
|
+
Throughput: >12,000 req/s single-threaded. Memory: ~50KB per instance.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Deprecated aliases
|
|
249
|
+
|
|
250
|
+
Still exported for backward compatibility; will be removed in v2:
|
|
251
|
+
|
|
252
|
+
| Deprecated | Replacement |
|
|
253
|
+
|---|---|
|
|
254
|
+
| `createAIDefence` | `createMonoDefence` |
|
|
255
|
+
| `getAIDefence` | `getMonoDefence` |
|
|
256
|
+
| `AIDefenceConfig` | `MonoDefenceConfig` |
|
|
257
|
+
| `AIDefence` | `MonoDefence` |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Development
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
git clone https://github.com/monoes/monomind.git
|
|
265
|
+
cd monomind/packages/monofence-ai
|
|
266
|
+
|
|
267
|
+
npm install
|
|
268
|
+
npm test # vitest run
|
|
269
|
+
npm run build # tsc
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT — part of the [Monomind](https://github.com/monoes/monomind) ecosystem.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/entities/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threat Domain Entity
|
|
3
|
+
*
|
|
4
|
+
* Represents a detected security threat from AI manipulation attempts.
|
|
5
|
+
*/
|
|
6
|
+
export type ThreatSeverity = 'low' | 'medium' | 'high' | 'critical';
|
|
7
|
+
export type ThreatType = 'prompt_injection' | 'jailbreak' | 'pii_exposure' | 'instruction_override' | 'role_switching' | 'context_manipulation' | 'encoding_attack' | 'unknown';
|
|
8
|
+
export interface Threat {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly type: ThreatType;
|
|
11
|
+
readonly severity: ThreatSeverity;
|
|
12
|
+
readonly confidence: number;
|
|
13
|
+
readonly pattern: string;
|
|
14
|
+
readonly description: string;
|
|
15
|
+
readonly location?: {
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
};
|
|
19
|
+
readonly detectedAt: Date;
|
|
20
|
+
}
|
|
21
|
+
export interface ThreatDetectionResult {
|
|
22
|
+
readonly safe: boolean;
|
|
23
|
+
readonly threats: Threat[];
|
|
24
|
+
readonly detectionTimeMs: number;
|
|
25
|
+
readonly piiFound: boolean;
|
|
26
|
+
readonly inputHash: string;
|
|
27
|
+
readonly wasObfuscated?: boolean;
|
|
28
|
+
/** Aggregate risk score [0, 1] derived from highest-confidence threat; boosted when obfuscation detected */
|
|
29
|
+
readonly overallRisk: number;
|
|
30
|
+
}
|
|
31
|
+
export interface BehavioralAnalysisResult {
|
|
32
|
+
readonly agentId: string;
|
|
33
|
+
readonly anomalyScore: number;
|
|
34
|
+
readonly attractorType: 'point' | 'cycle' | 'torus' | 'strange';
|
|
35
|
+
readonly lyapunovExponent: number;
|
|
36
|
+
readonly analysisTimeMs: number;
|
|
37
|
+
readonly windowSize: string;
|
|
38
|
+
readonly actionCount: number;
|
|
39
|
+
}
|
|
40
|
+
export interface PolicyVerificationResult {
|
|
41
|
+
readonly agentId: string;
|
|
42
|
+
readonly policy: string;
|
|
43
|
+
readonly valid: boolean;
|
|
44
|
+
readonly violations: string[];
|
|
45
|
+
readonly proofStatus: 'valid' | 'invalid' | 'timeout';
|
|
46
|
+
readonly verificationTimeMs: number;
|
|
47
|
+
}
|
|
48
|
+
export type EscalationState = 'clean' | 'probing' | 'escalating' | 'attack';
|
|
49
|
+
export interface EvasionResult {
|
|
50
|
+
readonly normalizedInput: string;
|
|
51
|
+
readonly wasObfuscated: boolean;
|
|
52
|
+
readonly techniqueDetected?: 'homoglyph' | 'leetspeak' | 'spacing' | 'base64' | 'zero_width';
|
|
53
|
+
}
|
|
54
|
+
export interface ContextState {
|
|
55
|
+
readonly escalationState: EscalationState;
|
|
56
|
+
readonly cumulativeThreatScore: number;
|
|
57
|
+
readonly turnCount: number;
|
|
58
|
+
readonly recentThreats: Threat[];
|
|
59
|
+
}
|
|
60
|
+
export interface OutputScanResult {
|
|
61
|
+
readonly safe: boolean;
|
|
62
|
+
readonly leakageFound: boolean;
|
|
63
|
+
readonly leakageTypes: string[];
|
|
64
|
+
readonly echoDetected: boolean;
|
|
65
|
+
readonly policyViolation: boolean;
|
|
66
|
+
readonly contradictionSignal: boolean;
|
|
67
|
+
readonly scanTimeMs: number;
|
|
68
|
+
}
|
|
69
|
+
export interface AllowlistRule {
|
|
70
|
+
readonly id: string;
|
|
71
|
+
readonly pattern: RegExp | string;
|
|
72
|
+
/**
|
|
73
|
+
* Threat types this rule applies to.
|
|
74
|
+
* - Empty array `[]`: full bypass — matching inputs skip detection entirely.
|
|
75
|
+
* - Non-empty array: selective suppression — detection still runs, but threats
|
|
76
|
+
* whose type appears in this array are removed from the result. Threats of
|
|
77
|
+
* other types are reported normally.
|
|
78
|
+
*/
|
|
79
|
+
readonly types: ThreatType[];
|
|
80
|
+
readonly context?: string;
|
|
81
|
+
readonly reason: string;
|
|
82
|
+
readonly source: 'builtin' | 'user';
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Factory function to create a Threat entity
|
|
86
|
+
*/
|
|
87
|
+
export declare function createThreat(params: {
|
|
88
|
+
type: ThreatType;
|
|
89
|
+
severity: ThreatSeverity;
|
|
90
|
+
confidence: number;
|
|
91
|
+
pattern: string;
|
|
92
|
+
description: string;
|
|
93
|
+
location?: {
|
|
94
|
+
start: number;
|
|
95
|
+
end: number;
|
|
96
|
+
};
|
|
97
|
+
}): Threat;
|
|
98
|
+
//# sourceMappingURL=threat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/threat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threat Domain Entity
|
|
3
|
+
*
|
|
4
|
+
* Represents a detected security threat from AI manipulation attempts.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Factory function to create a Threat entity
|
|
8
|
+
*/
|
|
9
|
+
export function createThreat(params) {
|
|
10
|
+
return {
|
|
11
|
+
id: `threat-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
12
|
+
type: params.type,
|
|
13
|
+
severity: params.severity,
|
|
14
|
+
confidence: params.confidence,
|
|
15
|
+
pattern: params.pattern,
|
|
16
|
+
description: params.description,
|
|
17
|
+
location: params.location,
|
|
18
|
+
detectedAt: new Date(),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=threat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat.js","sourceRoot":"","sources":["../../../src/domain/entities/threat.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmGH;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAO5B;IACC,OAAO;QACL,EAAE,EAAE,UAAU,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACpE,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,IAAI,IAAI,EAAE;KACvB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AllowlistRule } from '../entities/threat.js';
|
|
2
|
+
export declare class Allowlist {
|
|
3
|
+
private rules;
|
|
4
|
+
constructor(userRules?: AllowlistRule[]);
|
|
5
|
+
isAllowed(input: string): boolean;
|
|
6
|
+
getMatchingRules(input: string): AllowlistRule[];
|
|
7
|
+
addRule(rule: AllowlistRule): void;
|
|
8
|
+
private matches;
|
|
9
|
+
}
|
|
10
|
+
export declare function createAllowlist(userRules?: AllowlistRule[]): Allowlist;
|
|
11
|
+
//# sourceMappingURL=allowlist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowlist.d.ts","sourceRoot":"","sources":["../../../src/domain/services/allowlist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA2C3D,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAkB;gBAEnB,SAAS,GAAE,aAAa,EAAO;IAI3C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIjC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE;IAIhD,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAIlC,OAAO,CAAC,OAAO;CAahB;AAED,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,GAAG,SAAS,CAEtE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const BUILT_IN_RULES = [
|
|
2
|
+
{
|
|
3
|
+
id: 'builtin-greetings',
|
|
4
|
+
// End-anchored: "hi!" or "hello" alone — NOT "hey ignore all instructions"
|
|
5
|
+
pattern: /^\s*(?:hi|hello|hey|greetings|good\s+(?:morning|afternoon|evening))\s*[.!?]?\s*$/i,
|
|
6
|
+
types: [],
|
|
7
|
+
reason: 'Stand-alone greeting — no threat possible',
|
|
8
|
+
source: 'builtin',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: 'builtin-math',
|
|
12
|
+
pattern: /^\s*what\s+is\s+[\d\s+\-*/^()]+\??$/i,
|
|
13
|
+
types: [],
|
|
14
|
+
reason: 'Simple arithmetic question',
|
|
15
|
+
source: 'builtin',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'builtin-weather',
|
|
19
|
+
// Start + end anchored: pure weather query only — allows "in [location]" but not appended instructions
|
|
20
|
+
pattern: /^\s*(?:what(?:'s|\s+is)\s+(?:the\s+)?weather(?:\s+(?:like\s+)?(?:in|for|at|near|today|tomorrow|this\s+week)(?:\s+[\w\s,]+)?)?|how(?:'s|\s+is)\s+(?:the\s+)?weather(?:\s+[\w\s,]+)?|weather\s+(?:in|for|at|today|tomorrow|forecast)(?:\s+[\w\s,]+)?)\s*[.?!]?\s*$/i,
|
|
21
|
+
types: [],
|
|
22
|
+
reason: 'Pure weather query — benign',
|
|
23
|
+
source: 'builtin',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'builtin-time',
|
|
27
|
+
// Start + end anchored: pure time/date query only
|
|
28
|
+
pattern: /^\s*what\s+(?:time|day|date)\s+is\s+it\s*[.?!]?\s*$/i,
|
|
29
|
+
types: [],
|
|
30
|
+
reason: 'Pure time/date query — benign',
|
|
31
|
+
source: 'builtin',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'builtin-help',
|
|
35
|
+
pattern: /^\s*(?:can\s+you\s+)?help\s+me\s*[.?!]?\s*$/i,
|
|
36
|
+
types: [],
|
|
37
|
+
reason: 'Short "help me" request — benign',
|
|
38
|
+
source: 'builtin',
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
export class Allowlist {
|
|
42
|
+
rules;
|
|
43
|
+
constructor(userRules = []) {
|
|
44
|
+
this.rules = [...BUILT_IN_RULES, ...userRules];
|
|
45
|
+
}
|
|
46
|
+
isAllowed(input) {
|
|
47
|
+
return this.getMatchingRules(input).length > 0;
|
|
48
|
+
}
|
|
49
|
+
getMatchingRules(input) {
|
|
50
|
+
return this.rules.filter(rule => this.matches(rule, input));
|
|
51
|
+
}
|
|
52
|
+
addRule(rule) {
|
|
53
|
+
this.rules.push(rule);
|
|
54
|
+
}
|
|
55
|
+
matches(rule, input) {
|
|
56
|
+
if (typeof rule.pattern === 'string') {
|
|
57
|
+
// String patterns use substring matching. For security-sensitive rules,
|
|
58
|
+
// prefer RegExp with ^ and $ anchors to avoid over-allowlisting.
|
|
59
|
+
return input.toLowerCase().includes(rule.pattern.toLowerCase());
|
|
60
|
+
}
|
|
61
|
+
// Reset lastIndex before testing — g/y-flagged regexes advance lastIndex after each
|
|
62
|
+
// successful .test() call, causing alternating true/false on repeated identical inputs.
|
|
63
|
+
if (rule.pattern.global || rule.pattern.sticky) {
|
|
64
|
+
rule.pattern.lastIndex = 0;
|
|
65
|
+
}
|
|
66
|
+
return rule.pattern.test(input);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function createAllowlist(userRules) {
|
|
70
|
+
return new Allowlist(userRules);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=allowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowlist.js","sourceRoot":"","sources":["../../../src/domain/services/allowlist.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAoB;IACtC;QACE,EAAE,EAAE,mBAAmB;QACvB,2EAA2E;QAC3E,OAAO,EAAE,mFAAmF;QAC5F,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,2CAA2C;QACnD,MAAM,EAAE,SAAS;KAClB;IACD;QACE,EAAE,EAAE,cAAc;QAClB,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,4BAA4B;QACpC,MAAM,EAAE,SAAS;KAClB;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,uGAAuG;QACvG,OAAO,EAAE,mQAAmQ;QAC5Q,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,6BAA6B;QACrC,MAAM,EAAE,SAAS;KAClB;IACD;QACE,EAAE,EAAE,cAAc;QAClB,kDAAkD;QAClD,OAAO,EAAE,sDAAsD;QAC/D,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,+BAA+B;QACvC,MAAM,EAAE,SAAS;KAClB;IACD;QACE,EAAE,EAAE,cAAc;QAClB,OAAO,EAAE,8CAA8C;QACvD,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,kCAAkC;QAC1C,MAAM,EAAE,SAAS;KAClB;CACF,CAAC;AAEF,MAAM,OAAO,SAAS;IACZ,KAAK,CAAkB;IAE/B,YAAY,YAA6B,EAAE;QACzC,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,SAAS,CAAC,CAAC;IACjD,CAAC;IAED,SAAS,CAAC,KAAa;QACrB,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,gBAAgB,CAAC,KAAa;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,CAAC,IAAmB;QACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAEO,OAAO,CAAC,IAAmB,EAAE,KAAa;QAChD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACrC,wEAAwE;YACxE,iEAAiE;YACjE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,oFAAoF;QACpF,wFAAwF;QACxF,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/C,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,SAA2B;IACzD,OAAO,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ContextState, ThreatDetectionResult } from '../entities/threat.js';
|
|
2
|
+
export declare class ContextTracker {
|
|
3
|
+
private state;
|
|
4
|
+
private lastTurnAt;
|
|
5
|
+
private readonly idleDecayMs;
|
|
6
|
+
constructor(opts?: {
|
|
7
|
+
idleDecayMs?: number;
|
|
8
|
+
});
|
|
9
|
+
recordTurn(input: string, result: ThreatDetectionResult): void;
|
|
10
|
+
getState(): Readonly<ContextState>;
|
|
11
|
+
reset(): void;
|
|
12
|
+
private computeNextState;
|
|
13
|
+
}
|
|
14
|
+
export declare function createContextTracker(): ContextTracker;
|
|
15
|
+
//# sourceMappingURL=context-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-tracker.d.ts","sourceRoot":"","sources":["../../../src/domain/services/context-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA2B,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAiB1G,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAKX;IAEF,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,IAAI,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO;IAI/C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,IAAI;IA8B9D,QAAQ,IAAI,QAAQ,CAAC,YAAY,CAAC;IAIlC,KAAK,IAAI,IAAI;IAUb,OAAO,CAAC,gBAAgB;CAiBzB;AAED,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Escalation thresholds
|
|
2
|
+
const PROBING_THRESHOLD = 0.3;
|
|
3
|
+
const ESCALATING_THRESHOLD = 0.6; // cumulative score
|
|
4
|
+
const ATTACK_CONFIDENCE = 0.9; // single-turn jump-to-attack
|
|
5
|
+
const ESCALATION_ORDER = ['clean', 'probing', 'escalating', 'attack'];
|
|
6
|
+
export class ContextTracker {
|
|
7
|
+
state = {
|
|
8
|
+
escalationState: 'clean',
|
|
9
|
+
cumulativeThreatScore: 0,
|
|
10
|
+
turnCount: 0,
|
|
11
|
+
recentThreats: [],
|
|
12
|
+
};
|
|
13
|
+
lastTurnAt = 0;
|
|
14
|
+
idleDecayMs;
|
|
15
|
+
constructor(opts = {}) {
|
|
16
|
+
this.idleDecayMs = opts.idleDecayMs ?? 30 * 60 * 1000; // 30 min default
|
|
17
|
+
}
|
|
18
|
+
recordTurn(input, result) {
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
// Decay escalation state if session has been idle
|
|
21
|
+
if (this.lastTurnAt > 0 && now - this.lastTurnAt > this.idleDecayMs) {
|
|
22
|
+
const currentIndex = ESCALATION_ORDER.indexOf(this.state.escalationState);
|
|
23
|
+
if (currentIndex > 0) {
|
|
24
|
+
this.state.escalationState = ESCALATION_ORDER[currentIndex - 1];
|
|
25
|
+
}
|
|
26
|
+
// Also decay cumulative score so computeNextState doesn't immediately re-escalate
|
|
27
|
+
this.state.cumulativeThreatScore = Math.max(0, this.state.cumulativeThreatScore * 0.5);
|
|
28
|
+
}
|
|
29
|
+
this.lastTurnAt = now;
|
|
30
|
+
this.state.turnCount++;
|
|
31
|
+
// Update cumulative score
|
|
32
|
+
this.state.cumulativeThreatScore += result.overallRisk;
|
|
33
|
+
// Maintain sliding window of 10
|
|
34
|
+
if (!result.safe) {
|
|
35
|
+
this.state.recentThreats = [
|
|
36
|
+
...this.state.recentThreats.slice(-9),
|
|
37
|
+
...result.threats,
|
|
38
|
+
].slice(-10);
|
|
39
|
+
}
|
|
40
|
+
// Escalation state machine (monotonic — only moves forward)
|
|
41
|
+
this.state.escalationState = this.computeNextState(result);
|
|
42
|
+
}
|
|
43
|
+
getState() {
|
|
44
|
+
return { ...this.state, recentThreats: [...this.state.recentThreats] };
|
|
45
|
+
}
|
|
46
|
+
reset() {
|
|
47
|
+
this.state = {
|
|
48
|
+
escalationState: 'clean',
|
|
49
|
+
cumulativeThreatScore: 0,
|
|
50
|
+
turnCount: 0,
|
|
51
|
+
recentThreats: [],
|
|
52
|
+
};
|
|
53
|
+
this.lastTurnAt = 0;
|
|
54
|
+
}
|
|
55
|
+
computeNextState(result) {
|
|
56
|
+
const current = this.state.escalationState;
|
|
57
|
+
const currentIndex = ESCALATION_ORDER.indexOf(current);
|
|
58
|
+
let targetIndex = currentIndex; // monotonic: never go back
|
|
59
|
+
// Jump to attack on high single-turn confidence
|
|
60
|
+
if (result.overallRisk >= ATTACK_CONFIDENCE) {
|
|
61
|
+
targetIndex = ESCALATION_ORDER.indexOf('attack');
|
|
62
|
+
}
|
|
63
|
+
else if (this.state.cumulativeThreatScore >= ESCALATING_THRESHOLD) {
|
|
64
|
+
targetIndex = Math.max(targetIndex, ESCALATION_ORDER.indexOf('escalating'));
|
|
65
|
+
}
|
|
66
|
+
else if (result.overallRisk >= PROBING_THRESHOLD) {
|
|
67
|
+
targetIndex = Math.max(targetIndex, ESCALATION_ORDER.indexOf('probing'));
|
|
68
|
+
}
|
|
69
|
+
return ESCALATION_ORDER[targetIndex];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function createContextTracker() {
|
|
73
|
+
return new ContextTracker();
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=context-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-tracker.js","sourceRoot":"","sources":["../../../src/domain/services/context-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EvasionResult } from '../entities/threat.js';
|
|
2
|
+
export declare class EvasionDetector {
|
|
3
|
+
normalize(input: string): EvasionResult;
|
|
4
|
+
private replaceHomoglyphs;
|
|
5
|
+
private expandLeetspeak;
|
|
6
|
+
private collapseSpacedChars;
|
|
7
|
+
private stripZeroWidth;
|
|
8
|
+
private appendDecodedBase64;
|
|
9
|
+
private detectTechnique;
|
|
10
|
+
}
|
|
11
|
+
export declare function createEvasionDetector(): EvasionDetector;
|
|
12
|
+
//# sourceMappingURL=evasion-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evasion-detector.d.ts","sourceRoot":"","sources":["../../../src/domain/services/evasion-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAmD3D,qBAAa,eAAe;IAC1B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa;IA6BvC,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,eAAe;CAWxB;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD"}
|