From 53a8aa3869cd39eb9c60c1594292f5fc7b37239b Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 18 May 2026 15:43:37 +0200 Subject: [PATCH] =?UTF-8?q?Verbessere=20die=20Handhabung=20von=20Anzeigenk?= =?UTF-8?q?noten:=20F=C3=BCge=20Logik=20hinzu,=20um=20Skripte=20sicher=20a?= =?UTF-8?q?uszuf=C3=BChren=20und=20Textknoten=20zu=20entfernen,=20um=20sic?= =?UTF-8?q?htbaren=20JS-Code=20zu=20vermeiden.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/HeaderAdBanner.vue | 97 ++++++++++++++++++++---- 1 file changed, 83 insertions(+), 14 deletions(-) diff --git a/client/src/components/HeaderAdBanner.vue b/client/src/components/HeaderAdBanner.vue index 49e38f0..9af808a 100644 --- a/client/src/components/HeaderAdBanner.vue +++ b/client/src/components/HeaderAdBanner.vue @@ -129,21 +129,90 @@ async function renderPropeller() { const observer = new MutationObserver(mutations => { for (const m of mutations) { for (const node of Array.from(m.addedNodes)) { - if (!(node instanceof HTMLElement)) continue; - const src = (node.tagName === 'IFRAME' && node.getAttribute('src')) || ''; - const isAdNode = src.includes('nap5k') || (node.dataset && node.dataset.zone === propSlotId) || /nap5k|propel|propeller|inpage|push/i.test(node.className + ' ' + node.id); - if (isAdNode) { - try { - placeholder.innerHTML = ''; - placeholder.appendChild(node); - node.style.maxWidth = '100%'; - node.style.display = 'block'; - observer.disconnect(); - try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {} - return; - } catch (e) { - console.warn('Failed to relocate ad node', e); + try { + // Handle text nodes that may contain raw script/HTML + if (node.nodeType === Node.TEXT_NODE) { + const txt = (node.nodeValue || '').trim(); + if (txt.includes(' 500) { + // remove large/raw script text nodes to avoid visible JS + node.parentNode && node.parentNode.removeChild(node); + } + continue; } + + if (!(node instanceof HTMLElement)) continue; + + // If element contains script tags, extract and execute them safely + const innerScripts = Array.from(node.querySelectorAll('script')); + if (innerScripts.length) { + for (const sc of innerScripts) { + try { + if (sc.src) { + const s2 = document.createElement('script'); + s2.src = sc.src; + s2.async = true; + document.head.appendChild(s2); + } else if (sc.textContent) { + const s2 = document.createElement('script'); + s2.textContent = sc.textContent; + document.head.appendChild(s2); + } + } catch (e) { + console.warn('execute inner script failed', e); + } + // remove the inline script node from original element to avoid visible code + sc.parentNode && sc.parentNode.removeChild(sc); + } + } + + // If the added node is a script element itself, execute safely via head insertion + if (node.tagName === 'SCRIPT') { + const src = node.getAttribute('src'); + if (src) { + const s2 = document.createElement('script'); + s2.src = src; + s2.async = true; + s2.onload = () => console.log('relocated script loaded', src); + s2.onerror = (e) => console.warn('relocated script failed', src, e); + document.head.appendChild(s2); + node.parentNode && node.parentNode.removeChild(node); + continue; + } else if (node.textContent) { + const s2 = document.createElement('script'); + s2.textContent = node.textContent; + document.head.appendChild(s2); + node.parentNode && node.parentNode.removeChild(node); + continue; + } + } + + // Detect iframe ad nodes or nodes with nap5k indicators + const iframe = node.tagName === 'IFRAME' ? node : node.querySelector && node.querySelector('iframe'); + const src = iframe ? (iframe.getAttribute('src') || '') : ''; + const isAdNode = src.includes('nap5k') || (node.dataset && node.dataset.zone === propSlotId) || /nap5k|propel|propeller|inpage|push/i.test((node.className || '') + ' ' + (node.id || '')); + if (isAdNode) { + try { + // move iframe/ad node into placeholder + placeholder.innerHTML = ''; + if (iframe && iframe.parentNode) { + placeholder.appendChild(iframe); + } else { + placeholder.appendChild(node); + } + const moved = placeholder.firstElementChild; + if (moved) { + moved.style.maxWidth = '100%'; + moved.style.display = 'block'; + } + observer.disconnect(); + try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {} + return; + } catch (e) { + console.warn('Failed to relocate ad node', e); + } + } + } catch (e) { + console.warn('mutation handler error', e); } } }