Zum Inhalt

Modul: Vergleichsportale

Stand

Code-Analyse vom 2026-04-22 gegen Live-Instanz sachpool.de, WebEdition 9.2.3.0, PHP 8.3.29.

Zweck

Vergleichsportale sind externe Software-Produkte von Partnern (Covomo, Mr. Money, Thinksurance, Smart Insurtech, Softfair, Trixi, NAFI), die Sachpool seinen Vermittlern zugänglich macht — teils inklusive, teils lizenzpflichtig. Die Integration erfolgt über Single-Sign-On per signierten URLs oder iFrame-Einbettung mit übergebenen Vermittlerdaten.

Zugriff nur im Login-Bereich (Workspace 536).

Einstiegspunkte

Alle PHP-Dokumente liegen unter /_login/vergleichsportale/.

Doc-ID Pfad Partner-Template Integrations-Typ
546 index.php (Übersicht via Listview)
2543 covomo-portal.php 184 covomo.tmpl Redirect mit AES-verschlüsselten Daten
2724 mrmoney-portal.php 188 mrmoney.tmpl iFrame-Einbettung
2725 nafi-kfz-portal.php 189 nafi-kfz.tmpl
2712 thinksurance-portal.php 187 thinksurance.tmpl 4-stufiger cURL-Flow (Token/aToken/bToken)
2726 smart-insurtech-portal.php 206 freier-rechner-smart-insurtech.tmpl bzw. 190 smart-insurtech-legacy.tmpl
2727 softfair-portal.php 191 softfair.tmpl
2728 trixi-kfz-portal.php 192 trixi-kfz.tmpl
14621 freier-rechner.php

Alle acht portal-Dokumente sind publiziert (published = 1).

Datenmodell

Vergleichsportale sind Instanzen der Klasse software-tools (classid 4), angelegt im Workspace 35.

Wichtige Felder (aus Objekte & Klassen):

Feld Typ Rolle
input_name varchar Portalname
input_teaser varchar Kurzbeschreibung (unterhalb Titel)
img_img int Logo-Bild
text_text longtext Teaser-Text für „Mit Lizenz"-Zustand
text_text-intern longtext Interner Text nur für lizenzierte Nutzer
input_preis varchar Preis der Lizenz
input_preis-alt varchar Alter/durchgestrichener Preis (optional)
href_include-content text Ref. auf einzubettendes wE-Dokument (enthält i. d. R. iFrame oder Partner-Template-Aufruf)
checkbox_Lizenz tinyint(1) Lizenz erforderlich ja/nein
input_Lizenzname varchar(50) Name des Customer-Feldes, das den Lizenz-Status trägt
checkbox_verdeckteLizenz tinyint(1) Ohne Lizenz ganz unsichtbar (nicht als „Mit Lizenz" zeigen)
multiobject_ansprechpartner longtext Kontakt-Objekte
multiobject_WerbebannerObenMO/SeitlichMO longtext Werbebanner

Lizenzmodell

Drei Zustände pro Portal und Nutzer:

Zustand Bedingung Anzeige
INKLUSIVE Lizenz == 0 Grünes Badge. Zugang für alle eingeloggten Nutzer.
LIZENZIERT Lizenz == 1 UND Customer-Feld (laut Lizenzname) enthält ja Grünes Badge. Nutzer hat Lizenz, text-intern wird gerendert (enthält i. d. R. Link auf Partner-Template).
MIT LIZENZ Lizenz == 1 UND Customer-Feld enthält nicht ja Graues Badge. Preis-Box + Button „Software lizenzieren" (→ Dok 565) + text als Teaser.
versteckt verdeckteLizenz == 1 UND keine Lizenz Portal wird in Übersicht gar nicht gelistet.

Lizenz-Lookup-Mechanik (Indirektion)

Die Logik in _detail-vergleichsportal.tmpl (ID 149) und vergleichsportal-index.tmpl (ID 150):

<we:object name="software-tools" classid="4" id="$we_objectID">
  <we:field name="Lizenzname" nameto="sach_lizenzname" to="global" />
  <we:setVar to="global" nameto="userid" from="sessionfield" namefrom="ID" />
  <we:customer id="$userid">
    <we:field name="$sach_lizenzname" nameto="current_license" to="global" />
  </we:customer>
</we:object>

Der Objekt-Name Lizenzname hält den Namen eines Customer-Feldes (z. B. kategorie_VR_MrMoney). Über die Doppel-Indirektion wird dann im Customer dieser dynamisch benannte Feldinhalt gelesen. Wert "ja" = Lizenz vorhanden.

Vorteil: neue Portale erfordern nur einen neuen Eintrag in software-tools + ein neues Customer-Feld — keine Code-Änderung.

Offene Klärung

Welche Customer-Felder werden aktuell genutzt? → interne Datei OFFENE-FRAGEN.md im Repo-Root.

Übersichts-Template (vergleichsportal-index.tmpl, ID 150)

Rendert alle software-tools-Objekte aus Workspace 35 als Accordion-Karten:

  • Linke Sidebar (Desktop): flache Liste der Portale, Lizenz-Filter identisch
  • Haupt-Accordion: Karten mit Bild + Lizenz-Badge + Name + Preis (wenn nötig) + Teaser
  • Klick auf Karte → Detail-Seite (_detail-vergleichsportal.tmpl)

Detail-Template (_detail-vergleichsportal.tmpl, ID 149)

Zeigt ein einzelnes Portal:

  • Linke Spalte: Bild (320×213), Lizenz-Badge, Sachpool-Vermittlernummer
  • Rechte Spalte: Portalname, Preis/Lizenzieren-Button oder interner Text, include-content (eingebettetes wE-Dokument, enthält typischerweise den Partner-Template-Aufruf), Ansprechpartner

Pagination-Buttons oben (Prev/Next durch alle Portale — Bug: rendert Titel als href).

Partner-Templates (wie Partner angebunden sind)

Jedes Partner-Template liegt unter sachpool-portal/partnermodule/vergleichsportale/ und implementiert den Aufruf zum externen Partner-System.

Covomo (Template 184)

Technik: Clientseitiger Redirect mit AES-verschlüsseltem Data-Blob.

function encrypt($data, $key, $iv) {
    return base64_encode(openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv));
}

