From de4f16fefa00f3b1949c6a8d87cd04573d1400a2 Mon Sep 17 00:00:00 2001 From: s4luorth Date: Sun, 7 Jun 2026 16:57:09 +0200 Subject: [PATCH] fix: scanner ignoriert metadaten-links (gmpg.org rel=profile); version 1.2.0 - Nur ladende (stylesheet/preload/icon/...) werden gezaehlt; rel=profile/canonical/pingback etc. (z.B. gmpg.org) sind keine Requests mehr. - Plugin-Version + Header auf 1.2.0 (passend zu readme), Changelog-Eintrag. Co-Authored-By: Claude Opus 4.8 --- gdpr-content-blocker/gdpr-content-blocker.php | 4 ++-- gdpr-content-blocker/readme.txt | 8 ++++++- license-backend/src/scan.js | 23 ++++++++++++++++--- license-backend/test/scan.test.mjs | 4 ++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/gdpr-content-blocker/gdpr-content-blocker.php b/gdpr-content-blocker/gdpr-content-blocker.php index b7a7884..f42cba5 100644 --- a/gdpr-content-blocker/gdpr-content-blocker.php +++ b/gdpr-content-blocker/gdpr-content-blocker.php @@ -3,7 +3,7 @@ * Plugin Name: GDPR Content Blocker * Plugin URI: https://lucas-orth.de * Description: DSGVO-konformer Consent-Blocker für externe iframes. Lädt Drittinhalte erst nach aktiver Einwilligung. - * Version: 1.1.0 + * Version: 1.2.0 * Author: Lucas Orth * Author URI: https://lucas-orth.de * Text Domain: gdpr-content-blocker @@ -15,7 +15,7 @@ defined( 'ABSPATH' ) || exit; -define( 'CB_VERSION', '1.1.0' ); +define( 'CB_VERSION', '1.2.0' ); define( 'CB_FILE', __FILE__ ); define( 'CB_DIR', plugin_dir_path( __FILE__ ) ); define( 'CB_URL', plugin_dir_url( __FILE__ ) ); diff --git a/gdpr-content-blocker/readme.txt b/gdpr-content-blocker/readme.txt index 143f8a9..99307fd 100644 --- a/gdpr-content-blocker/readme.txt +++ b/gdpr-content-blocker/readme.txt @@ -4,7 +4,7 @@ Tags: dsgvo, gdpr, consent, iframe, datenschutz, gdpr-content-blocker Requires at least: 6.0 Tested up to: 6.7 Requires PHP: 8.1 -Stable tag: 1.1.0 +Stable tag: 1.2.0 License: GPL-2.0-or-later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -93,6 +93,12 @@ ZIP muss einen Ordner `gdpr-content-blocker/` auf oberster Ebene enthalten. == Changelog == += 1.2.0 = +* Shortcodes in eigenen Tab; „Über das Plugin"-Tab +* Belegte Domains als Liste mit Papierkorb; Lizenz-Status live aktualisiert +* Pfeil-Icon zum Ein-/Ausklappen; diverse UI-Korrekturen +* Cache-Busting der Admin-Skripte + = 1.1.0 = * Vorlagen für Google Maps, YouTube, OpenStreetMap, Vimeo * Client-seitige Erkennung (Elementor-Videos, per JS nachgeladene iframes) diff --git a/license-backend/src/scan.js b/license-backend/src/scan.js index 9f492fc..1f9fcdc 100644 --- a/license-backend/src/scan.js +++ b/license-backend/src/scan.js @@ -13,6 +13,16 @@ function normHost(h) { return String(h || '').toLowerCase().replace(/:.*$/, '').replace(/^www\./, ''); } +// Only these values actually fetch/connect to a resource. +// Everything else (profile, canonical, alternate, pingback, EditURI, wlwmanifest, +// shortlink, https://api.w.org/, …) is pure metadata and triggers no request — +// e.g. gmpg.org via rel="profile" must NOT be reported. +const LINK_LOADING_RELS = new Set([ + 'stylesheet', 'preload', 'modulepreload', 'preconnect', 'dns-prefetch', + 'prefetch', 'prerender', 'icon', 'shortcut icon', 'apple-touch-icon', + 'apple-touch-icon-precomposed', 'mask-icon', 'manifest', 'fetch', +]); + /** Extract absolute resource URLs (with a type tag) from one HTML document. */ export function extractResources(html, baseUrl) { const out = []; @@ -23,9 +33,16 @@ export function extractResources(html, baseUrl) { const body = m[2]; let raw = ''; - if (tag === 'object') raw = attr(body, 'data'); - else if (tag === 'link') raw = attr(body, 'href'); - else raw = attr(body, 'src'); + if (tag === 'object') { + raw = attr(body, 'data'); + } else if (tag === 'link') { + // Skip metadata links that never load anything (rel="profile" etc.). + const rel = attr(body, 'rel').toLowerCase().trim(); + if (!LINK_LOADING_RELS.has(rel)) continue; + raw = attr(body, 'href'); + } else { + raw = attr(body, 'src'); + } if (!raw) continue; if (/^(data:|blob:|javascript:|mailto:|tel:|#|about:)/i.test(raw)) continue; diff --git a/license-backend/test/scan.test.mjs b/license-backend/test/scan.test.mjs index f939ab3..a78bb94 100644 --- a/license-backend/test/scan.test.mjs +++ b/license-backend/test/scan.test.mjs @@ -8,6 +8,8 @@ const ok = (name, cond, extra = '') => { const html = ` + + @@ -31,6 +33,8 @@ ok('finds external script (gtm)', resources.some((r) => r.type === 'script' && r ok('resolves relative script to absolute', resources.some((r) => r.url === 'https://example.com/wp-includes/js/jquery.js')); ok('finds external img', resources.some((r) => r.type === 'img' && r.url.includes('cdn.example.com'))); ok('finds link stylesheet', resources.some((r) => r.type === 'link' && r.url.includes('fonts.googleapis.com'))); +ok('ignores rel=profile (gmpg.org)', !resources.some((r) => r.url.includes('gmpg.org'))); +ok('ignores rel=canonical', !resources.some((r) => r.url.includes('other.example'))); ok('finds object data (vimeo)', resources.some((r) => r.type === 'object' && r.url.includes('player.vimeo.com'))); ok('ignores anchor href', !resources.some((r) => r.url.includes('twitter.com')));