@troykelly/openclaw-projects 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +7 -2
- package/dist/hooks.js.map +1 -1
- package/dist/register-openclaw.d.ts.map +1 -1
- package/dist/register-openclaw.js +57 -28
- package/dist/register-openclaw.js.map +1 -1
- package/dist/tools/context-search.d.ts +2 -2
- package/dist/tools/context-search.d.ts.map +1 -1
- package/dist/tools/context-search.js +7 -5
- package/dist/tools/context-search.js.map +1 -1
- package/dist/tools/entity-links.d.ts +12 -12
- package/dist/tools/message-search.d.ts +1 -1
- package/dist/tools/message-search.d.ts.map +1 -1
- package/dist/tools/message-search.js +26 -11
- package/dist/tools/message-search.js.map +1 -1
- package/dist/tools/skill-store.d.ts +8 -8
- package/dist/tools/threads.d.ts +1 -1
- package/dist/tools/threads.d.ts.map +1 -1
- package/dist/tools/threads.js +27 -13
- package/dist/tools/threads.js.map +1 -1
- package/dist/tools/todo-search.d.ts +2 -2
- package/dist/utils/injection-log-rate-limiter.d.ts +62 -0
- package/dist/utils/injection-log-rate-limiter.d.ts.map +1 -0
- package/dist/utils/injection-log-rate-limiter.js +106 -0
- package/dist/utils/injection-log-rate-limiter.js.map +1 -0
- package/dist/utils/injection-protection.d.ts +55 -3
- package/dist/utils/injection-protection.d.ts.map +1 -1
- package/dist/utils/injection-protection.js +100 -27
- package/dist/utils/injection-protection.js.map +1 -1
- package/dist/utils/prompt-guard-client.d.ts +59 -0
- package/dist/utils/prompt-guard-client.d.ts.map +1 -0
- package/dist/utils/prompt-guard-client.js +99 -0
- package/dist/utils/prompt-guard-client.js.map +1 -0
- package/openclaw.plugin.json +23 -1
- package/package.json +12 -11
- package/LICENSE +0 -21
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Searches message history semantically using pgvector embeddings.
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import {
|
|
6
|
+
import { injectionLogLimiter } from '../utils/injection-log-rate-limiter.js';
|
|
7
|
+
import { createBoundaryMarkers, detectInjectionPatternsAsync, sanitizeMetadataField, wrapExternalMessage } from '../utils/injection-protection.js';
|
|
7
8
|
/** Channel type enum */
|
|
8
9
|
const ChannelType = z.enum(['sms', 'email', 'all']);
|
|
9
10
|
/** Maximum results limit */
|
|
@@ -22,7 +23,7 @@ export const MessageSearchParamsSchema = z.object({
|
|
|
22
23
|
* Creates the message_search tool.
|
|
23
24
|
*/
|
|
24
25
|
export function createMessageSearchTool(options) {
|
|
25
|
-
const { client, logger, userId } = options;
|
|
26
|
+
const { client, logger, config, userId } = options;
|
|
26
27
|
return {
|
|
27
28
|
name: 'message_search',
|
|
28
29
|
description: 'Search message history semantically. Use when you need to find past conversations, ' +
|
|
@@ -88,28 +89,42 @@ export function createMessageSearchTool(options) {
|
|
|
88
89
|
resultCount: messages.length,
|
|
89
90
|
total,
|
|
90
91
|
});
|
|
91
|
-
//
|
|
92
|
+
// SECURITY: Run injection detection on the FULL snippet BEFORE any
|
|
93
|
+
// truncation. Snippets are later truncated to 100 chars for display, but
|
|
94
|
+
// detection must see the complete content to catch payloads that an
|
|
95
|
+
// attacker could hide beyond the truncation boundary. (Issue #1258)
|
|
96
|
+
// Rate-limited to prevent log flooding from volume attacks. (#1257)
|
|
92
97
|
for (const m of messages) {
|
|
93
98
|
if (m.snippet) {
|
|
94
|
-
const detection =
|
|
99
|
+
const detection = await detectInjectionPatternsAsync(m.snippet, {
|
|
100
|
+
promptGuardUrl: config.promptGuardUrl,
|
|
101
|
+
});
|
|
95
102
|
if (detection.detected) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
const logDecision = injectionLogLimiter.shouldLog(userId);
|
|
104
|
+
if (logDecision.log) {
|
|
105
|
+
logger.warn(logDecision.summary ? 'injection detection log summary for previous window' : 'potential prompt injection detected in message_search result', {
|
|
106
|
+
userId,
|
|
107
|
+
messageId: m.id,
|
|
108
|
+
patterns: detection.patterns,
|
|
109
|
+
source: detection.source,
|
|
110
|
+
...(logDecision.suppressed > 0 && { suppressedCount: logDecision.suppressed }),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
101
113
|
}
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
// Format content for display with injection protection.
|
|
105
117
|
// Boundary-wrap all snippets since they may contain external message content.
|
|
118
|
+
// NOTE: Truncation happens here AFTER detection above — do not reorder.
|
|
119
|
+
// Generate a per-invocation nonce for boundary markers (#1255)
|
|
120
|
+
const { nonce } = createBoundaryMarkers();
|
|
106
121
|
const content = messages.length > 0
|
|
107
122
|
? messages
|
|
108
123
|
.map((m) => {
|
|
109
124
|
const score = `(${Math.round(m.score * 100)}%)`;
|
|
110
125
|
const truncatedSnippet = m.snippet.substring(0, 100) + (m.snippet.length > 100 ? '...' : '');
|
|
111
|
-
const wrappedSnippet = wrapExternalMessage(truncatedSnippet);
|
|
112
|
-
const safeTitle = sanitizeMetadataField(m.title);
|
|
126
|
+
const wrappedSnippet = wrapExternalMessage(truncatedSnippet, { nonce });
|
|
127
|
+
const safeTitle = sanitizeMetadataField(m.title, nonce);
|
|
113
128
|
return `${safeTitle} ${score}: ${wrappedSnippet}`;
|
|
114
129
|
})
|
|
115
130
|
.join('\n')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-search.js","sourceRoot":"","sources":["../../src/tools/message-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"message-search.js","sourceRoot":"","sources":["../../src/tools/message-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,10 +32,10 @@ export declare const SkillStorePutParamsSchema: z.ZodObject<{
|
|
|
32
32
|
skill_id: string;
|
|
33
33
|
key?: string | undefined;
|
|
34
34
|
data?: Record<string, unknown> | undefined;
|
|
35
|
-
user_email?: string | undefined;
|
|
36
35
|
tags?: string[] | undefined;
|
|
37
36
|
content?: string | undefined;
|
|
38
37
|
title?: string | undefined;
|
|
38
|
+
user_email?: string | undefined;
|
|
39
39
|
summary?: string | undefined;
|
|
40
40
|
collection?: string | undefined;
|
|
41
41
|
media_url?: string | undefined;
|
|
@@ -48,10 +48,10 @@ export declare const SkillStorePutParamsSchema: z.ZodObject<{
|
|
|
48
48
|
skill_id: string;
|
|
49
49
|
key?: string | undefined;
|
|
50
50
|
data?: Record<string, unknown> | undefined;
|
|
51
|
-
user_email?: string | undefined;
|
|
52
51
|
tags?: string[] | undefined;
|
|
53
52
|
content?: string | undefined;
|
|
54
53
|
title?: string | undefined;
|
|
54
|
+
user_email?: string | undefined;
|
|
55
55
|
summary?: string | undefined;
|
|
56
56
|
collection?: string | undefined;
|
|
57
57
|
media_url?: string | undefined;
|
|
@@ -96,9 +96,9 @@ export declare const SkillStoreListParamsSchema: z.ZodObject<{
|
|
|
96
96
|
status?: "active" | "archived" | "processing" | undefined;
|
|
97
97
|
limit?: number | undefined;
|
|
98
98
|
since?: string | undefined;
|
|
99
|
-
user_email?: string | undefined;
|
|
100
99
|
tags?: string[] | undefined;
|
|
101
100
|
offset?: number | undefined;
|
|
101
|
+
user_email?: string | undefined;
|
|
102
102
|
collection?: string | undefined;
|
|
103
103
|
order_by?: "title" | "priority" | "created_at" | "updated_at" | undefined;
|
|
104
104
|
}, {
|
|
@@ -106,9 +106,9 @@ export declare const SkillStoreListParamsSchema: z.ZodObject<{
|
|
|
106
106
|
status?: "active" | "archived" | "processing" | undefined;
|
|
107
107
|
limit?: number | undefined;
|
|
108
108
|
since?: string | undefined;
|
|
109
|
-
user_email?: string | undefined;
|
|
110
109
|
tags?: string[] | undefined;
|
|
111
110
|
offset?: number | undefined;
|
|
111
|
+
user_email?: string | undefined;
|
|
112
112
|
collection?: string | undefined;
|
|
113
113
|
order_by?: "title" | "priority" | "created_at" | "updated_at" | undefined;
|
|
114
114
|
}>;
|
|
@@ -210,18 +210,18 @@ export declare const SkillStoreSearchParamsSchema: z.ZodObject<{
|
|
|
210
210
|
query: string;
|
|
211
211
|
skill_id: string;
|
|
212
212
|
limit?: number | undefined;
|
|
213
|
-
user_email?: string | undefined;
|
|
214
|
-
semantic?: boolean | undefined;
|
|
215
213
|
tags?: string[] | undefined;
|
|
214
|
+
semantic?: boolean | undefined;
|
|
215
|
+
user_email?: string | undefined;
|
|
216
216
|
collection?: string | undefined;
|
|
217
217
|
min_similarity?: number | undefined;
|
|
218
218
|
}, {
|
|
219
219
|
query: string;
|
|
220
220
|
skill_id: string;
|
|
221
221
|
limit?: number | undefined;
|
|
222
|
-
user_email?: string | undefined;
|
|
223
|
-
semantic?: boolean | undefined;
|
|
224
222
|
tags?: string[] | undefined;
|
|
223
|
+
semantic?: boolean | undefined;
|
|
224
|
+
user_email?: string | undefined;
|
|
225
225
|
collection?: string | undefined;
|
|
226
226
|
min_similarity?: number | undefined;
|
|
227
227
|
}>;
|
package/dist/tools/threads.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import type { ApiClient } from '../api-client.js';
|
|
7
|
-
import type { Logger } from '../logger.js';
|
|
8
7
|
import type { PluginConfig } from '../config.js';
|
|
8
|
+
import type { Logger } from '../logger.js';
|
|
9
9
|
/** Parameters for thread_list tool */
|
|
10
10
|
export declare const ThreadListParamsSchema: z.ZodObject<{
|
|
11
11
|
channel: z.ZodOptional<z.ZodEnum<["sms", "email"]>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../src/tools/threads.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../src/tools/threads.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAuB3C,sCAAsC;AACtC,eAAO,MAAM,sBAAsB;;;;;;;;;;;;EAIjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAsBtE,2DAA2D;AAC3D,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,6BAA6B;AAC7B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE;YACP,OAAO,EAAE,cAAc,EAAE,CAAC;YAC1B,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,CAAC;CACH;AAED,yBAAyB;AACzB,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAErE,yBAAyB;AACzB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sBAAsB;AACtB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,sBAAsB,CAAC;IAC1C,OAAO,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAClE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CA0G/E;AAMD,qCAAqC;AACrC,eAAO,MAAM,qBAAqB;;;;;;;;;EAQhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,mCAAmC;AACnC,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2BAA2B;AAC3B,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAwB;AACxB,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAyBD,6BAA6B;AAC7B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE;YACP,MAAM,EAAE,UAAU,CAAC;YACnB,QAAQ,EAAE,aAAa,EAAE,CAAC;YAC1B,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,CAAC;CACH;AAED,yBAAyB;AACzB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAElE,sBAAsB;AACtB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,qBAAqB,CAAC;IACzC,OAAO,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CAChE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CA4H7E"}
|
package/dist/tools/threads.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Provides thread_list and thread_get tools for viewing message threads.
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import {
|
|
6
|
+
import { injectionLogLimiter } from '../utils/injection-log-rate-limiter.js';
|
|
7
|
+
import { createBoundaryMarkers, detectInjectionPatternsAsync, sanitizeMessageForContext, sanitizeMetadataField, wrapExternalMessage, } from '../utils/injection-protection.js';
|
|
7
8
|
/** Channel type enum */
|
|
8
9
|
const ChannelType = z.enum(['sms', 'email']);
|
|
9
10
|
/** Default and max limits */
|
|
@@ -85,11 +86,13 @@ export function createThreadListTool(options) {
|
|
|
85
86
|
});
|
|
86
87
|
// Format content for display with injection protection.
|
|
87
88
|
// Sanitize snippet/title since they may contain external message content.
|
|
89
|
+
// Generate a per-invocation nonce for boundary markers (#1255)
|
|
90
|
+
const { nonce } = createBoundaryMarkers();
|
|
88
91
|
const content = threadItems.length > 0
|
|
89
92
|
? threadItems
|
|
90
93
|
.map((t) => {
|
|
91
|
-
const safeTitle = sanitizeMetadataField(t.title);
|
|
92
|
-
const wrappedSnippet = wrapExternalMessage(t.snippet);
|
|
94
|
+
const safeTitle = sanitizeMetadataField(t.title, nonce);
|
|
95
|
+
const wrappedSnippet = wrapExternalMessage(t.snippet, { nonce });
|
|
93
96
|
return `${safeTitle}: ${wrappedSnippet}`;
|
|
94
97
|
})
|
|
95
98
|
.join('\n')
|
|
@@ -132,7 +135,7 @@ export const ThreadGetParamsSchema = z.object({
|
|
|
132
135
|
* Creates the thread_get tool.
|
|
133
136
|
*/
|
|
134
137
|
export function createThreadGetTool(options) {
|
|
135
|
-
const { client, logger, userId } = options;
|
|
138
|
+
const { client, logger, config, userId } = options;
|
|
136
139
|
return {
|
|
137
140
|
name: 'thread_get',
|
|
138
141
|
description: 'Get a thread with its message history. Use to view the full conversation in a thread.',
|
|
@@ -173,20 +176,30 @@ export function createThreadGetTool(options) {
|
|
|
173
176
|
messageCount: messages.length,
|
|
174
177
|
});
|
|
175
178
|
// Format content for display — sanitize metadata fields interpolated outside boundary wrappers
|
|
176
|
-
|
|
177
|
-
const
|
|
179
|
+
// Generate a per-invocation nonce for boundary markers (#1255)
|
|
180
|
+
const { nonce: threadGetNonce } = createBoundaryMarkers();
|
|
181
|
+
const contact = sanitizeMetadataField(thread.contact?.displayName || 'Unknown', threadGetNonce);
|
|
182
|
+
const safeChannel = sanitizeMetadataField(thread.channel, threadGetNonce);
|
|
178
183
|
const header = `Thread with ${contact} [${safeChannel}]`;
|
|
179
184
|
// Detect and log potential injection patterns in inbound messages
|
|
185
|
+
// Rate-limited to prevent log flooding from volume attacks. (#1257)
|
|
180
186
|
for (const m of messages) {
|
|
181
187
|
if (m.direction === 'inbound' && m.body) {
|
|
182
|
-
const detection =
|
|
188
|
+
const detection = await detectInjectionPatternsAsync(m.body, {
|
|
189
|
+
promptGuardUrl: config.promptGuardUrl,
|
|
190
|
+
});
|
|
183
191
|
if (detection.detected) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
const logDecision = injectionLogLimiter.shouldLog(userId);
|
|
193
|
+
if (logDecision.log) {
|
|
194
|
+
logger.warn(logDecision.summary ? 'injection detection log summary for previous window' : 'potential prompt injection detected in thread_get result', {
|
|
195
|
+
userId,
|
|
196
|
+
threadId,
|
|
197
|
+
messageId: m.id,
|
|
198
|
+
patterns: detection.patterns,
|
|
199
|
+
source: detection.source,
|
|
200
|
+
...(logDecision.suppressed > 0 && { suppressedCount: logDecision.suppressed }),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
190
203
|
}
|
|
191
204
|
}
|
|
192
205
|
}
|
|
@@ -199,6 +212,7 @@ export function createThreadGetTool(options) {
|
|
|
199
212
|
direction: m.direction,
|
|
200
213
|
channel: thread.channel,
|
|
201
214
|
sender: contact,
|
|
215
|
+
nonce: threadGetNonce,
|
|
202
216
|
});
|
|
203
217
|
return `${prefix} [${timestamp}] ${body}`;
|
|
204
218
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threads.js","sourceRoot":"","sources":["../../src/tools/threads.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"threads.js","sourceRoot":"","sources":["../../src/tools/threads.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,7 +34,7 @@ export declare const TodoSearchParamsSchema: z.ZodObject<{
|
|
|
34
34
|
lat: number;
|
|
35
35
|
lng: number;
|
|
36
36
|
} | undefined;
|
|
37
|
-
kind?: "project" | "task" | "
|
|
37
|
+
kind?: "project" | "task" | "initiative" | "epic" | "issue" | undefined;
|
|
38
38
|
}, {
|
|
39
39
|
query: string;
|
|
40
40
|
status?: string | undefined;
|
|
@@ -43,7 +43,7 @@ export declare const TodoSearchParamsSchema: z.ZodObject<{
|
|
|
43
43
|
lat: number;
|
|
44
44
|
lng: number;
|
|
45
45
|
} | undefined;
|
|
46
|
-
kind?: "project" | "task" | "
|
|
46
|
+
kind?: "project" | "task" | "initiative" | "epic" | "issue" | undefined;
|
|
47
47
|
}>;
|
|
48
48
|
export type TodoSearchParams = z.infer<typeof TodoSearchParamsSchema>;
|
|
49
49
|
/** Search result item */
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate limiter for injection detection logging.
|
|
3
|
+
*
|
|
4
|
+
* Prevents log flooding when an attacker sends many injection-containing
|
|
5
|
+
* messages. Logs the first N detections per key (sender/userId) per window,
|
|
6
|
+
* then samples at a configurable rate. Emits summary entries for suppressed
|
|
7
|
+
* counts when a new window begins.
|
|
8
|
+
*
|
|
9
|
+
* Memory-bounded via maxEntries with LRU eviction of oldest keys.
|
|
10
|
+
*
|
|
11
|
+
* Issue #1257
|
|
12
|
+
*/
|
|
13
|
+
/** Configuration for the injection log rate limiter */
|
|
14
|
+
export interface InjectionLogRateLimiterConfig {
|
|
15
|
+
/** Sliding window duration in milliseconds */
|
|
16
|
+
windowMs: number;
|
|
17
|
+
/** Maximum number of log entries allowed per key per window before sampling */
|
|
18
|
+
maxLogsPerWindow: number;
|
|
19
|
+
/** Probability (0-1) of logging after exceeding maxLogsPerWindow */
|
|
20
|
+
sampleRate: number;
|
|
21
|
+
/** Maximum number of tracked key entries (LRU eviction when exceeded) */
|
|
22
|
+
maxEntries: number;
|
|
23
|
+
}
|
|
24
|
+
/** Result of a shouldLog check */
|
|
25
|
+
export interface InjectionLogResult {
|
|
26
|
+
/** Whether this detection should be logged */
|
|
27
|
+
log: boolean;
|
|
28
|
+
/** Number of suppressed detections (in the current or previous window) */
|
|
29
|
+
suppressed: number;
|
|
30
|
+
/** Whether this is a summary entry reporting prior-window suppressions */
|
|
31
|
+
summary: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Stats about the rate limiter's current state */
|
|
34
|
+
export interface InjectionLogRateLimiterStats {
|
|
35
|
+
/** Number of currently tracked keys */
|
|
36
|
+
activeKeys: number;
|
|
37
|
+
/** Total number of suppressed detections across all keys */
|
|
38
|
+
totalSuppressed: number;
|
|
39
|
+
}
|
|
40
|
+
/** Default configuration */
|
|
41
|
+
export declare const DEFAULT_INJECTION_LOG_RATE_LIMITER_CONFIG: InjectionLogRateLimiterConfig;
|
|
42
|
+
/** Injection log rate limiter instance */
|
|
43
|
+
export interface InjectionLogRateLimiter {
|
|
44
|
+
/** Check whether a detection for the given key should be logged */
|
|
45
|
+
shouldLog(key: string): InjectionLogResult;
|
|
46
|
+
/** Get current stats */
|
|
47
|
+
getStats(): InjectionLogRateLimiterStats;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create a new injection log rate limiter.
|
|
51
|
+
*
|
|
52
|
+
* @param config - Configuration overrides (defaults to DEFAULT_INJECTION_LOG_RATE_LIMITER_CONFIG)
|
|
53
|
+
* @param randomFn - Optional random function for testing (defaults to Math.random)
|
|
54
|
+
*/
|
|
55
|
+
export declare function createInjectionLogRateLimiter(config?: InjectionLogRateLimiterConfig, randomFn?: () => number): InjectionLogRateLimiter;
|
|
56
|
+
/**
|
|
57
|
+
* Shared singleton rate limiter for injection detection logging.
|
|
58
|
+
* All callsites in the plugin share this instance so that rate limiting
|
|
59
|
+
* is coordinated across tools and hooks within the same process.
|
|
60
|
+
*/
|
|
61
|
+
export declare const injectionLogLimiter: InjectionLogRateLimiter;
|
|
62
|
+
//# sourceMappingURL=injection-log-rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injection-log-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/utils/injection-log-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,uDAAuD;AACvD,MAAM,WAAW,6BAA6B;IAC5C,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,GAAG,EAAE,OAAO,CAAC;IACb,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,mDAAmD;AACnD,MAAM,WAAW,4BAA4B;IAC3C,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,4BAA4B;AAC5B,eAAO,MAAM,yCAAyC,EAAE,6BAKvD,CAAC;AAcF,0CAA0C;AAC1C,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAC3C,wBAAwB;IACxB,QAAQ,IAAI,4BAA4B,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,GAAE,6BAAyE,EACjF,QAAQ,GAAE,MAAM,MAAoB,GACnC,uBAAuB,CAyFzB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,yBAAkC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate limiter for injection detection logging.
|
|
3
|
+
*
|
|
4
|
+
* Prevents log flooding when an attacker sends many injection-containing
|
|
5
|
+
* messages. Logs the first N detections per key (sender/userId) per window,
|
|
6
|
+
* then samples at a configurable rate. Emits summary entries for suppressed
|
|
7
|
+
* counts when a new window begins.
|
|
8
|
+
*
|
|
9
|
+
* Memory-bounded via maxEntries with LRU eviction of oldest keys.
|
|
10
|
+
*
|
|
11
|
+
* Issue #1257
|
|
12
|
+
*/
|
|
13
|
+
/** Default configuration */
|
|
14
|
+
export const DEFAULT_INJECTION_LOG_RATE_LIMITER_CONFIG = {
|
|
15
|
+
windowMs: 60_000,
|
|
16
|
+
maxLogsPerWindow: 10,
|
|
17
|
+
sampleRate: 0.1,
|
|
18
|
+
maxEntries: 10_000,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Create a new injection log rate limiter.
|
|
22
|
+
*
|
|
23
|
+
* @param config - Configuration overrides (defaults to DEFAULT_INJECTION_LOG_RATE_LIMITER_CONFIG)
|
|
24
|
+
* @param randomFn - Optional random function for testing (defaults to Math.random)
|
|
25
|
+
*/
|
|
26
|
+
export function createInjectionLogRateLimiter(config = DEFAULT_INJECTION_LOG_RATE_LIMITER_CONFIG, randomFn = Math.random) {
|
|
27
|
+
const entries = new Map();
|
|
28
|
+
function now() {
|
|
29
|
+
return Date.now();
|
|
30
|
+
}
|
|
31
|
+
function evictIfNeeded() {
|
|
32
|
+
if (entries.size <= config.maxEntries)
|
|
33
|
+
return;
|
|
34
|
+
// Sort by lastSeen ascending (oldest first), evict until at maxEntries
|
|
35
|
+
const sorted = [...entries.entries()].sort((a, b) => a[1].lastSeen - b[1].lastSeen);
|
|
36
|
+
const toEvict = sorted.length - config.maxEntries;
|
|
37
|
+
for (let i = 0; i < toEvict; i++) {
|
|
38
|
+
entries.delete(sorted[i][0]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function shouldLog(key) {
|
|
42
|
+
const currentTime = now();
|
|
43
|
+
const existing = entries.get(key);
|
|
44
|
+
// Check if we need to start a new window
|
|
45
|
+
if (existing && currentTime - existing.windowStart >= config.windowMs) {
|
|
46
|
+
// Window expired — check if there were suppressions to report
|
|
47
|
+
const previousSuppressed = existing.suppressedCount;
|
|
48
|
+
// Reset to new window
|
|
49
|
+
existing.windowStart = currentTime;
|
|
50
|
+
existing.logCount = 1;
|
|
51
|
+
existing.suppressedCount = 0;
|
|
52
|
+
existing.lastSeen = currentTime;
|
|
53
|
+
if (previousSuppressed > 0) {
|
|
54
|
+
// Emit a summary log entry reporting previous window suppressions
|
|
55
|
+
return { log: true, suppressed: previousSuppressed, summary: true };
|
|
56
|
+
}
|
|
57
|
+
// Normal first log in new window, no summary needed
|
|
58
|
+
return { log: true, suppressed: 0, summary: false };
|
|
59
|
+
}
|
|
60
|
+
if (!existing) {
|
|
61
|
+
// First detection for this key
|
|
62
|
+
entries.set(key, {
|
|
63
|
+
windowStart: currentTime,
|
|
64
|
+
logCount: 1,
|
|
65
|
+
suppressedCount: 0,
|
|
66
|
+
lastSeen: currentTime,
|
|
67
|
+
});
|
|
68
|
+
evictIfNeeded();
|
|
69
|
+
return { log: true, suppressed: 0, summary: false };
|
|
70
|
+
}
|
|
71
|
+
// Within the same window
|
|
72
|
+
existing.lastSeen = currentTime;
|
|
73
|
+
if (existing.logCount < config.maxLogsPerWindow) {
|
|
74
|
+
// Still under the limit
|
|
75
|
+
existing.logCount++;
|
|
76
|
+
return { log: true, suppressed: 0, summary: false };
|
|
77
|
+
}
|
|
78
|
+
// Over the limit — apply sampling
|
|
79
|
+
existing.suppressedCount++;
|
|
80
|
+
if (config.sampleRate > 0 && randomFn() < config.sampleRate) {
|
|
81
|
+
// Sampled in — log it
|
|
82
|
+
existing.logCount++;
|
|
83
|
+
return { log: true, suppressed: existing.suppressedCount, summary: false };
|
|
84
|
+
}
|
|
85
|
+
// Suppressed
|
|
86
|
+
return { log: false, suppressed: existing.suppressedCount, summary: false };
|
|
87
|
+
}
|
|
88
|
+
function getStats() {
|
|
89
|
+
let totalSuppressed = 0;
|
|
90
|
+
for (const state of entries.values()) {
|
|
91
|
+
totalSuppressed += state.suppressedCount;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
activeKeys: entries.size,
|
|
95
|
+
totalSuppressed,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return { shouldLog, getStats };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Shared singleton rate limiter for injection detection logging.
|
|
102
|
+
* All callsites in the plugin share this instance so that rate limiting
|
|
103
|
+
* is coordinated across tools and hooks within the same process.
|
|
104
|
+
*/
|
|
105
|
+
export const injectionLogLimiter = createInjectionLogRateLimiter();
|
|
106
|
+
//# sourceMappingURL=injection-log-rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injection-log-rate-limiter.js","sourceRoot":"","sources":["../../src/utils/injection-log-rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,17 +3,42 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides layered defence for external message content before LLM exposure:
|
|
5
5
|
* 1. Unicode/control character sanitisation
|
|
6
|
-
* 2. Data boundary marking (spotlighting)
|
|
6
|
+
* 2. Data boundary marking (spotlighting) with per-session nonce
|
|
7
7
|
* 3. Suspicious pattern detection and logging
|
|
8
|
+
* 4. PromptGuard-2 classifier integration (optional, async)
|
|
8
9
|
*
|
|
9
|
-
* Issue #1224
|
|
10
|
+
* Issue #1224, #1255, #1256
|
|
10
11
|
*/
|
|
12
|
+
import { type PromptGuardResult } from './prompt-guard-client.js';
|
|
13
|
+
/** Boundary markers for external message content, keyed by per-session nonce */
|
|
14
|
+
export interface BoundaryMarkers {
|
|
15
|
+
/** Opening marker, e.g. `[EXTERNAL_MSG_a1b2c3d4_START]` */
|
|
16
|
+
start: string;
|
|
17
|
+
/** Closing marker, e.g. `[EXTERNAL_MSG_a1b2c3d4_END]` */
|
|
18
|
+
end: string;
|
|
19
|
+
/** The nonce embedded in the markers */
|
|
20
|
+
nonce: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create boundary markers with a per-session cryptographic nonce.
|
|
24
|
+
*
|
|
25
|
+
* If no nonce is provided, one is generated from 4 random bytes (8 hex chars).
|
|
26
|
+
* Callers should create markers once per session/hook invocation and reuse
|
|
27
|
+
* them for all messages in that session, rather than generating per-message.
|
|
28
|
+
*
|
|
29
|
+
* @throws {Error} If a provided nonce contains non-hex characters.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createBoundaryMarkers(nonce?: string): BoundaryMarkers;
|
|
11
32
|
/** Result of injection pattern detection */
|
|
12
33
|
export interface InjectionDetectionResult {
|
|
13
34
|
/** Whether any injection patterns were detected */
|
|
14
35
|
detected: boolean;
|
|
15
36
|
/** Names of the patterns that matched */
|
|
16
37
|
patterns: string[];
|
|
38
|
+
/** PromptGuard classifier result, if available (Issue #1256) */
|
|
39
|
+
classifier?: PromptGuardResult;
|
|
40
|
+
/** Detection source: 'regex' (default), 'classifier', or 'both' */
|
|
41
|
+
source?: 'regex' | 'classifier' | 'both';
|
|
17
42
|
}
|
|
18
43
|
/** Options for wrapping external messages */
|
|
19
44
|
export interface WrapOptions {
|
|
@@ -21,6 +46,8 @@ export interface WrapOptions {
|
|
|
21
46
|
channel?: string;
|
|
22
47
|
/** Sender name or identifier */
|
|
23
48
|
sender?: string;
|
|
49
|
+
/** Per-session nonce for boundary markers. If omitted, one is auto-generated. */
|
|
50
|
+
nonce?: string;
|
|
24
51
|
}
|
|
25
52
|
/** Options for context sanitisation */
|
|
26
53
|
export interface ContextSanitizeOptions {
|
|
@@ -30,6 +57,8 @@ export interface ContextSanitizeOptions {
|
|
|
30
57
|
channel?: string;
|
|
31
58
|
/** Sender name */
|
|
32
59
|
sender?: string;
|
|
60
|
+
/** Per-session nonce for boundary markers. If omitted, one is auto-generated. */
|
|
61
|
+
nonce?: string;
|
|
33
62
|
}
|
|
34
63
|
/**
|
|
35
64
|
* Sanitize external message content by removing control characters
|
|
@@ -44,7 +73,7 @@ export declare function sanitizeExternalMessage(text: string): string;
|
|
|
44
73
|
* the boundary wrapper header. Strips control chars, invisible Unicode,
|
|
45
74
|
* newlines (which could break out of the header line), and boundary markers.
|
|
46
75
|
*/
|
|
47
|
-
export declare function sanitizeMetadataField(field: string): string;
|
|
76
|
+
export declare function sanitizeMetadataField(field: string, nonce?: string): string;
|
|
48
77
|
/**
|
|
49
78
|
* Wrap external message content with data boundary markers.
|
|
50
79
|
*
|
|
@@ -54,6 +83,9 @@ export declare function sanitizeMetadataField(field: string): string;
|
|
|
54
83
|
*
|
|
55
84
|
* Content, sender, and channel are all sanitized and have boundary markers
|
|
56
85
|
* escaped before wrapping to prevent breakout attacks.
|
|
86
|
+
*
|
|
87
|
+
* When `options.nonce` is provided, markers use that nonce. Otherwise a
|
|
88
|
+
* fresh cryptographic nonce is generated per call.
|
|
57
89
|
*/
|
|
58
90
|
export declare function wrapExternalMessage(content: string, options?: WrapOptions): string;
|
|
59
91
|
/**
|
|
@@ -68,6 +100,26 @@ export declare function wrapExternalMessage(content: string, options?: WrapOptio
|
|
|
68
100
|
* to prevent Unicode obfuscation from bypassing detection.
|
|
69
101
|
*/
|
|
70
102
|
export declare function detectInjectionPatterns(text: string): InjectionDetectionResult;
|
|
103
|
+
/** Options for async injection detection */
|
|
104
|
+
export interface AsyncDetectionOptions {
|
|
105
|
+
/** PromptGuard service base URL (e.g. http://localhost:8190) */
|
|
106
|
+
promptGuardUrl?: string;
|
|
107
|
+
/** Timeout for classifier requests in milliseconds (default 500ms) */
|
|
108
|
+
classifierTimeoutMs?: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Detect suspicious prompt injection patterns using both regex and
|
|
112
|
+
* (optionally) the PromptGuard-2 classifier.
|
|
113
|
+
*
|
|
114
|
+
* When `promptGuardUrl` is configured, the classifier is called in parallel
|
|
115
|
+
* with regex scanning. If the classifier is unavailable or times out,
|
|
116
|
+
* the function gracefully falls back to regex-only results.
|
|
117
|
+
*
|
|
118
|
+
* Detection remains monitoring-only (no blocking).
|
|
119
|
+
*
|
|
120
|
+
* Issue #1256
|
|
121
|
+
*/
|
|
122
|
+
export declare function detectInjectionPatternsAsync(text: string, options?: AsyncDetectionOptions): Promise<InjectionDetectionResult>;
|
|
71
123
|
/**
|
|
72
124
|
* Sanitize message content for safe inclusion in LLM context.
|
|
73
125
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injection-protection.d.ts","sourceRoot":"","sources":["../../src/utils/injection-protection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"injection-protection.d.ts","sourceRoot":"","sources":["../../src/utils/injection-protection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEhF,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;CACf;AAKD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAUrE;AAsFD,4CAA4C;AAC5C,MAAM,WAAW,wBAAwB;IACvC,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gEAAgE;IAChE,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,CAAC;CAC1C;AAED,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACrC,wBAAwB;IACxB,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACnC,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAuBD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAmBtF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAc9E;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAqCvI;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAQvG"}
|