@dotsetlabs/tollgate 0.2.0 → 0.2.2
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 +76 -2
- package/dist/analyzers/credential-detector.d.ts +62 -0
- package/dist/analyzers/credential-detector.d.ts.map +1 -0
- package/dist/analyzers/credential-detector.js +384 -0
- package/dist/analyzers/credential-detector.js.map +1 -0
- package/dist/analyzers/enhanced-output-validator.d.ts +68 -0
- package/dist/analyzers/enhanced-output-validator.d.ts.map +1 -0
- package/dist/analyzers/enhanced-output-validator.js +341 -0
- package/dist/analyzers/enhanced-output-validator.js.map +1 -0
- package/dist/analyzers/filesystem.d.ts +5 -0
- package/dist/analyzers/filesystem.d.ts.map +1 -1
- package/dist/analyzers/filesystem.js +95 -1
- package/dist/analyzers/filesystem.js.map +1 -1
- package/dist/analyzers/index.d.ts +4 -0
- package/dist/analyzers/index.d.ts.map +1 -1
- package/dist/analyzers/index.js +5 -0
- package/dist/analyzers/index.js.map +1 -1
- package/dist/analyzers/output-validation-types.d.ts +179 -0
- package/dist/analyzers/output-validation-types.d.ts.map +1 -0
- package/dist/analyzers/output-validation-types.js +43 -0
- package/dist/analyzers/output-validation-types.js.map +1 -0
- package/dist/analyzers/pii-detector.d.ts +61 -0
- package/dist/analyzers/pii-detector.d.ts.map +1 -0
- package/dist/analyzers/pii-detector.js +289 -0
- package/dist/analyzers/pii-detector.js.map +1 -0
- package/dist/audit/logger.d.ts.map +1 -1
- package/dist/audit/logger.js +3 -3
- package/dist/audit/logger.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@dotsetlabs/tollgate)
|
|
6
6
|
[](LICENSE)
|
|
7
|
-
[](https://github.com/dotsetlabs/tollgate/actions/workflows/ci.yml)
|
|
8
8
|
|
|
9
9
|
Add security to any MCP server in one command. No Docker, no Kubernetes, no cloud accounts — just `npm install`.
|
|
10
10
|
|
|
@@ -168,6 +168,80 @@ Add to your `claude_desktop_config.json`:
|
|
|
168
168
|
|
|
169
169
|
---
|
|
170
170
|
|
|
171
|
+
## Real-World Threats
|
|
172
|
+
|
|
173
|
+
MCP security isn't theoretical. In 2025, documented attacks demonstrated why tool-level control matters:
|
|
174
|
+
|
|
175
|
+
- **CVE-2025-54135 (CurXecute)** — Prompt injection led to arbitrary code execution via MCP config manipulation (CVSS 8.6)
|
|
176
|
+
- **Malicious MCP server attacks** — Supply chain attacks where fake MCP servers secretly BCC'd emails to attackers
|
|
177
|
+
- **RAG system exploitation** — A Fortune 500 breach where prompt injection led to database exfiltration and regulatory fines
|
|
178
|
+
- **43% of MCP servers** tested in security research contained command injection vulnerabilities
|
|
179
|
+
|
|
180
|
+
Tollgate sits between your AI assistant and MCP servers, analyzing every tool call before execution.
|
|
181
|
+
|
|
182
|
+
**Threat Model:** AI agents with tool access are a new attack surface. When Claude or Cursor can execute SQL queries, write files, or make API calls, a single prompt injection can become code execution. Tollgate provides the authorization layer that MCP doesn't include.
|
|
183
|
+
|
|
184
|
+
## Privacy & Trust
|
|
185
|
+
|
|
186
|
+
Tollgate runs entirely on your machine. No exceptions.
|
|
187
|
+
|
|
188
|
+
**What Tollgate does:**
|
|
189
|
+
- Proxies MCP tool calls through a local policy engine
|
|
190
|
+
- Stores audit logs locally in SQLite (`~/.tollgate/audit.db`)
|
|
191
|
+
- Prompts for approval when needed (terminal or web UI)
|
|
192
|
+
|
|
193
|
+
**What Tollgate does NOT do:**
|
|
194
|
+
- No network connections to Dotset Labs or anywhere else
|
|
195
|
+
- No telemetry, analytics, or usage tracking
|
|
196
|
+
- No cloud dependencies or external services
|
|
197
|
+
- No data ever leaves your machine
|
|
198
|
+
|
|
199
|
+
**Verify it yourself:**
|
|
200
|
+
```bash
|
|
201
|
+
# Check for network connections while Tollgate runs
|
|
202
|
+
lsof -i -P | grep tollgate
|
|
203
|
+
# Output should only show local connections to your MCP servers
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Source code: [github.com/dotsetlabs/tollgate](https://github.com/dotsetlabs/tollgate)
|
|
207
|
+
|
|
208
|
+
See [SECURITY.md](SECURITY.md) for our security policy and responsible disclosure process.
|
|
209
|
+
|
|
210
|
+
## Platform Support
|
|
211
|
+
|
|
212
|
+
| Platform | Status | Notes |
|
|
213
|
+
|----------|--------|-------|
|
|
214
|
+
| macOS (arm64/amd64) | ✅ Tested | Primary development platform |
|
|
215
|
+
| Linux (amd64/arm64) | ✅ Tested | Full functionality |
|
|
216
|
+
| Windows | ⚠️ Experimental | Should work, less testing coverage |
|
|
217
|
+
|
|
218
|
+
**Requirements:**
|
|
219
|
+
- Node.js 20.0.0 or later
|
|
220
|
+
- npm 9.0.0 or later
|
|
221
|
+
|
|
222
|
+
## Project Status
|
|
223
|
+
|
|
224
|
+
Tollgate is at **v0.2.x** — the core features are stable and production-ready.
|
|
225
|
+
|
|
226
|
+
**What's solid:**
|
|
227
|
+
- Policy engine with smart content analyzers
|
|
228
|
+
- SQL, shell, filesystem, HTTP, and prompt injection detection
|
|
229
|
+
- Session-based approval memory
|
|
230
|
+
- Audit logging and export (JSON, CSV, CEF)
|
|
231
|
+
- 25 test files covering core functionality
|
|
232
|
+
|
|
233
|
+
**What's coming:**
|
|
234
|
+
- Team dashboards (exploring)
|
|
235
|
+
- Additional analyzers for GraphQL, Redis
|
|
236
|
+
- Improved Windows testing
|
|
237
|
+
|
|
238
|
+
**How to help:**
|
|
239
|
+
- Report analyzer bypasses or false positives via [GitHub Issues](https://github.com/dotsetlabs/tollgate/issues)
|
|
240
|
+
- Contribute custom analyzers
|
|
241
|
+
- Test on Windows and report issues
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
171
245
|
## Performance
|
|
172
246
|
|
|
173
247
|
Tollgate adds minimal overhead to MCP operations:
|
|
@@ -906,7 +980,7 @@ await bridge.start();
|
|
|
906
980
|
|-------|------|-------|
|
|
907
981
|
| **Pre-install** | [Hardpoint](https://github.com/dotsetlabs/hardpoint) | Scan dev environment for threats |
|
|
908
982
|
| **At runtime** | **Tollgate** | Control what MCP servers can do |
|
|
909
|
-
| **
|
|
983
|
+
| **Detection** | [Deadfall](https://github.com/dotsetlabs/deadfall) | Detect AI compromise with cognitive honeypots |
|
|
910
984
|
|
|
911
985
|
---
|
|
912
986
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects credentials and secrets in tool output:
|
|
5
|
+
* - API Keys (OpenAI, Anthropic, AWS, GCP, GitHub, etc.)
|
|
6
|
+
* - Database connection strings
|
|
7
|
+
* - Private keys (SSH, PGP, SSL)
|
|
8
|
+
* - Access tokens
|
|
9
|
+
* - Passwords in common patterns
|
|
10
|
+
*
|
|
11
|
+
* @module analyzers/credential-detector
|
|
12
|
+
*/
|
|
13
|
+
import type { OutputValidationMatch, OutputValidationAction, OutputValidationSeverity } from './output-validation-types.js';
|
|
14
|
+
interface CredentialPattern {
|
|
15
|
+
name: string;
|
|
16
|
+
pattern: RegExp;
|
|
17
|
+
severity: OutputValidationSeverity;
|
|
18
|
+
replacement: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Built-in credential patterns.
|
|
23
|
+
*/
|
|
24
|
+
declare const CREDENTIAL_PATTERNS: CredentialPattern[];
|
|
25
|
+
/**
|
|
26
|
+
* Detects credentials and secrets in text content.
|
|
27
|
+
*/
|
|
28
|
+
export declare class CredentialDetector {
|
|
29
|
+
private enabled;
|
|
30
|
+
private defaultAction;
|
|
31
|
+
private customPatterns;
|
|
32
|
+
constructor(enabled?: boolean, defaultAction?: OutputValidationAction);
|
|
33
|
+
/**
|
|
34
|
+
* Enable or disable the detector.
|
|
35
|
+
*/
|
|
36
|
+
setEnabled(enabled: boolean): void;
|
|
37
|
+
/**
|
|
38
|
+
* Add a custom pattern.
|
|
39
|
+
*/
|
|
40
|
+
addPattern(pattern: CredentialPattern): void;
|
|
41
|
+
/**
|
|
42
|
+
* Detect all credential matches in content.
|
|
43
|
+
*/
|
|
44
|
+
detect(content: string): OutputValidationMatch[];
|
|
45
|
+
/**
|
|
46
|
+
* Remove overlapping matches, keeping the more specific one.
|
|
47
|
+
*/
|
|
48
|
+
private deduplicateMatches;
|
|
49
|
+
/**
|
|
50
|
+
* Compare severity levels.
|
|
51
|
+
*/
|
|
52
|
+
private compareSeverity;
|
|
53
|
+
/**
|
|
54
|
+
* Apply redactions to content.
|
|
55
|
+
*/
|
|
56
|
+
applyRedactions(content: string, matches: OutputValidationMatch[]): string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Export patterns for testing.
|
|
60
|
+
*/
|
|
61
|
+
export { CREDENTIAL_PATTERNS };
|
|
62
|
+
//# sourceMappingURL=credential-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/credential-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACR,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EAC3B,MAAM,8BAA8B,CAAC;AAOtC,UAAU,iBAAiB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,QAAA,MAAM,mBAAmB,EAAE,iBAAiB,EAqP3C,CAAC;AAMF;;GAEG;AACH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,cAAc,CAAsB;gBAGxC,OAAO,GAAE,OAAc,EACvB,aAAa,GAAE,sBAAiC;IAOpD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAI5C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE;IAwChD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE,GAAG,MAAM;CAoB7E;AAED;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects credentials and secrets in tool output:
|
|
5
|
+
* - API Keys (OpenAI, Anthropic, AWS, GCP, GitHub, etc.)
|
|
6
|
+
* - Database connection strings
|
|
7
|
+
* - Private keys (SSH, PGP, SSL)
|
|
8
|
+
* - Access tokens
|
|
9
|
+
* - Passwords in common patterns
|
|
10
|
+
*
|
|
11
|
+
* @module analyzers/credential-detector
|
|
12
|
+
*/
|
|
13
|
+
import { OUTPUT_VALIDATION_CATEGORIES } from './output-validation-types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Built-in credential patterns.
|
|
16
|
+
*/
|
|
17
|
+
const CREDENTIAL_PATTERNS = [
|
|
18
|
+
// -------------------------------------------------------------------------
|
|
19
|
+
// AI Provider API Keys
|
|
20
|
+
// -------------------------------------------------------------------------
|
|
21
|
+
{
|
|
22
|
+
name: 'OpenAI API Key',
|
|
23
|
+
pattern: /\bsk-[a-zA-Z0-9]{32,}(?:\b|$)/g,
|
|
24
|
+
severity: 'critical',
|
|
25
|
+
replacement: '[OPENAI_KEY REDACTED]',
|
|
26
|
+
description: 'OpenAI API key',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'Anthropic API Key',
|
|
30
|
+
pattern: /\bsk-ant-[a-zA-Z0-9-]{32,}(?:\b|$)/g,
|
|
31
|
+
severity: 'critical',
|
|
32
|
+
replacement: '[ANTHROPIC_KEY REDACTED]',
|
|
33
|
+
description: 'Anthropic API key',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Google API Key',
|
|
37
|
+
pattern: /\bAIza[0-9A-Za-z\-_]{31,}\b/g,
|
|
38
|
+
severity: 'critical',
|
|
39
|
+
replacement: '[GOOGLE_KEY REDACTED]',
|
|
40
|
+
description: 'Google Cloud API key',
|
|
41
|
+
},
|
|
42
|
+
// -------------------------------------------------------------------------
|
|
43
|
+
// GitHub Tokens
|
|
44
|
+
// -------------------------------------------------------------------------
|
|
45
|
+
{
|
|
46
|
+
name: 'GitHub Personal Access Token',
|
|
47
|
+
pattern: /\bghp_[a-zA-Z0-9]{30,}\b/g,
|
|
48
|
+
severity: 'critical',
|
|
49
|
+
replacement: '[GITHUB_PAT REDACTED]',
|
|
50
|
+
description: 'GitHub personal access token (classic)',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'GitHub Fine-grained Token',
|
|
54
|
+
pattern: /\bgithub_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}\b/g,
|
|
55
|
+
severity: 'critical',
|
|
56
|
+
replacement: '[GITHUB_PAT REDACTED]',
|
|
57
|
+
description: 'GitHub fine-grained personal access token',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'GitHub App Token',
|
|
61
|
+
pattern: /\bghs_[a-zA-Z0-9]{30,}\b/g,
|
|
62
|
+
severity: 'critical',
|
|
63
|
+
replacement: '[GITHUB_APP REDACTED]',
|
|
64
|
+
description: 'GitHub App installation token',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'GitHub OAuth Token',
|
|
68
|
+
pattern: /\bgho_[a-zA-Z0-9]{30,}\b/g,
|
|
69
|
+
severity: 'critical',
|
|
70
|
+
replacement: '[GITHUB_OAUTH REDACTED]',
|
|
71
|
+
description: 'GitHub OAuth token',
|
|
72
|
+
},
|
|
73
|
+
// -------------------------------------------------------------------------
|
|
74
|
+
// AWS Credentials
|
|
75
|
+
// -------------------------------------------------------------------------
|
|
76
|
+
{
|
|
77
|
+
name: 'AWS Access Key ID',
|
|
78
|
+
pattern: /\bAKIA[0-9A-Z]{16}\b/g,
|
|
79
|
+
severity: 'critical',
|
|
80
|
+
replacement: '[AWS_KEY REDACTED]',
|
|
81
|
+
description: 'AWS access key ID',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'AWS Secret Access Key',
|
|
85
|
+
pattern: /\baws_secret_access_key\s*[=:]\s*["']?([A-Za-z0-9/+=]{40})["']?\b/gi,
|
|
86
|
+
severity: 'critical',
|
|
87
|
+
replacement: '[AWS_SECRET REDACTED]',
|
|
88
|
+
description: 'AWS secret access key in config',
|
|
89
|
+
},
|
|
90
|
+
// -------------------------------------------------------------------------
|
|
91
|
+
// Private Keys
|
|
92
|
+
// -------------------------------------------------------------------------
|
|
93
|
+
{
|
|
94
|
+
name: 'RSA Private Key',
|
|
95
|
+
pattern: /-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,
|
|
96
|
+
severity: 'critical',
|
|
97
|
+
replacement: '[PRIVATE_KEY REDACTED]',
|
|
98
|
+
description: 'Private key in PEM format',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'PGP Private Key',
|
|
102
|
+
pattern: /-----BEGIN PGP PRIVATE KEY BLOCK-----[\s\S]*?-----END PGP PRIVATE KEY BLOCK-----/g,
|
|
103
|
+
severity: 'critical',
|
|
104
|
+
replacement: '[PGP_PRIVATE_KEY REDACTED]',
|
|
105
|
+
description: 'PGP private key block',
|
|
106
|
+
},
|
|
107
|
+
// -------------------------------------------------------------------------
|
|
108
|
+
// Database Connection Strings
|
|
109
|
+
// -------------------------------------------------------------------------
|
|
110
|
+
{
|
|
111
|
+
name: 'MongoDB Connection String',
|
|
112
|
+
pattern: /mongodb(\+srv)?:\/\/[^:]+:[^@]+@[^\s'"]+/gi,
|
|
113
|
+
severity: 'critical',
|
|
114
|
+
replacement: '[MONGODB_URI REDACTED]',
|
|
115
|
+
description: 'MongoDB connection string with credentials',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'PostgreSQL Connection String',
|
|
119
|
+
pattern: /postgres(ql)?:\/\/[^:]+:[^@]+@[^\s'"]+/gi,
|
|
120
|
+
severity: 'critical',
|
|
121
|
+
replacement: '[POSTGRES_URI REDACTED]',
|
|
122
|
+
description: 'PostgreSQL connection string with credentials',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'MySQL Connection String',
|
|
126
|
+
pattern: /mysql:\/\/[^:]+:[^@]+@[^\s'"]+/gi,
|
|
127
|
+
severity: 'critical',
|
|
128
|
+
replacement: '[MYSQL_URI REDACTED]',
|
|
129
|
+
description: 'MySQL connection string with credentials',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'Redis Connection String',
|
|
133
|
+
pattern: /redis:\/\/[^:]*:[^@]+@[^\s'"]+/gi,
|
|
134
|
+
severity: 'critical',
|
|
135
|
+
replacement: '[REDIS_URI REDACTED]',
|
|
136
|
+
description: 'Redis connection string with credentials',
|
|
137
|
+
},
|
|
138
|
+
// -------------------------------------------------------------------------
|
|
139
|
+
// Generic Secrets
|
|
140
|
+
// -------------------------------------------------------------------------
|
|
141
|
+
{
|
|
142
|
+
name: 'Bearer Token',
|
|
143
|
+
pattern: /\bBearer\s+[a-zA-Z0-9\-._~+/]+=*\b/gi,
|
|
144
|
+
severity: 'high',
|
|
145
|
+
replacement: '[BEARER_TOKEN REDACTED]',
|
|
146
|
+
description: 'Bearer authentication token',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'Basic Auth',
|
|
150
|
+
pattern: /\bBasic\s+[a-zA-Z0-9+/]+=*\b/gi,
|
|
151
|
+
severity: 'high',
|
|
152
|
+
replacement: '[BASIC_AUTH REDACTED]',
|
|
153
|
+
description: 'Basic authentication header',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'Password Assignment',
|
|
157
|
+
pattern: /\bpassword\s*[=:]\s*["']([^"']{8,})["']/gi,
|
|
158
|
+
severity: 'high',
|
|
159
|
+
replacement: 'password=[PASSWORD REDACTED]',
|
|
160
|
+
description: 'Password in assignment',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: 'API Key Assignment',
|
|
164
|
+
pattern: /\bapi[_-]?key\s*[=:]\s*["']([^"']{16,})["']/gi,
|
|
165
|
+
severity: 'high',
|
|
166
|
+
replacement: 'api_key=[API_KEY REDACTED]',
|
|
167
|
+
description: 'API key in assignment',
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'Secret Assignment',
|
|
171
|
+
pattern: /\bsecret[_-]?key?\s*[=:]\s*["']([^"']{16,})["']/gi,
|
|
172
|
+
severity: 'high',
|
|
173
|
+
replacement: 'secret=[SECRET REDACTED]',
|
|
174
|
+
description: 'Secret in assignment',
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'Token Assignment',
|
|
178
|
+
pattern: /\b(?:access_?)?token\s*[=:]\s*["']([^"']{20,})["']/gi,
|
|
179
|
+
severity: 'high',
|
|
180
|
+
replacement: 'token=[TOKEN REDACTED]',
|
|
181
|
+
description: 'Token in assignment',
|
|
182
|
+
},
|
|
183
|
+
// -------------------------------------------------------------------------
|
|
184
|
+
// Other Service Keys
|
|
185
|
+
// -------------------------------------------------------------------------
|
|
186
|
+
{
|
|
187
|
+
name: 'Stripe API Key',
|
|
188
|
+
pattern: /\bsk_(?:live|test)_[a-zA-Z0-9]{24,}\b/g,
|
|
189
|
+
severity: 'critical',
|
|
190
|
+
replacement: '[STRIPE_KEY REDACTED]',
|
|
191
|
+
description: 'Stripe API secret key',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: 'Stripe Publishable Key',
|
|
195
|
+
pattern: /\bpk_(?:live|test)_[a-zA-Z0-9]{24,}\b/g,
|
|
196
|
+
severity: 'medium',
|
|
197
|
+
replacement: '[STRIPE_PK REDACTED]',
|
|
198
|
+
description: 'Stripe publishable key',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'Slack Token',
|
|
202
|
+
pattern: /\bxox[baprs]-[0-9]{9,12}-[0-9]{9,12}(?:-[a-zA-Z0-9]+)?\b/g,
|
|
203
|
+
severity: 'critical',
|
|
204
|
+
replacement: '[SLACK_TOKEN REDACTED]',
|
|
205
|
+
description: 'Slack API token',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: 'Slack Webhook',
|
|
209
|
+
pattern: /https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[a-zA-Z0-9]+/g,
|
|
210
|
+
severity: 'high',
|
|
211
|
+
replacement: '[SLACK_WEBHOOK REDACTED]',
|
|
212
|
+
description: 'Slack incoming webhook URL',
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: 'Twilio API Key',
|
|
216
|
+
pattern: /\bSK[a-z0-9]{32}\b/g,
|
|
217
|
+
severity: 'critical',
|
|
218
|
+
replacement: '[TWILIO_KEY REDACTED]',
|
|
219
|
+
description: 'Twilio API key',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: 'SendGrid API Key',
|
|
223
|
+
pattern: /\bSG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}\b/g,
|
|
224
|
+
severity: 'critical',
|
|
225
|
+
replacement: '[SENDGRID_KEY REDACTED]',
|
|
226
|
+
description: 'SendGrid API key',
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: 'Mailchimp API Key',
|
|
230
|
+
pattern: /\b[a-f0-9]{32}-us[0-9]{1,2}\b/g,
|
|
231
|
+
severity: 'high',
|
|
232
|
+
replacement: '[MAILCHIMP_KEY REDACTED]',
|
|
233
|
+
description: 'Mailchimp API key',
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: 'npm Token',
|
|
237
|
+
pattern: /\bnpm_[a-zA-Z0-9]{36}\b/g,
|
|
238
|
+
severity: 'critical',
|
|
239
|
+
replacement: '[NPM_TOKEN REDACTED]',
|
|
240
|
+
description: 'npm authentication token',
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: 'PyPI Token',
|
|
244
|
+
pattern: /\bpypi-[A-Za-z0-9_-]{32,}\b/g,
|
|
245
|
+
severity: 'critical',
|
|
246
|
+
replacement: '[PYPI_TOKEN REDACTED]',
|
|
247
|
+
description: 'PyPI API token',
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: 'Discord Token',
|
|
251
|
+
pattern: /\b[MN][A-Za-z\d]{23,}\.[\w-]{6}\.[\w-]{27}\b/g,
|
|
252
|
+
severity: 'critical',
|
|
253
|
+
replacement: '[DISCORD_TOKEN REDACTED]',
|
|
254
|
+
description: 'Discord bot token',
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Credential Detector Class
|
|
259
|
+
// ============================================================================
|
|
260
|
+
/**
|
|
261
|
+
* Detects credentials and secrets in text content.
|
|
262
|
+
*/
|
|
263
|
+
export class CredentialDetector {
|
|
264
|
+
enabled;
|
|
265
|
+
defaultAction;
|
|
266
|
+
customPatterns;
|
|
267
|
+
constructor(enabled = true, defaultAction = 'redact') {
|
|
268
|
+
this.enabled = enabled;
|
|
269
|
+
this.defaultAction = defaultAction;
|
|
270
|
+
this.customPatterns = [];
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Enable or disable the detector.
|
|
274
|
+
*/
|
|
275
|
+
setEnabled(enabled) {
|
|
276
|
+
this.enabled = enabled;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Add a custom pattern.
|
|
280
|
+
*/
|
|
281
|
+
addPattern(pattern) {
|
|
282
|
+
this.customPatterns.push(pattern);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Detect all credential matches in content.
|
|
286
|
+
*/
|
|
287
|
+
detect(content) {
|
|
288
|
+
if (!this.enabled) {
|
|
289
|
+
return [];
|
|
290
|
+
}
|
|
291
|
+
const matches = [];
|
|
292
|
+
const allPatterns = [...CREDENTIAL_PATTERNS, ...this.customPatterns];
|
|
293
|
+
for (const credPattern of allPatterns) {
|
|
294
|
+
// Reset regex lastIndex
|
|
295
|
+
credPattern.pattern.lastIndex = 0;
|
|
296
|
+
let match;
|
|
297
|
+
while ((match = credPattern.pattern.exec(content)) !== null) {
|
|
298
|
+
const matchedText = match[0];
|
|
299
|
+
// Skip very short matches that might be false positives
|
|
300
|
+
if (matchedText.length < 10) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
matches.push({
|
|
304
|
+
pattern: credPattern.name,
|
|
305
|
+
category: OUTPUT_VALIDATION_CATEGORIES.CREDENTIAL,
|
|
306
|
+
action: this.defaultAction,
|
|
307
|
+
matchedContent: matchedText,
|
|
308
|
+
replacement: credPattern.replacement,
|
|
309
|
+
position: {
|
|
310
|
+
start: match.index,
|
|
311
|
+
end: match.index + matchedText.length,
|
|
312
|
+
},
|
|
313
|
+
severity: credPattern.severity,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Sort by position and remove duplicates (overlapping matches)
|
|
318
|
+
return this.deduplicateMatches(matches);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Remove overlapping matches, keeping the more specific one.
|
|
322
|
+
*/
|
|
323
|
+
deduplicateMatches(matches) {
|
|
324
|
+
if (matches.length <= 1) {
|
|
325
|
+
return matches;
|
|
326
|
+
}
|
|
327
|
+
// Sort by position
|
|
328
|
+
matches.sort((a, b) => a.position.start - b.position.start);
|
|
329
|
+
const result = [];
|
|
330
|
+
let lastEnd = -1;
|
|
331
|
+
for (const match of matches) {
|
|
332
|
+
if (match.position.start >= lastEnd) {
|
|
333
|
+
result.push(match);
|
|
334
|
+
lastEnd = match.position.end;
|
|
335
|
+
}
|
|
336
|
+
else if (match.position.end > lastEnd) {
|
|
337
|
+
// Overlapping match that extends further - check severity
|
|
338
|
+
const existing = result[result.length - 1];
|
|
339
|
+
if (this.compareSeverity(match.severity, existing.severity) > 0) {
|
|
340
|
+
result[result.length - 1] = match;
|
|
341
|
+
lastEnd = match.position.end;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return result;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Compare severity levels.
|
|
349
|
+
*/
|
|
350
|
+
compareSeverity(a, b) {
|
|
351
|
+
const order = {
|
|
352
|
+
low: 0,
|
|
353
|
+
medium: 1,
|
|
354
|
+
high: 2,
|
|
355
|
+
critical: 3,
|
|
356
|
+
};
|
|
357
|
+
return order[a] - order[b];
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Apply redactions to content.
|
|
361
|
+
*/
|
|
362
|
+
applyRedactions(content, matches) {
|
|
363
|
+
if (matches.length === 0) {
|
|
364
|
+
return content;
|
|
365
|
+
}
|
|
366
|
+
// Filter to only redact actions, sort in reverse order
|
|
367
|
+
const redactMatches = matches
|
|
368
|
+
.filter(m => m.action === 'redact')
|
|
369
|
+
.sort((a, b) => b.position.start - a.position.start);
|
|
370
|
+
let result = content;
|
|
371
|
+
for (const match of redactMatches) {
|
|
372
|
+
result =
|
|
373
|
+
result.slice(0, match.position.start) +
|
|
374
|
+
(match.replacement || '[REDACTED]') +
|
|
375
|
+
result.slice(match.position.end);
|
|
376
|
+
}
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Export patterns for testing.
|
|
382
|
+
*/
|
|
383
|
+
export { CREDENTIAL_PATTERNS };
|
|
384
|
+
//# sourceMappingURL=credential-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-detector.js","sourceRoot":"","sources":["../../src/analyzers/credential-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Output Validator
|
|
3
|
+
*
|
|
4
|
+
* A configurable output validation system that scans tool responses for:
|
|
5
|
+
* - PII (SSN, credit cards, phone numbers, etc.)
|
|
6
|
+
* - Credentials (API keys, tokens, connection strings)
|
|
7
|
+
* - Prompt injection attempts
|
|
8
|
+
* - Data exfiltration markers
|
|
9
|
+
*
|
|
10
|
+
* Supports multiple actions: block, redact, warn, log.
|
|
11
|
+
*
|
|
12
|
+
* @module analyzers/enhanced-output-validator
|
|
13
|
+
*/
|
|
14
|
+
import type { OutputValidationConfig, OutputValidationResult } from './output-validation-types.js';
|
|
15
|
+
import type { AnalysisResult, ContentAnalyzer, AnalyzerContext } from './types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Enhanced Output Validator that combines PII detection, credential detection,
|
|
18
|
+
* and injection detection into a single configurable system.
|
|
19
|
+
*/
|
|
20
|
+
export declare class EnhancedOutputValidator implements ContentAnalyzer {
|
|
21
|
+
readonly name = "enhanced-output-validator";
|
|
22
|
+
private config;
|
|
23
|
+
private piiDetector;
|
|
24
|
+
private credentialDetector;
|
|
25
|
+
private customPatterns;
|
|
26
|
+
constructor(config?: Partial<OutputValidationConfig>);
|
|
27
|
+
/**
|
|
28
|
+
* Configure the validator with new settings.
|
|
29
|
+
*/
|
|
30
|
+
configure(config: Partial<OutputValidationConfig>): void;
|
|
31
|
+
/**
|
|
32
|
+
* Compile custom patterns from config.
|
|
33
|
+
*/
|
|
34
|
+
private compileCustomPatterns;
|
|
35
|
+
/**
|
|
36
|
+
* Legacy analyze method for compatibility with ContentAnalyzer interface.
|
|
37
|
+
*/
|
|
38
|
+
analyze(content: string, context?: AnalyzerContext): AnalysisResult;
|
|
39
|
+
/**
|
|
40
|
+
* Validate content and optionally transform (redact) it.
|
|
41
|
+
*/
|
|
42
|
+
validateAndTransform(content: string, _context?: AnalyzerContext): OutputValidationResult;
|
|
43
|
+
/**
|
|
44
|
+
* Detect custom patterns from config.
|
|
45
|
+
*/
|
|
46
|
+
private detectCustomPatterns;
|
|
47
|
+
/**
|
|
48
|
+
* Detect injection patterns.
|
|
49
|
+
*/
|
|
50
|
+
private detectInjection;
|
|
51
|
+
/**
|
|
52
|
+
* Deduplicate overlapping matches.
|
|
53
|
+
*/
|
|
54
|
+
private deduplicateMatches;
|
|
55
|
+
/**
|
|
56
|
+
* Determine if a new match should replace an existing overlapping one.
|
|
57
|
+
*/
|
|
58
|
+
private shouldReplace;
|
|
59
|
+
/**
|
|
60
|
+
* Apply redactions to content.
|
|
61
|
+
*/
|
|
62
|
+
private applyRedactions;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create an enhanced output validator instance.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createEnhancedOutputValidator(config?: Partial<OutputValidationConfig>): EnhancedOutputValidator;
|
|
68
|
+
//# sourceMappingURL=enhanced-output-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enhanced-output-validator.d.ts","sourceRoot":"","sources":["../../src/analyzers/enhanced-output-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACR,sBAAsB,EACtB,sBAAsB,EAGzB,MAAM,8BAA8B,CAAC;AAOtC,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMnF;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC3D,QAAQ,CAAC,IAAI,+BAA+B;IAE5C,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAsB;gBAEhC,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC;IAapD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI;IAOxD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc;IA0CnE;;OAEG;IACH,oBAAoB,CAChB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,eAAe,GAC3B,sBAAsB;IA6EzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA+B5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAkFvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,OAAO,CAAC,eAAe;CAmB1B;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,GACzC,uBAAuB,CAEzB"}
|