-
-
Save jknezek-locktera/f355371af152b4469772ded0f20de314 to your computer and use it in GitHub Desktop.
WebKit postMessage(CryptoKey) reproduction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"/> | |
<meta name="viewport" content="width=device-width"/> | |
<title>Service Worker Bug Reproduction</title> | |
</head> | |
<body> | |
<script type="module"> | |
navigator.serviceWorker.addEventListener('message', async (e) => { | |
console.log('message from service worker:', e.data); | |
const password_string = 'password'; | |
const password_bytes = new TextEncoder().encode(password_string); | |
const password_key = await crypto.subtle.importKey('raw', password_bytes, 'PBKDF2', false, ['deriveKey']); | |
const salt = crypto.getRandomValues(new Uint8Array(16)); | |
const derived_key = await crypto.subtle.deriveKey({ | |
name: 'PBKDF2', | |
hash: 'SHA-512', | |
salt: salt, | |
iterations: 200_000, // 100ms | |
}, password_key, { | |
name: 'AES-GCM', | |
length: 256, | |
}, false, ['encrypt', 'decrypt']); | |
console.log('posting response:', derived_key); | |
e.data.postMessage(derived_key); | |
console.log('posting repsonse:', 'no key'); | |
e.data.postMessage('no key'); | |
}); | |
const registration = await navigator.serviceWorker.register(new URL('./sw.js', window.location.href).pathname, { type: 'module' }); | |
await registration.update(); | |
await navigator.serviceWorker.ready; | |
const rsp = await fetch('sw.js'); | |
console.log('response:', rsp); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
self.addEventListener('install', (e) => { | |
e.waitUntil(self.skipWaiting()); | |
}); | |
self.addEventListener('activate', (e) => { | |
e.waitUntil(self.clients.claim()); | |
}); | |
self.addEventListener('fetch', (e) => { | |
console.log('fetch event:', e); | |
e.respondWith((async () => { | |
const client = await self.clients.get(e.clientId); | |
if (!client) return await fetch(e.request); | |
const response_promise = new Promise(resolve => { | |
const channel = new MessageChannel(); | |
channel.port1.onmessage = (e) => { | |
resolve(e.data); | |
}; | |
client.postMessage(channel.port2, [channel.port2]); | |
}); | |
const response = await response_promise; | |
console.log('response:', response); | |
return await fetch(e.request); | |
})()); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment