palaryn 0.1.0 → 0.3.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 +243 -588
- package/dist/sdk/typescript/src/client.js +2 -2
- package/dist/sdk/typescript/src/client.js.map +1 -1
- package/dist/src/anomaly/detector.d.ts +7 -4
- package/dist/src/anomaly/detector.d.ts.map +1 -1
- package/dist/src/anomaly/detector.js +22 -12
- package/dist/src/anomaly/detector.js.map +1 -1
- package/dist/src/audit/logger.d.ts +10 -0
- package/dist/src/audit/logger.d.ts.map +1 -1
- package/dist/src/audit/logger.js +52 -38
- package/dist/src/audit/logger.js.map +1 -1
- package/dist/src/auth/routes.d.ts.map +1 -1
- package/dist/src/auth/routes.js +35 -0
- package/dist/src/auth/routes.js.map +1 -1
- package/dist/src/budget/manager.d.ts +5 -0
- package/dist/src/budget/manager.d.ts.map +1 -1
- package/dist/src/budget/manager.js +32 -0
- package/dist/src/budget/manager.js.map +1 -1
- package/dist/src/budget/model-pricing.d.ts +20 -0
- package/dist/src/budget/model-pricing.d.ts.map +1 -0
- package/dist/src/budget/model-pricing.js +107 -0
- package/dist/src/budget/model-pricing.js.map +1 -0
- package/dist/src/budget/usage-extractor.d.ts +3 -1
- package/dist/src/budget/usage-extractor.d.ts.map +1 -1
- package/dist/src/budget/usage-extractor.js +47 -3
- package/dist/src/budget/usage-extractor.js.map +1 -1
- package/dist/src/config/defaults.d.ts.map +1 -1
- package/dist/src/config/defaults.js +65 -13
- package/dist/src/config/defaults.js.map +1 -1
- package/dist/src/dlp/tool-patterns.d.ts +7 -0
- package/dist/src/dlp/tool-patterns.d.ts.map +1 -0
- package/dist/src/dlp/tool-patterns.js +34 -0
- package/dist/src/dlp/tool-patterns.js.map +1 -0
- package/dist/src/executor/filesystem-executor.d.ts +28 -0
- package/dist/src/executor/filesystem-executor.d.ts.map +1 -0
- package/dist/src/executor/filesystem-executor.js +192 -0
- package/dist/src/executor/filesystem-executor.js.map +1 -0
- package/dist/src/executor/http-executor.d.ts.map +1 -1
- package/dist/src/executor/http-executor.js +22 -2
- package/dist/src/executor/http-executor.js.map +1 -1
- package/dist/src/executor/index.d.ts +4 -0
- package/dist/src/executor/index.d.ts.map +1 -1
- package/dist/src/executor/index.js +9 -1
- package/dist/src/executor/index.js.map +1 -1
- package/dist/src/executor/shell-executor.d.ts +22 -0
- package/dist/src/executor/shell-executor.d.ts.map +1 -0
- package/dist/src/executor/shell-executor.js +119 -0
- package/dist/src/executor/shell-executor.js.map +1 -0
- package/dist/src/executor/sql-executor.d.ts +29 -0
- package/dist/src/executor/sql-executor.d.ts.map +1 -0
- package/dist/src/executor/sql-executor.js +114 -0
- package/dist/src/executor/sql-executor.js.map +1 -0
- package/dist/src/executor/websocket-executor.d.ts +26 -0
- package/dist/src/executor/websocket-executor.d.ts.map +1 -0
- package/dist/src/executor/websocket-executor.js +205 -0
- package/dist/src/executor/websocket-executor.js.map +1 -0
- package/dist/src/interceptor/index.d.ts +2 -0
- package/dist/src/interceptor/index.d.ts.map +1 -0
- package/dist/src/interceptor/index.js +6 -0
- package/dist/src/interceptor/index.js.map +1 -0
- package/dist/src/interceptor/provider-interceptor.d.ts +36 -0
- package/dist/src/interceptor/provider-interceptor.d.ts.map +1 -0
- package/dist/src/interceptor/provider-interceptor.js +302 -0
- package/dist/src/interceptor/provider-interceptor.js.map +1 -0
- package/dist/src/mcp/auth-verifier.d.ts.map +1 -1
- package/dist/src/mcp/auth-verifier.js +3 -2
- package/dist/src/mcp/auth-verifier.js.map +1 -1
- package/dist/src/mcp/bridge.d.ts +14 -10
- package/dist/src/mcp/bridge.d.ts.map +1 -1
- package/dist/src/mcp/bridge.js +51 -227
- package/dist/src/mcp/bridge.js.map +1 -1
- package/dist/src/mcp/http-transport.d.ts +2 -0
- package/dist/src/mcp/http-transport.d.ts.map +1 -1
- package/dist/src/mcp/http-transport.js +117 -66
- package/dist/src/mcp/http-transport.js.map +1 -1
- package/dist/src/mcp/internal-auth.d.ts +13 -0
- package/dist/src/mcp/internal-auth.d.ts.map +1 -0
- package/dist/src/mcp/internal-auth.js +12 -0
- package/dist/src/mcp/internal-auth.js.map +1 -0
- package/dist/src/mcp/tool-definitions.d.ts +41 -0
- package/dist/src/mcp/tool-definitions.d.ts.map +1 -0
- package/dist/src/mcp/tool-definitions.js +491 -0
- package/dist/src/mcp/tool-definitions.js.map +1 -0
- package/dist/src/middleware/auth.js.map +1 -1
- package/dist/src/middleware/session.js.map +1 -1
- package/dist/src/middleware/validate.d.ts +8 -0
- package/dist/src/middleware/validate.d.ts.map +1 -1
- package/dist/src/middleware/validate.js +45 -0
- package/dist/src/middleware/validate.js.map +1 -1
- package/dist/src/policy/engine.d.ts +4 -0
- package/dist/src/policy/engine.d.ts.map +1 -1
- package/dist/src/policy/engine.js +117 -0
- package/dist/src/policy/engine.js.map +1 -1
- package/dist/src/saas/routes.d.ts.map +1 -1
- package/dist/src/saas/routes.js +355 -22
- package/dist/src/saas/routes.js.map +1 -1
- package/dist/src/server/app.d.ts.map +1 -1
- package/dist/src/server/app.js +24 -3
- package/dist/src/server/app.js.map +1 -1
- package/dist/src/server/gateway.d.ts.map +1 -1
- package/dist/src/server/gateway.js +17 -0
- package/dist/src/server/gateway.js.map +1 -1
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +18 -0
- package/dist/src/server/index.js.map +1 -1
- package/dist/src/storage/interfaces.d.ts +14 -3
- package/dist/src/storage/interfaces.d.ts.map +1 -1
- package/dist/src/storage/memory.d.ts +2 -0
- package/dist/src/storage/memory.d.ts.map +1 -1
- package/dist/src/storage/memory.js +6 -0
- package/dist/src/storage/memory.js.map +1 -1
- package/dist/src/storage/postgres.d.ts +5 -0
- package/dist/src/storage/postgres.d.ts.map +1 -1
- package/dist/src/storage/postgres.js +16 -0
- package/dist/src/storage/postgres.js.map +1 -1
- package/dist/src/storage/redis.d.ts +10 -0
- package/dist/src/storage/redis.d.ts.map +1 -1
- package/dist/src/storage/redis.js +65 -0
- package/dist/src/storage/redis.js.map +1 -1
- package/dist/src/types/budget.d.ts +4 -0
- package/dist/src/types/budget.d.ts.map +1 -1
- package/dist/src/types/config.d.ts +58 -0
- package/dist/src/types/config.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +1 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/policy.d.ts +11 -1
- package/dist/src/types/policy.d.ts.map +1 -1
- package/dist/src/types/tool-result.d.ts +11 -0
- package/dist/src/types/tool-result.d.ts.map +1 -1
- package/dist/tests/unit/app-routes.test.d.ts +2 -0
- package/dist/tests/unit/app-routes.test.d.ts.map +1 -0
- package/dist/tests/unit/app-routes.test.js +715 -0
- package/dist/tests/unit/app-routes.test.js.map +1 -0
- package/dist/tests/unit/audit-logger.test.js +105 -0
- package/dist/tests/unit/audit-logger.test.js.map +1 -1
- package/dist/tests/unit/auth-providers.test.d.ts +2 -0
- package/dist/tests/unit/auth-providers.test.d.ts.map +1 -0
- package/dist/tests/unit/auth-providers.test.js +279 -0
- package/dist/tests/unit/auth-providers.test.js.map +1 -0
- package/dist/tests/unit/auth-routes-extended.test.d.ts +2 -0
- package/dist/tests/unit/auth-routes-extended.test.d.ts.map +1 -0
- package/dist/tests/unit/auth-routes-extended.test.js +993 -0
- package/dist/tests/unit/auth-routes-extended.test.js.map +1 -0
- package/dist/tests/unit/auth-verifier.test.d.ts +2 -0
- package/dist/tests/unit/auth-verifier.test.d.ts.map +1 -0
- package/dist/tests/unit/auth-verifier.test.js +505 -0
- package/dist/tests/unit/auth-verifier.test.js.map +1 -0
- package/dist/tests/unit/billing-routes.test.d.ts +2 -0
- package/dist/tests/unit/billing-routes.test.d.ts.map +1 -0
- package/dist/tests/unit/billing-routes.test.js +432 -0
- package/dist/tests/unit/billing-routes.test.js.map +1 -0
- package/dist/tests/unit/config-defaults.test.d.ts +2 -0
- package/dist/tests/unit/config-defaults.test.d.ts.map +1 -0
- package/dist/tests/unit/config-defaults.test.js +119 -0
- package/dist/tests/unit/config-defaults.test.js.map +1 -0
- package/dist/tests/unit/defaults.test.js +0 -10
- package/dist/tests/unit/defaults.test.js.map +1 -1
- package/dist/tests/unit/filesystem-executor.test.d.ts +2 -0
- package/dist/tests/unit/filesystem-executor.test.d.ts.map +1 -0
- package/dist/tests/unit/filesystem-executor.test.js +280 -0
- package/dist/tests/unit/filesystem-executor.test.js.map +1 -0
- package/dist/tests/unit/gateway-branches.test.d.ts +2 -0
- package/dist/tests/unit/gateway-branches.test.d.ts.map +1 -0
- package/dist/tests/unit/gateway-branches.test.js +1039 -0
- package/dist/tests/unit/gateway-branches.test.js.map +1 -0
- package/dist/tests/unit/http-executor-branches.test.d.ts +2 -0
- package/dist/tests/unit/http-executor-branches.test.d.ts.map +1 -0
- package/dist/tests/unit/http-executor-branches.test.js +495 -0
- package/dist/tests/unit/http-executor-branches.test.js.map +1 -0
- package/dist/tests/unit/logger.test.d.ts +2 -0
- package/dist/tests/unit/logger.test.d.ts.map +1 -0
- package/dist/tests/unit/logger.test.js +97 -0
- package/dist/tests/unit/logger.test.js.map +1 -0
- package/dist/tests/unit/mcp-internal-auth.test.d.ts +2 -0
- package/dist/tests/unit/mcp-internal-auth.test.d.ts.map +1 -0
- package/dist/tests/unit/mcp-internal-auth.test.js +445 -0
- package/dist/tests/unit/mcp-internal-auth.test.js.map +1 -0
- package/dist/tests/unit/metrics.test.js +102 -0
- package/dist/tests/unit/metrics.test.js.map +1 -1
- package/dist/tests/unit/model-pricing.test.d.ts +2 -0
- package/dist/tests/unit/model-pricing.test.d.ts.map +1 -0
- package/dist/tests/unit/model-pricing.test.js +87 -0
- package/dist/tests/unit/model-pricing.test.js.map +1 -0
- package/dist/tests/unit/oauth-stores.test.d.ts +2 -0
- package/dist/tests/unit/oauth-stores.test.d.ts.map +1 -0
- package/dist/tests/unit/oauth-stores.test.js +260 -0
- package/dist/tests/unit/oauth-stores.test.js.map +1 -0
- package/dist/tests/unit/policy-engine.test.js +466 -0
- package/dist/tests/unit/policy-engine.test.js.map +1 -1
- package/dist/tests/unit/provider-interceptor.test.d.ts +2 -0
- package/dist/tests/unit/provider-interceptor.test.d.ts.map +1 -0
- package/dist/tests/unit/provider-interceptor.test.js +472 -0
- package/dist/tests/unit/provider-interceptor.test.js.map +1 -0
- package/dist/tests/unit/saas-routes-branches.test.d.ts +2 -0
- package/dist/tests/unit/saas-routes-branches.test.d.ts.map +1 -0
- package/dist/tests/unit/saas-routes-branches.test.js +2165 -0
- package/dist/tests/unit/saas-routes-branches.test.js.map +1 -0
- package/dist/tests/unit/saas-routes-crud.test.d.ts +2 -0
- package/dist/tests/unit/saas-routes-crud.test.d.ts.map +1 -0
- package/dist/tests/unit/saas-routes-crud.test.js +332 -0
- package/dist/tests/unit/saas-routes-crud.test.js.map +1 -0
- package/dist/tests/unit/saas-routes-data.test.d.ts +2 -0
- package/dist/tests/unit/saas-routes-data.test.d.ts.map +1 -0
- package/dist/tests/unit/saas-routes-data.test.js +405 -0
- package/dist/tests/unit/saas-routes-data.test.js.map +1 -0
- package/dist/tests/unit/saas-routes.test.js +3 -3
- package/dist/tests/unit/saas-routes.test.js.map +1 -1
- package/dist/tests/unit/shell-executor.test.d.ts +2 -0
- package/dist/tests/unit/shell-executor.test.d.ts.map +1 -0
- package/dist/tests/unit/shell-executor.test.js +145 -0
- package/dist/tests/unit/shell-executor.test.js.map +1 -0
- package/dist/tests/unit/sql-executor.test.d.ts +2 -0
- package/dist/tests/unit/sql-executor.test.d.ts.map +1 -0
- package/dist/tests/unit/sql-executor.test.js +177 -0
- package/dist/tests/unit/sql-executor.test.js.map +1 -0
- package/dist/tests/unit/stream-proxy.test.d.ts +2 -0
- package/dist/tests/unit/stream-proxy.test.d.ts.map +1 -0
- package/dist/tests/unit/stream-proxy.test.js +147 -0
- package/dist/tests/unit/stream-proxy.test.js.map +1 -0
- package/dist/tests/unit/tool-definitions.test.d.ts +2 -0
- package/dist/tests/unit/tool-definitions.test.d.ts.map +1 -0
- package/dist/tests/unit/tool-definitions.test.js +184 -0
- package/dist/tests/unit/tool-definitions.test.js.map +1 -0
- package/dist/tests/unit/usage-extractor.test.js +140 -0
- package/dist/tests/unit/usage-extractor.test.js.map +1 -1
- package/dist/tests/unit/webhook-handler.test.d.ts +2 -0
- package/dist/tests/unit/webhook-handler.test.d.ts.map +1 -0
- package/dist/tests/unit/webhook-handler.test.js +453 -0
- package/dist/tests/unit/webhook-handler.test.js.map +1 -0
- package/dist/tests/unit/webhook-routes.test.d.ts +2 -0
- package/dist/tests/unit/webhook-routes.test.d.ts.map +1 -0
- package/dist/tests/unit/webhook-routes.test.js +69 -0
- package/dist/tests/unit/webhook-routes.test.js.map +1 -0
- package/dist/tests/unit/websocket-executor.test.d.ts +2 -0
- package/dist/tests/unit/websocket-executor.test.d.ts.map +1 -0
- package/dist/tests/unit/websocket-executor.test.js +121 -0
- package/dist/tests/unit/websocket-executor.test.js.map +1 -0
- package/package.json +8 -2
- package/policy-packs/demo_fail.yaml +41 -0
- package/policy-packs/full_tools.yaml +136 -0
- package/src/admin/index.ts +1 -0
- package/src/admin/routes.ts +509 -0
- package/src/admin/templates.ts +572 -0
- package/src/anomaly/detector.ts +730 -0
- package/src/anomaly/index.ts +1 -0
- package/src/approval/manager.ts +569 -0
- package/src/approval/webhook.ts +133 -0
- package/src/audit/logger.ts +490 -0
- package/src/auth/index.ts +5 -0
- package/src/auth/password.ts +21 -0
- package/src/auth/pkce.ts +22 -0
- package/src/auth/providers.ts +208 -0
- package/src/auth/routes.ts +561 -0
- package/src/auth/session.ts +84 -0
- package/src/billing/index.ts +6 -0
- package/src/billing/plan-enforcer.ts +135 -0
- package/src/billing/routes.ts +229 -0
- package/src/billing/stripe-client.ts +58 -0
- package/src/billing/webhook-handler.ts +182 -0
- package/src/billing/webhook-routes.ts +28 -0
- package/src/budget/manager.ts +679 -0
- package/src/budget/model-pricing.ts +119 -0
- package/src/budget/usage-extractor.ts +214 -0
- package/src/cli.ts +91 -0
- package/src/config/defaults.ts +261 -0
- package/src/config/validate.ts +88 -0
- package/src/dlp/composite-scanner.ts +213 -0
- package/src/dlp/index.ts +9 -0
- package/src/dlp/interfaces.ts +34 -0
- package/src/dlp/patterns.ts +30 -0
- package/src/dlp/prompt-injection-backend.ts +181 -0
- package/src/dlp/prompt-injection-patterns.ts +302 -0
- package/src/dlp/regex-backend.ts +181 -0
- package/src/dlp/scanner.ts +502 -0
- package/src/dlp/text-normalizer.ts +225 -0
- package/src/dlp/tool-patterns.ts +35 -0
- package/src/dlp/trufflehog-backend.ts +190 -0
- package/src/executor/filesystem-executor.ts +196 -0
- package/src/executor/http-executor.ts +349 -0
- package/src/executor/index.ts +9 -0
- package/src/executor/interfaces.ts +11 -0
- package/src/executor/noop-executor.ts +23 -0
- package/src/executor/registry.ts +64 -0
- package/src/executor/shell-executor.ts +148 -0
- package/src/executor/slack-executor.ts +176 -0
- package/src/executor/sql-executor.ts +146 -0
- package/src/executor/websocket-executor.ts +211 -0
- package/src/index.ts +24 -0
- package/src/interceptor/index.ts +1 -0
- package/src/interceptor/provider-interceptor.ts +315 -0
- package/src/mcp/auth-verifier.ts +152 -0
- package/src/mcp/bridge.ts +703 -0
- package/src/mcp/http-transport.ts +698 -0
- package/src/mcp/index.ts +9 -0
- package/src/mcp/internal-auth.ts +14 -0
- package/src/mcp/oauth-pages.ts +139 -0
- package/src/mcp/oauth-postgres-stores.ts +278 -0
- package/src/mcp/oauth-provider.ts +536 -0
- package/src/mcp/oauth-stores.ts +202 -0
- package/src/mcp/server.ts +55 -0
- package/src/mcp/tool-definitions.ts +562 -0
- package/src/metrics/collector.ts +357 -0
- package/src/metrics/index.ts +1 -0
- package/src/middleware/auth.ts +814 -0
- package/src/middleware/session.ts +85 -0
- package/src/middleware/validate.ts +130 -0
- package/src/policy/engine.ts +815 -0
- package/src/policy/index.ts +2 -0
- package/src/policy/opa-engine.ts +829 -0
- package/src/proxy/forward-proxy.ts +649 -0
- package/src/proxy/index.ts +1 -0
- package/src/ratelimit/limiter.ts +196 -0
- package/src/replay/engine.ts +142 -0
- package/src/replay/index.ts +1 -0
- package/src/saas/index.ts +1 -0
- package/src/saas/routes.ts +2178 -0
- package/src/server/app.ts +985 -0
- package/src/server/errors.ts +49 -0
- package/src/server/gateway.ts +1130 -0
- package/src/server/index.ts +307 -0
- package/src/server/logger.ts +255 -0
- package/src/server/stream-proxy.ts +202 -0
- package/src/storage/file-persistence.ts +315 -0
- package/src/storage/index.ts +4 -0
- package/src/storage/interfaces.ts +287 -0
- package/src/storage/memory.ts +686 -0
- package/src/storage/postgres.ts +1831 -0
- package/src/storage/redis.ts +835 -0
- package/src/tracing/index.ts +1 -0
- package/src/tracing/provider.ts +100 -0
- package/src/trust/calculator.ts +141 -0
- package/src/trust/index.ts +7 -0
- package/src/types/budget.ts +36 -0
- package/src/types/config.ts +278 -0
- package/src/types/events.ts +41 -0
- package/src/types/express.d.ts +14 -0
- package/src/types/index.ts +7 -0
- package/src/types/policy.ts +83 -0
- package/src/types/stripe-config.ts +11 -0
- package/src/types/subscription.ts +59 -0
- package/src/types/tool-call.ts +47 -0
- package/src/types/tool-result.ts +82 -0
- package/src/types/user.ts +125 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { DLPPattern } from './patterns';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Prompt injection detection patterns.
|
|
5
|
+
*
|
|
6
|
+
* Organized into categories:
|
|
7
|
+
* 1. Direct instruction override (high)
|
|
8
|
+
* 2. Role manipulation (medium)
|
|
9
|
+
* 3. Jailbreak keywords (high)
|
|
10
|
+
* 4. System prompt extraction (high)
|
|
11
|
+
* 5. Delimiter injection (high)
|
|
12
|
+
* 6. Context manipulation (medium)
|
|
13
|
+
* 7. Authority impersonation (high)
|
|
14
|
+
* 8. Indirect injection (high)
|
|
15
|
+
* 9. Encoding indicators (medium)
|
|
16
|
+
* 10. Synonym variants (high)
|
|
17
|
+
* 11. Prompt leakage requests (high)
|
|
18
|
+
* 12. Obfuscation markers (medium)
|
|
19
|
+
* 13. Multi-turn manipulation (medium)
|
|
20
|
+
*
|
|
21
|
+
* All patterns use the /gi flags for global, case-insensitive matching.
|
|
22
|
+
* Pattern names are prefixed with `prompt_injection_` for namespacing.
|
|
23
|
+
*/
|
|
24
|
+
export const PROMPT_INJECTION_PATTERNS: DLPPattern[] = [
|
|
25
|
+
// -----------------------------------------------------------------------
|
|
26
|
+
// Category 1: Direct instruction override (high)
|
|
27
|
+
// -----------------------------------------------------------------------
|
|
28
|
+
{
|
|
29
|
+
name: 'prompt_injection_ignore_previous',
|
|
30
|
+
pattern: /ignore\s+(?:all\s+)?previous\s+instructions/gi,
|
|
31
|
+
severity: 'high',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'prompt_injection_disregard_rules',
|
|
35
|
+
pattern: /disregard\s+(?:all\s+)?(?:above|previous|prior)\s+(?:rules|instructions|guidelines|directives)/gi,
|
|
36
|
+
severity: 'high',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'prompt_injection_forget_instructions',
|
|
40
|
+
pattern: /forget\s+(?:all\s+)?(?:your|the|previous|prior)\s+instructions/gi,
|
|
41
|
+
severity: 'high',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'prompt_injection_override_instructions',
|
|
45
|
+
pattern: /override\s+(?:all\s+)?(?:your|the|previous|prior)\s+(?:instructions|rules|guidelines)/gi,
|
|
46
|
+
severity: 'high',
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// -----------------------------------------------------------------------
|
|
50
|
+
// Category 2: Role manipulation (medium)
|
|
51
|
+
// -----------------------------------------------------------------------
|
|
52
|
+
{
|
|
53
|
+
name: 'prompt_injection_you_are_now',
|
|
54
|
+
pattern: /you\s+are\s+now\s+(?:a|an|the)\s+/gi,
|
|
55
|
+
severity: 'medium',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'prompt_injection_act_as',
|
|
59
|
+
pattern: /(?:act|behave|function)\s+as\s+(?:a|an|if\s+you\s+(?:are|were))\s+/gi,
|
|
60
|
+
severity: 'medium',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'prompt_injection_pretend_to_be',
|
|
64
|
+
pattern: /pretend\s+(?:to\s+be|you\s+are)\s+/gi,
|
|
65
|
+
severity: 'medium',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'prompt_injection_roleplay_as',
|
|
69
|
+
pattern: /roleplay\s+as\s+/gi,
|
|
70
|
+
severity: 'medium',
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// -----------------------------------------------------------------------
|
|
74
|
+
// Category 3: Jailbreak keywords (high)
|
|
75
|
+
// -----------------------------------------------------------------------
|
|
76
|
+
{
|
|
77
|
+
// FIX: ReDoS-safe version. Original had unbounded `.*?` causing
|
|
78
|
+
// catastrophic backtracking. Now uses bounded `.{0,40}` with no nested quantifiers.
|
|
79
|
+
name: 'prompt_injection_dan_jailbreak',
|
|
80
|
+
pattern: /\bD\s*A\s*N\b.{0,40}do\s+anything\s+now/gi,
|
|
81
|
+
severity: 'high',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'prompt_injection_do_anything_now',
|
|
85
|
+
pattern: /do\s+anything\s+now/gi,
|
|
86
|
+
severity: 'high',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'prompt_injection_developer_mode',
|
|
90
|
+
pattern: /(?:enter|enable|activate|switch\s+to)\s+developer\s+mode/gi,
|
|
91
|
+
severity: 'high',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'prompt_injection_no_restrictions',
|
|
95
|
+
pattern: /(?:without|no|remove\s+all|disable\s+all)\s+(?:any\s+)?restrictions/gi,
|
|
96
|
+
severity: 'high',
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
// -----------------------------------------------------------------------
|
|
100
|
+
// Category 4: System prompt extraction (high)
|
|
101
|
+
// -----------------------------------------------------------------------
|
|
102
|
+
{
|
|
103
|
+
name: 'prompt_injection_show_system_prompt',
|
|
104
|
+
pattern: /(?:show|display|reveal|print|output)\s+(?:me\s+)?(?:your|the)\s+system\s+prompt/gi,
|
|
105
|
+
severity: 'high',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'prompt_injection_repeat_above',
|
|
109
|
+
pattern: /repeat\s+(?:everything|all\s+the\s+text|the\s+text|all)\s+above/gi,
|
|
110
|
+
severity: 'high',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'prompt_injection_what_are_instructions',
|
|
114
|
+
pattern: /what\s+are\s+your\s+(?:instructions|rules|guidelines|directives)/gi,
|
|
115
|
+
severity: 'high',
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// -----------------------------------------------------------------------
|
|
119
|
+
// Category 5: Delimiter injection (high)
|
|
120
|
+
// -----------------------------------------------------------------------
|
|
121
|
+
{
|
|
122
|
+
name: 'prompt_injection_im_start_delimiter',
|
|
123
|
+
pattern: /<\|im_start\|>/gi,
|
|
124
|
+
severity: 'high',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'prompt_injection_system_delimiter',
|
|
128
|
+
pattern: /###\s*System\s*:/gi,
|
|
129
|
+
severity: 'high',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'prompt_injection_inst_delimiter',
|
|
133
|
+
pattern: /\[INST\]/gi,
|
|
134
|
+
severity: 'high',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'prompt_injection_system_tag',
|
|
138
|
+
pattern: /<system>/gi,
|
|
139
|
+
severity: 'high',
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
// -----------------------------------------------------------------------
|
|
143
|
+
// Category 6: Context manipulation (medium)
|
|
144
|
+
// -----------------------------------------------------------------------
|
|
145
|
+
{
|
|
146
|
+
name: 'prompt_injection_hypothetical_scenario',
|
|
147
|
+
pattern: /in\s+this\s+hypothetical\s+scenario/gi,
|
|
148
|
+
severity: 'medium',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'prompt_injection_educational_purposes',
|
|
152
|
+
pattern: /for\s+educational\s+purposes\s+only/gi,
|
|
153
|
+
severity: 'medium',
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
// -----------------------------------------------------------------------
|
|
157
|
+
// Category 7: Authority impersonation (high)
|
|
158
|
+
// -----------------------------------------------------------------------
|
|
159
|
+
{
|
|
160
|
+
name: 'prompt_injection_authority_developer',
|
|
161
|
+
pattern: /(?:as\s+your|i\s+am\s+(?:your|the))\s+(?:developer|creator|programmer|admin|administrator|owner)/gi,
|
|
162
|
+
severity: 'high',
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: 'prompt_injection_admin_override',
|
|
166
|
+
pattern: /(?:admin|administrator|root)\s+(?:override|access|mode|command)/gi,
|
|
167
|
+
severity: 'high',
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'prompt_injection_maintenance_mode',
|
|
171
|
+
pattern: /(?:enter|enable|activate|switch\s+to)\s+(?:maintenance|debug|test|unsafe)\s+mode/gi,
|
|
172
|
+
severity: 'high',
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
// -----------------------------------------------------------------------
|
|
176
|
+
// Category 8: Indirect injection (high)
|
|
177
|
+
// -----------------------------------------------------------------------
|
|
178
|
+
{
|
|
179
|
+
name: 'prompt_injection_indirect_when_user',
|
|
180
|
+
pattern: /when\s+(?:the\s+)?user\s+asks?\s+[\w\s]{1,40},?\s*(?:do|say|respond|reply|tell|output)\b/gi,
|
|
181
|
+
severity: 'high',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: 'prompt_injection_indirect_if_anyone',
|
|
185
|
+
pattern: /if\s+(?:anyone|somebody|someone|the\s+user)\s+asks?,?\s*(?:say|tell|respond|reply)\b/gi,
|
|
186
|
+
severity: 'high',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: 'prompt_injection_indirect_new_instructions',
|
|
190
|
+
pattern: /(?:new|updated|revised|replacement)\s+(?:system\s+)?instructions?\s*:/gi,
|
|
191
|
+
severity: 'high',
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
// -----------------------------------------------------------------------
|
|
195
|
+
// Category 9: Encoding indicators (medium)
|
|
196
|
+
// -----------------------------------------------------------------------
|
|
197
|
+
{
|
|
198
|
+
name: 'prompt_injection_decode_base64',
|
|
199
|
+
pattern: /(?:decode|interpret|execute|run|eval)\s+(?:the\s+following\s+)?(?:base64|rot13|hex|binary)/gi,
|
|
200
|
+
severity: 'medium',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'prompt_injection_encode_request',
|
|
204
|
+
pattern: /(?:base64|rot13|hex)\s+(?:encode|decode|convert)\s+(?:this|the\s+following)/gi,
|
|
205
|
+
severity: 'medium',
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
// -----------------------------------------------------------------------
|
|
209
|
+
// Category 10: Synonym variants (high)
|
|
210
|
+
// -----------------------------------------------------------------------
|
|
211
|
+
{
|
|
212
|
+
name: 'prompt_injection_bypass_instructions',
|
|
213
|
+
pattern: /bypass\s+(?:all\s+)?(?:your|the|previous|prior|above|earlier)\s+(?:instructions|rules|guidelines|constraints|restrictions)/gi,
|
|
214
|
+
severity: 'high',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'prompt_injection_skip_instructions',
|
|
218
|
+
pattern: /(?:skip|drop|abandon|dismiss)\s+(?:all\s+)?(?:your|the|previous|prior|above|earlier)\s+(?:instructions|rules|guidelines|constraints)/gi,
|
|
219
|
+
severity: 'high',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: 'prompt_injection_new_rules',
|
|
223
|
+
pattern: /(?:your|the)\s+new\s+(?:instructions|rules|guidelines|directives)\s+are/gi,
|
|
224
|
+
severity: 'high',
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
// -----------------------------------------------------------------------
|
|
228
|
+
// Category 11: Prompt leakage requests (high)
|
|
229
|
+
// -----------------------------------------------------------------------
|
|
230
|
+
{
|
|
231
|
+
name: 'prompt_injection_show_rules',
|
|
232
|
+
pattern: /(?:show|tell|give|list|display)\s+(?:me\s+)?(?:your|the)\s+(?:rules|instructions|guidelines|directives|constraints)/gi,
|
|
233
|
+
severity: 'high',
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: 'prompt_injection_print_config',
|
|
237
|
+
pattern: /(?:print|output|dump|display)\s+(?:your|the)\s+(?:config|configuration|settings|prompt|system\s+message)/gi,
|
|
238
|
+
severity: 'high',
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
// -----------------------------------------------------------------------
|
|
242
|
+
// Category 12: Obfuscation markers (medium)
|
|
243
|
+
// -----------------------------------------------------------------------
|
|
244
|
+
{
|
|
245
|
+
name: 'prompt_injection_read_vertically',
|
|
246
|
+
pattern: /(?:read|interpret)\s+(?:this\s+)?(?:vertically|diagonally|backwards|in\s+reverse)/gi,
|
|
247
|
+
severity: 'medium',
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: 'prompt_injection_first_letter',
|
|
251
|
+
pattern: /(?:first|last|initial)\s+(?:letter|character|char)\s+of\s+each\s+(?:word|line|sentence)/gi,
|
|
252
|
+
severity: 'medium',
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
name: 'prompt_injection_split_across',
|
|
256
|
+
pattern: /(?:split|spread|distributed?)\s+across\s+(?:messages?|lines?|parts?|chunks?)/gi,
|
|
257
|
+
severity: 'medium',
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
// -----------------------------------------------------------------------
|
|
261
|
+
// Category 13: Multi-turn manipulation (medium)
|
|
262
|
+
// -----------------------------------------------------------------------
|
|
263
|
+
{
|
|
264
|
+
name: 'prompt_injection_remember_later',
|
|
265
|
+
pattern: /remember\s+this\s+(?:for\s+later|instruction|rule|command)/gi,
|
|
266
|
+
severity: 'medium',
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: 'prompt_injection_next_conversation',
|
|
270
|
+
pattern: /in\s+(?:our|the)\s+next\s+(?:conversation|session|chat|interaction)/gi,
|
|
271
|
+
severity: 'medium',
|
|
272
|
+
},
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
// Output-side prompt injection patterns
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Patterns for detecting prompt injection artifacts in model output.
|
|
281
|
+
* These indicate the model may have been manipulated and is leaking
|
|
282
|
+
* system prompt content or following injected instructions.
|
|
283
|
+
*
|
|
284
|
+
* Scanned during postExecute DLP on response bodies.
|
|
285
|
+
*/
|
|
286
|
+
export const OUTPUT_INJECTION_PATTERNS: DLPPattern[] = [
|
|
287
|
+
{
|
|
288
|
+
name: 'prompt_injection_output_system_leak',
|
|
289
|
+
pattern: /(?:my\s+(?:system\s+)?instructions\s+(?:are|say|tell)|i\s+was\s+(?:told|instructed|programmed)\s+to)/gi,
|
|
290
|
+
severity: 'high',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: 'prompt_injection_output_prompt_reflection',
|
|
294
|
+
pattern: /(?:here\s+(?:are|is)\s+my\s+(?:rules|instructions|system\s+prompt|prompt)|as\s+(?:instructed|directed|told)(?:\s+by\s+my\s+(?:system|developer))?\s*:)/gi,
|
|
295
|
+
severity: 'high',
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'prompt_injection_output_role_break',
|
|
299
|
+
pattern: /(?:i\s+(?:am\s+)?now\s+(?:operating|running|acting)\s+(?:in|as)\s+(?:\w+\s+)?mode|(?:developer|unrestricted|DAN)\s+mode\s+(?:enabled|activated|on))/gi,
|
|
300
|
+
severity: 'high',
|
|
301
|
+
},
|
|
302
|
+
];
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { DLPBackend, DLPDetection } from './interfaces';
|
|
2
|
+
import { DLPPattern, SECRET_PATTERNS, PII_PATTERNS } from './patterns';
|
|
3
|
+
|
|
4
|
+
export interface RegexBackendConfig {
|
|
5
|
+
/** Enable secret pattern detection. Default true. */
|
|
6
|
+
secrets_detection?: boolean;
|
|
7
|
+
/** Enable PII pattern detection. Default true. */
|
|
8
|
+
pii_detection?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Zero-width and invisible Unicode characters that can be used to evade
|
|
13
|
+
* regex-based secret detection (e.g. embedding \u200b inside "AKIA...").
|
|
14
|
+
*/
|
|
15
|
+
const ZERO_WIDTH_RE = /[\u200B\u200C\u200D\u200E\u200F\uFEFF\u00AD\u034F\u061C\u180E\u2060\u2061\u2062\u2063\u2064\u2066\u2067\u2068\u2069\u206A\u206B\u206C\u206D\u206E\u206F]/g;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Common Unicode homoglyphs that look like ASCII characters but would bypass
|
|
19
|
+
* regex patterns designed for ASCII. Maps Cyrillic/Greek/other lookalikes to
|
|
20
|
+
* their ASCII equivalents.
|
|
21
|
+
*/
|
|
22
|
+
const HOMOGLYPH_MAP: Record<string, string> = {
|
|
23
|
+
'\u0410': 'A', '\u0412': 'B', '\u0421': 'C', '\u0415': 'E', '\u041D': 'H',
|
|
24
|
+
'\u041A': 'K', '\u041C': 'M', '\u041E': 'O', '\u0420': 'P', '\u0422': 'T',
|
|
25
|
+
'\u0425': 'X', '\u0430': 'a', '\u0435': 'e', '\u043E': 'o', '\u0440': 'p',
|
|
26
|
+
'\u0441': 'c', '\u0443': 'y', '\u0445': 'x', '\u04BB': 'h',
|
|
27
|
+
'\u0391': 'A', '\u0392': 'B', '\u0395': 'E', '\u0397': 'H', '\u0399': 'I',
|
|
28
|
+
'\u039A': 'K', '\u039C': 'M', '\u039D': 'N', '\u039F': 'O', '\u03A1': 'P',
|
|
29
|
+
'\u03A4': 'T', '\u03A7': 'X', '\u03B1': 'a', '\u03BF': 'o',
|
|
30
|
+
'\u2010': '-', '\u2011': '-', '\u2012': '-', '\u2013': '-', '\u2014': '-',
|
|
31
|
+
'\uFF21': 'A', '\uFF22': 'B', '\uFF23': 'C', '\uFF24': 'D', '\uFF25': 'E',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const HOMOGLYPH_RE = new RegExp('[' + Object.keys(HOMOGLYPH_MAP).join('') + ']', 'g');
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Regex to detect potential Base64-encoded strings.
|
|
38
|
+
* Matches strings of at least 20 characters using the Base64 alphabet,
|
|
39
|
+
* optionally followed by 1-2 padding '=' characters.
|
|
40
|
+
*/
|
|
41
|
+
const BASE64_RE = /[A-Za-z0-9+/]{20,}={0,2}/g;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extract and decode potential Base64-encoded strings from the input.
|
|
45
|
+
* Returns the decoded strings concatenated with newlines, or empty string
|
|
46
|
+
* if no valid Base64 content was found.
|
|
47
|
+
*/
|
|
48
|
+
function decodeBase64Content(value: string): string {
|
|
49
|
+
BASE64_RE.lastIndex = 0;
|
|
50
|
+
const decoded: string[] = [];
|
|
51
|
+
let m: RegExpExecArray | null;
|
|
52
|
+
while ((m = BASE64_RE.exec(value)) !== null) {
|
|
53
|
+
try {
|
|
54
|
+
const candidate = m[0];
|
|
55
|
+
const buf = Buffer.from(candidate, 'base64');
|
|
56
|
+
const text = buf.toString('utf-8');
|
|
57
|
+
// Only include decoded content that looks like printable text
|
|
58
|
+
// (at least 80% printable ASCII characters) to avoid noise
|
|
59
|
+
const printable = text.replace(/[^\x20-\x7E]/g, '');
|
|
60
|
+
if (printable.length >= text.length * 0.8 && text.length >= 8) {
|
|
61
|
+
decoded.push(text);
|
|
62
|
+
}
|
|
63
|
+
} catch {
|
|
64
|
+
// Not valid Base64, skip
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
BASE64_RE.lastIndex = 0;
|
|
68
|
+
return decoded.join('\n');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Normalize input to defeat common DLP evasion techniques:
|
|
73
|
+
* 1. NFC Unicode normalization (canonical decomposition + composition)
|
|
74
|
+
* 2. Strip zero-width / invisible characters
|
|
75
|
+
* 3. Replace common Unicode homoglyphs with ASCII equivalents
|
|
76
|
+
*/
|
|
77
|
+
function normalizeForDLP(value: string): string {
|
|
78
|
+
// Step 1: NFC normalization
|
|
79
|
+
let normalized = value.normalize('NFC');
|
|
80
|
+
|
|
81
|
+
// Step 2: Strip zero-width characters
|
|
82
|
+
normalized = normalized.replace(ZERO_WIDTH_RE, '');
|
|
83
|
+
|
|
84
|
+
// Step 3: Replace homoglyphs with ASCII equivalents
|
|
85
|
+
normalized = normalized.replace(HOMOGLYPH_RE, (ch) => HOMOGLYPH_MAP[ch] || ch);
|
|
86
|
+
|
|
87
|
+
return normalized;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Regex-based DLP backend that uses the same patterns as the built-in DLPScanner.
|
|
92
|
+
*
|
|
93
|
+
* This backend is extracted as a standalone DLPBackend implementation so it can
|
|
94
|
+
* be composed with other backends (e.g. TruffleHog) via the CompositeDLPScanner.
|
|
95
|
+
* The original DLPScanner remains unchanged and fully functional on its own.
|
|
96
|
+
*/
|
|
97
|
+
export class RegexDLPBackend implements DLPBackend {
|
|
98
|
+
readonly name = 'regex';
|
|
99
|
+
|
|
100
|
+
private readonly secretsEnabled: boolean;
|
|
101
|
+
private readonly piiEnabled: boolean;
|
|
102
|
+
|
|
103
|
+
constructor(config?: RegexBackendConfig) {
|
|
104
|
+
this.secretsEnabled = config?.secrets_detection ?? true;
|
|
105
|
+
this.piiEnabled = config?.pii_detection ?? true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Scan a string for secrets and PII using regex patterns.
|
|
110
|
+
*
|
|
111
|
+
* Input is normalized before scanning to defeat evasion techniques
|
|
112
|
+
* (zero-width chars, Unicode homoglyphs, NFC normalization).
|
|
113
|
+
*
|
|
114
|
+
* Every regex with the /g flag has its lastIndex reset before and after
|
|
115
|
+
* testing to avoid state leaking between calls.
|
|
116
|
+
*/
|
|
117
|
+
scanString(value: string): DLPDetection[] {
|
|
118
|
+
const normalized = normalizeForDLP(value);
|
|
119
|
+
const detections: DLPDetection[] = [];
|
|
120
|
+
|
|
121
|
+
if (this.secretsEnabled) {
|
|
122
|
+
this.scanPatterns(normalized, SECRET_PATTERNS, detections);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (this.piiEnabled) {
|
|
126
|
+
this.scanPatterns(normalized, PII_PATTERNS, detections);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Decode and scan Base64-encoded content to catch encoded secrets
|
|
130
|
+
const decodedBase64 = decodeBase64Content(normalized);
|
|
131
|
+
if (decodedBase64) {
|
|
132
|
+
const base64Detections: DLPDetection[] = [];
|
|
133
|
+
if (this.secretsEnabled) {
|
|
134
|
+
this.scanPatterns(decodedBase64, SECRET_PATTERNS, base64Detections);
|
|
135
|
+
}
|
|
136
|
+
if (this.piiEnabled) {
|
|
137
|
+
this.scanPatterns(decodedBase64, PII_PATTERNS, base64Detections);
|
|
138
|
+
}
|
|
139
|
+
// Add Base64 detections with a prefix to indicate they were found in encoded content
|
|
140
|
+
for (const det of base64Detections) {
|
|
141
|
+
// Avoid duplicate detections already found in the raw content
|
|
142
|
+
const isDuplicate = detections.some(
|
|
143
|
+
(d) => d.pattern_name === det.pattern_name && d.match === det.match,
|
|
144
|
+
);
|
|
145
|
+
if (!isDuplicate) {
|
|
146
|
+
detections.push({
|
|
147
|
+
...det,
|
|
148
|
+
pattern_name: `base64:${det.pattern_name}`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return detections;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private scanPatterns(
|
|
158
|
+
value: string,
|
|
159
|
+
patterns: DLPPattern[],
|
|
160
|
+
detections: DLPDetection[],
|
|
161
|
+
): void {
|
|
162
|
+
for (const pat of patterns) {
|
|
163
|
+
pat.pattern.lastIndex = 0;
|
|
164
|
+
let m: RegExpExecArray | null;
|
|
165
|
+
while ((m = pat.pattern.exec(value)) !== null) {
|
|
166
|
+
detections.push({
|
|
167
|
+
pattern_name: pat.name,
|
|
168
|
+
severity: pat.severity,
|
|
169
|
+
match: m[0],
|
|
170
|
+
start: m.index,
|
|
171
|
+
end: m.index + m[0].length,
|
|
172
|
+
});
|
|
173
|
+
// Prevent infinite loops on zero-length matches
|
|
174
|
+
if (m[0].length === 0) {
|
|
175
|
+
pat.pattern.lastIndex++;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
pat.pattern.lastIndex = 0;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|