$data = [
    'id' => $array_owner["benutzer"],           // Vermittlerkennung
    'email' => $array_owner["email"],
    'form_of_address' => $array_owner["Anrede"],
    'first_name' => $array_owner["Vorname"],
    'last_name' => $array_owner["Nachname"],
    // ... Adresse, Telefon, IHK-Nr., Firma, Website
];
$arrParams = [
    'pool' => POOL_HASH,
    'data' => encrypt(http_build_query($data), $key, $iv),
];
$url = 'https://portal.covomo.de?' . http_build_query($arrParams);

Anschließend JS-Redirect via window.open(url, '_self') + Auto-Back.

Secrets hardcodiert: POOL_HASH, $key — siehe interne HANDLUNGSEMPFEHLUNGEN.md (Repo-Root). 🔴

Mr. Money (Template 188)

Technik: iFrame-Einbettung. Parameter mm_category, mm_headline, mm_height kommen über GET rein.

$link = "https://www.mr-money.de/cookievgl.php?sp=KATEGORIE&id=00203686&v_id=BENUTZERNAME";
$link = str_replace("KATEGORIE", $mm_category, $link);
$link = str_replace("BENUTZERNAME", $benutzer, $link);
$link = str_replace("PASSWORT", $sach_pass, $link);   // ← 🔴 Passwort im URL
echo "<iframe src='$link' width='750' height='$mm_height' ...>";

Security-Hinweis: $sach_pass wird direkt in die iFrame-URL eingebaut — landet in Browser-Historie, Referer, Partner-Logs. Das Link-Modul markiert %SACHPASS% bereits als nicht verwenden. 🔴

Thinksurance (Template 187)

Technik: 4-stufiger cURL-Workflow:

  1. POST /api/token mit hash + secret$token
  2. POST /api/account/get/tokens/$token$aToken
  3. POST /api/broker/get/$token mit bExternalId=$benutzer$bToken (oder POST /api/broker/set/$token zum Neu-Anlegen)
  4. POST /api/broker/fwd/$token mit bToken → Redirect-URL

Die finale URL wird per window.open(url, '_self') angesteuert.

Debug-Dumps bei Fehlern: print '<pre>'; print_r($response); print '</pre>'; — leakt API-Responses ins HTML. 🟡

Adcuri / Barmenia (Template 176 — Tarifrechner-Ordner, Doppelnutzung)

Siehe Tarifrechner.

Softfair / Trixi / NAFI / Smart Insurtech / Smart Insurtech Legacy

Templates 191 / 192 / 189 / 206 / 190 — analoges Schema, je nach Partner Redirect oder iFrame. Details werden in einer eigenen Runde nachgezogen.

Authentifizierungs-Variablen aus authorization.tmpl

Die Partner-Templates greifen auf die vom Kompatibilitätslayer bereitgestellten Variablen zu:

  • $benutzer — Vermittlernummer (Login-Name)
  • $sach_user / $sach_forename / $sach_surname — Nutzerdaten
  • $sach_firma, $sach_strasse, $sach_nr, $sach_plz, $sach_ort
  • $sach_mail, $sach_tel, $sach_fax, $sach_url
  • $sach_anrede, $sach_ihk_nr
  • $sach_passsensitiv, nicht verwenden außer für Legacy-Integrationen

Bekannte Altlasten

→ Vollständiger Audit-Katalog: interne Datei HANDLUNGSEMPFEHLUNGEN.md im Repo-Root

Kurzauszug:

  • 🔴🔴🔴 Hardcodierte Credentials in allen Partner-Templates (Adcuri, Baloise, Covomo, Thinksurance, Mr.Money) — zentral auslagern + rotieren
  • 🔴 Adcuri zeigt auf Integrations-URL (integration-i2-www.adcuri.de), nicht Produktion
  • 🔴 Mr.Money bekommt $sach_pass in der URL
  • 🟡 _detail-vergleichsportal.tmpl: Pagination nutzt Title statt URL
  • 🟡 _detail-tarifrechner.tmpl: Syntax-Fehler Z. 102 (fehlendes >)
  • 🟡 Thinksurance Debug-Dumps im Fehlerpfad
  • 🟡 Doppelter <we:object>-Lookup in _detail-tarifrechner.tmpl
  • 🟢 Tote Code-Blöcke, auskommentierte mysql_*-Reste in Covomo

Siehe auch