Skip to content

Commit af55262

Browse files
DreamLab-AI Mega-Sprintruvnet
andcommitted
security: whitelist message types in content script relay
Add an ALLOWED_TYPES whitelist to validate the type field from page events before forwarding to the background script. Previously, the type field came directly from the page with no validation, and the spread operator forwarded arbitrary fields, allowing a malicious page to invoke internal extension message handlers or inject unexpected data. Now only known NIP message types are forwarded, and only safe fields per message type are included in the forwarded message. Co-Authored-By: claude-flow <ruv@ruv.net>
1 parent b83f414 commit af55262

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

src/injected.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,17 +314,47 @@ script.onload = function () {
314314
};
315315
(document.head || document.documentElement).appendChild(script);
316316

317+
// Allowed message types that can be forwarded to the background script
318+
const ALLOWED_TYPES = new Set([
319+
'GET_PUBLIC_KEY',
320+
'SIGN_EVENT',
321+
'GET_RELAYS',
322+
'NIP04_ENCRYPT',
323+
'NIP04_DECRYPT',
324+
'NIP44_ENCRYPT',
325+
'NIP44_DECRYPT'
326+
]);
327+
317328
// Listen for requests from the injected script
318329
window.addEventListener('podkey-request', async (event) => {
319330
const { id, type, ...data } = event.detail;
320331

321332
console.log('[Podkey] Received request:', type, 'from page');
322333

334+
if (!ALLOWED_TYPES.has(type)) {
335+
console.warn('[Podkey] Rejected unknown request type:', type);
336+
window.dispatchEvent(new CustomEvent('podkey-response', {
337+
detail: { id, error: 'Unknown request type' }
338+
}));
339+
return;
340+
}
341+
342+
// Only forward known safe fields per message type
343+
const safeData = {};
344+
if (type === 'SIGN_EVENT' && data.event) {
345+
safeData.event = data.event;
346+
} else if ((type === 'NIP04_ENCRYPT' || type === 'NIP04_DECRYPT' ||
347+
type === 'NIP44_ENCRYPT' || type === 'NIP44_DECRYPT')) {
348+
if (data.peer) safeData.peer = String(data.peer);
349+
if (data.plaintext !== undefined) safeData.plaintext = String(data.plaintext || '');
350+
if (data.ciphertext !== undefined) safeData.ciphertext = String(data.ciphertext);
351+
}
352+
323353
try {
324-
// Forward to background script
354+
// Forward to background script with only validated fields
325355
const response = await chrome.runtime.sendMessage({
326356
type,
327-
...data,
357+
...safeData,
328358
origin: window.location.origin
329359
});
330360

0 commit comments

Comments
 (0)