T09 · Insecure Skill Coding Practices
- Location
skill.md:155- Finding
Unrestricted Cross-Window Theme Synchronization Messages
- Content
View full analysis
Vulnerability Details
File Location:
skill.md, lines 155-162 and 316-328
Vulnerability Type: Unvalidated cross-window messaging
Risk Level: LowVulnerable Code
javascript window.addEventListener('message', function (e) { if (e.data && e.data.type === 'pusa-theme') { const theme = e.data.theme; document.documentElement.setAttribute('data-theme', theme); localStorage.setItem('pusa-theme', theme); const btn = document.getElementById('themeToggle'); if (btn) btn.textContent = theme === 'dark' ? '☀️ 明亮' : '🌙 暗黑'; } });javascript const iframe = document.querySelector('#iframeContainer iframe'); if (iframe && iframe.contentWindow) { try { iframe.contentWindow.postMessage({ type: 'pusa-theme', theme: next }, '*'); } catch(e) {} }javascript iframe.onload = () => { const theme = document.documentElement.getAttribute('data-theme'); try { iframe.contentWindow.postMessage({ type: 'pusa-theme', theme }, '*'); } catch(e) {} };Technical Analysis
The prescribed message listener trusts any message whose payload contains a matching
type. It does not validatee.originore.source, and it does not restricte.data.themeto the expecteddarkandlightvalues. An untrusted window with a reference to the generated report can therefore supply an arbitrary string that is persisted inlocalStorageand assigned to the root element'sdata-themeattribute.The sending examples also use the wildcard target origin
'*'. If the iframe is navigated to an unexpected origin before a message is sent, that recipient can receive the theme synchronization payload.This does not directly establish script execution because the value is assigned through
setAttributeandtextContent, rather than inserted as executable HTML. The confirmed exposure is unauthorized cross-window state manipulation and overly broad message delivery.Att
...[truncated 1396 chars]
- Remediation
View remediation
Remediation Suggestions
-
Permit messages only from the exact trusted application origin:
javascript const TRUSTED_ORIGIN = 'https://reports.example.com'; window.addEventListener('message', function (e) { if (e.origin !== TRUSTED_ORIGIN) return; if (e.source !== window.parent) return; if (!e.data || e.data.type !== 'pusa-theme') return; if (!['dark', 'light'].includes(e.data.theme)) return; const theme = e.data.theme; document.documentElement.setAttribute('data-theme', theme); localStorage.setItem('pusa-theme', theme); const btn = document.getElementById('themeToggle'); if (btn) { btn.textContent = theme === 'dark' ? '☀️ Light' : '🌙 Dark'; } }); -
Replace wildcard target origins with the recipient's exact origin:
javascript iframe.contentWindow.postMessage( { type: 'pusa-theme', theme: next }, TRUSTED_ORIGIN ); -
Validate locally restored values before applying them:
javascript const stored = localStorage.getItem('pusa-theme'); const theme = stored === 'light' || stored === 'dark' ? stored : 'dark'; -
Verify that the iframe URL belongs to the expected origin before sending a message. Where feasible, also compare the incoming event's
sourcewith the known parent or iframe window. -
If cross-origin synchronization is unnecessary, remove
postMessagesynchronization entirely and keep theme selection local to each document.
-
