diff --git a/core/ui/viewer.html b/core/ui/viewer.html index 4a45d4a..09d2954 100644 --- a/core/ui/viewer.html +++ b/core/ui/viewer.html @@ -364,7 +364,7 @@ diff --git a/src/webviewMessageHandler.ts b/src/webviewMessageHandler.ts index f62117a..e862b1c 100644 --- a/src/webviewMessageHandler.ts +++ b/src/webviewMessageHandler.ts @@ -21,13 +21,14 @@ interface WebviewLegacyRpcMessage { function isWebviewRpcInvokeMessage(message: unknown): message is WebviewRpcInvokeMessage { if (!message || typeof message !== 'object') return false; - const msg = message as Record; - return msg.channel === 'rpc' && msg.content?.kind === 'invoke'; + const msg = message as Record; + const content = msg.content as Record | undefined; + return msg.channel === 'rpc' && content?.kind === 'invoke'; } function isWebviewLegacyRpcMessage(message: unknown): message is WebviewLegacyRpcMessage { if (!message || typeof message !== 'object') return false; - const msg = message as Record; + const msg = message as Record; return msg.type === 'rpc-request'; } @@ -81,9 +82,9 @@ export class WebviewMessageHandler { // SECURITY: Block Object.prototype methods to prevent prototype pollution attacks. // Allow class prototype methods (e.g., HostBridge.initialize) but reject inherited // Object methods like 'constructor', '__defineGetter__', 'toString'. - if (!BLOCKED_METHODS.has(targetMethod) && targetMethod in hostBridge && typeof (hostBridge as Record)[targetMethod] === 'function') { - const fn = (hostBridge as Record)[targetMethod]; - Promise.resolve(fn.apply(hostBridge as any, deserializedPayload)) + if (!BLOCKED_METHODS.has(targetMethod) && targetMethod in hostBridge && typeof (hostBridge as unknown as Record)[targetMethod] === 'function') { + const fn = (hostBridge as unknown as Record)[targetMethod] as Function; + Promise.resolve(fn.apply(hostBridge as unknown, deserializedPayload)) .then(result => { // Serialize result to handle Uint8Array and other typed arrays // which get converted to {} by postMessage JSON serialization @@ -131,9 +132,9 @@ export class WebviewMessageHandler { const hostBridge = this.hostBridge; // SECURITY: Same prototype pollution guard as #handleRpcInvoke if (BLOCKED_METHODS.has(message.method) || !(message.method in hostBridge)) return; - const fn = (hostBridge as Record)[message.method]; + const fn = (hostBridge as unknown as Record)[message.method]; if (typeof fn === 'function') { - Promise.resolve(fn.apply(hostBridge as any, deserializeArgs(message.args || []))) + Promise.resolve((fn as Function).apply(hostBridge as unknown, deserializeArgs(message.args || []))) .then(result => { // Serialize result to handle Uint8Array const serializedResult = serializeValue(result); diff --git a/website/public/sqlite-viewer/viewer.html b/website/public/sqlite-viewer/viewer.html index a4add1a..29c4347 100644 --- a/website/public/sqlite-viewer/viewer.html +++ b/website/public/sqlite-viewer/viewer.html @@ -364,7 +364,7 @@