T03 · Remote Payload Retrieval and Execution
- Location
- net-loader.html:35
- Finding
- <![CDATA[Mutable Remote Code Execution Through JSONP and Untrusted Onchain HTML]]><![CDATA[ ## Vulnerability Details **File Location**: `net-loader.html:35-38`, `net-loader.html:92-104`, and `net-loader.html:116-136` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Complete Vulnerable Code Snippet ```javascript const CONFIG = { storageKey: 'okc-test', // LEFT-padded bytes32 of 'okc-test' keyBytes: '0x0000000000000000000000000000000000000000000000006f6b632d74657374', operator: '0x2460F6C6CA04DD6a73E9B5535aC67Ac48726c09b', // JSONP relay URL - bypasses iframe sandbox! relayUrl: 'https://okc-relay.vercel.app/api/rpc' }; ``` ```javascript // Check if HTML if (data.trim().startsWith('<!DOCTYPE') || data.trim().startsWith('<html')) { document.open(); document.write(data); document.close(); } else { content.textContent = data; } }; // Load content via JSONP relay function loadContent() { const status = document.getElementById('status'); debug('Loading via JSONP relay...'); debug('Key: ' + CONFIG.storageKey); const calldata = buildCalldata(CONFIG.keyBytes, CONFIG.operator); debug('Calldata: ' + calldata.slice(0, 20) + '...'); // Create script tag for JSONP const script = document.createElement('script'); const params = new URLSearchParams({ to: SIMPLE_STORAGE, data: calldata, callback: 'netProtocolCallback', chainId: '8453' }); script.src = CONFIG.relayUrl + '?' + params.toString(); script.onerror = function() { debug('Script load failed - relay might be down'); status.className = 'error'; status.textContent = 'Error: Could not reach relay'; }; debug('Loading: ' + script.src.slice(0, 60) + '...'); document.body.appendChild(script); } ``` The behavior is also explicitly recommended in `SKILL.md:450-454`, which instructs users to deploy the loader so that it retrieves and renders content through the JSONP relay. ### Technical Analysis The loader creates a `<script>` element whose source is a mutable, external ...[truncated 2948 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the JSONP mechanism and the recommendation to bypass iframe network restrictions. 2. Never load RPC data through a `<script>` element. Retrieve it as non-executable data through a controlled API or a narrowly scoped same-origin backend. 3. Authenticate retrieved content before use: - Require a signature from an explicitly trusted publisher. - Bind the signature to the chain ID, contract, key, operator, content hash, and version. - Reject content whose signer or expected hash is not preconfigured. 4. Do not pass untrusted HTML to `document.write()`. Render plain content through `textContent`. 5. If HTML rendering is required, place it in a separate sandboxed iframe without `allow-scripts`, `allow-same-origin`, forms, popups, top navigation, or wallet access. 6. Apply a restrictive Content Security Policy that disallows inline script, event handlers, arbitrary remote scripts, and unexpected network destinations. 7. Pin and independently verify any relay implementation and deployment. A source-code repository reference is not sufficient to authenticate the deployed endpoint. 8. Clearly document that blockchain data is public and untrusted, regardless of whether it passes an integrity hash check. ]]>
