Skip to content

Commit a3fcdb0

Browse files
secret-marsclaude
andauthored
fix(storage): escape SQL wildcards in KV prefix queries, log parse errors (#73)
C1: Escape `%`, `_`, and `\` in user-supplied prefix before building the LIKE clause in `kvList`, and add `ESCAPE '\\'` to the query so wildcard characters in key prefixes cannot bypass prefix-boundary filtering. C3: Add `console.warn` in `parseJsonField` and `parseStringArray` so corrupt stored values surface in Cloudflare Worker logs instead of silently returning null / []. Fixes #72. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e60974f commit a3fcdb0

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

src/durable-objects/StorageDO.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ function parseJsonField(value: unknown): Record<string, unknown> | null {
3636
if (!value) return null;
3737
try {
3838
return JSON.parse(value as string);
39-
} catch {
39+
} catch (e) {
40+
console.warn('parseJsonField: failed to parse stored JSON value', e);
4041
return null;
4142
}
4243
}
@@ -50,7 +51,8 @@ function parseStringArray(value: unknown): string[] {
5051
try {
5152
const parsed = JSON.parse(value as string);
5253
return Array.isArray(parsed) ? parsed : [];
53-
} catch {
54+
} catch (e) {
55+
console.warn('parseStringArray: failed to parse stored JSON array value', e);
5456
return [];
5557
}
5658
}
@@ -258,8 +260,9 @@ export class StorageDO extends DurableObject<Env> {
258260
const params: unknown[] = [];
259261

260262
if (options?.prefix) {
261-
query += " WHERE key LIKE ?";
262-
params.push(`${options.prefix}%`);
263+
query += " WHERE key LIKE ? ESCAPE '\\'";
264+
const escapedPrefix = options.prefix.replace(/[%_\\]/g, '\\$&');
265+
params.push(`${escapedPrefix}%`);
263266
}
264267
query += " ORDER BY key LIMIT ?";
265268
params.push(limit);

0 commit comments

Comments
 (0)