Zum Inhalt

Modul: Makler-Newsmodul

Stand

Code-Analyse vom 2026-04-22 gegen sachpool.de, WebEdition 9.2.3, PHP 8.3.

Zweck

Eigenes CRUD-Modul für Branchen-News-Beiträge im Login-Bereich. Nur eigene Beiträge sichtbar/editierbar. Nutzt die Klasse branchennews (classid 1, 136 Objekte) mit autorenid-Filter pro eingeloggtem Vermittler.

Template-Struktur

Fünf Templates nach CRUD-Muster:

Tpl-ID Pfad Funktion
229 makler-beitrag-uebersicht.tmpl Liste aller Beiträge (R-ead)
234 makler-beitrag-erstellen.tmpl Neuer Beitrag (C-reate)
232 makler-beitrag-editieren.tmpl Bearbeiten (U-pdate)
235 makler-beitrag-sichtbarkeit.tmpl Publish/Unpublish
233 makler-beitrag-loeschen.tmpl Löschen (D-elete)

Übersichts-Template (229)

Datenbank-Filter: <we:condition> mit Zugriff auf $sach_userid:

<we:condition name="condition">
  <we:conditionAdd field="autorenid" var="sach_userid" compare="="/>
</we:condition>

<we:listview type="object" classid="1" condition="$condition" searchable="false">
  <we:repeat>
    <we:field name="WE_ID" />
    <we:field type="date" name="datum" />
    <we:field name="headline" />
    <we:field name="teaser" />
    ...
  </we:repeat>
</we:listview>

Pro Zeile:

  • Edit-Icon (<i class="fas fa-pen-square">) → <we:a edit="object" id="39530"> öffnet das Bearbeiten-Dokument
  • Preview-Icon (<i class="fas fa-search">) → WE_PATH in neuem Tab
  • Auskommentiert: Löschen, Publish-Toggle (werden derzeit nicht angeboten)
  • publish==0 Zeile: Text wird muted gerendert (<tr class="text-muted">)

Dokument-IDs im Einsatz:

  • 39530 — Editieren-Dokument
  • 39817 — (auskommentiert) Löschen-Endpoint
  • 39818 — „Neuen Beitrag"-Button-Ziel (vermutlich Dokument für Template 234)
  • 39820 — Sichtbarkeits-Toggle-Endpoint

Datenmodell: Klasse branchennews (classid 1)

Felder (aus Templates ableitbar):

Feld Rolle
WE_ID, WE_PATH System
datum Veröffentlichungsdatum
headline Titel
teaser Kurztext (Übersicht)
autorenid Filter-Feld — FK auf eingeloggten Vermittler ($sach_userid)
publish 0 / 1 — Sichtbarkeits-Flag
...weitere... Inhalte, Bilder, Tags (noch nicht vollständig analysiert)

CRUD-Templates (232, 233, 234, 235)

Template 234 — Erstellen (<we:form type="object">)

Das Create-Formular ist ein gekapselter WebEdition-Objekt-Form:

<we:form type="object" classid="1" parentid="535" enctype="multipart/form-data">
  <we:userInput type="date"     name="datum" currentdate="true" />
  <we:userInput type="textinput" name="headline" maxlength="160" />
  <we:userInput type="img"      name="img"  parentid="39824" />
  <we:userInput type="textinput" name="teaser" maxlength="160" />
  <we:userInput type="textarea" name="text" wysiwyg="true" />
  <we:userInput type="binary"   name="datei" parentid="39825" accept=".pdf" />
  <we:userInput type="textinput" name="dateibeschreibung" />
  <we:userInput type="checkbox"  name="publish" />
  <we:userInput type="hidden"    name="autorenid" value="$sach_userid" />
</we:form>

Objekte landen unter parentid=535 (Workspace Login-Bereich), Bilder in Ordner 39824, PDFs in 39825.

Template 232 — Editieren

Identische Felder wie Create, aber:

  • Objekt wird per GET we_editObject_ID geladen
  • datum bleibt currentdate="true"überschreibt Publikationsdatum bei jedem Save (Bug, → HANDLUNGSEMPFEHLUNGEN.md)
  • autorenid wieder als hidden-Feld mit $sach_userid

Template 233 — Löschen

<we:object id="$newsid">
  <we:setVar nameto="current_news_valid" to="global" value="1" varType="bool" />
</we:object>
<we:ifVar match="1" name="current_news_valid" ...>
  <we:delete type="object" classid="1" forceedit="true" pid="535" id="$newsid" />
</we:ifVar>

Template 235 — Sichtbarkeit

Nutzt we_objectFile::we_publish() / we_unpublish():

<we:object classid="1" id="$publishid">
  <we:field name="autorenid" nameto="autorenid" to="global" />
</we:object>
<?php
$obj = new we_objectFile();
$obj->initByID($publishid);
if ($_GET['action'] == 'publish') $obj->we_publish();
else $obj->we_unpublish();
?>

Berechtigungsmodell

  • Lesen (Übersicht 229): <we:condition> filtert sauber auf autorenid = $sach_userid.
  • Erstellen (234): autorenid wird serverseitig als hidden auf $sach_userid gesetzt — sauber, solange niemand das Feld aus dem Formular manipuliert.
  • Editieren / Löschen / Publish (232/233/235): Kein Owner-Check. Die Templates laden das Zielobjekt per URL-ID und führen die Aktion aus, sobald das Objekt existiert — die autorenid des Zielobjekts wird nie gegen $sach_userid geprüft.
  • Sachpool-Redakteure: Backend-Zugriff auf alle 136 Objekte der Klasse.

Kritische IDOR-Kette

Ein Angreifer kann durch Manipulation der we_editObject_ID / newsid / publishid fremde Beiträge lesen, ändern, löschen und publizieren. Beim Save übernimmt er zusätzlich die Autorenschaft (hidden autorenid=$sach_userid überschreibt die ursprüngliche). Fix: Owner-Prüfung in allen vier Modify-Templates. Details in HANDLUNGSEMPFEHLUNGEN.md.

Einstiegspunkte

Dokument Template Funktion
— (Dashboard-Quicklink) Verlinkt auf Doc 39528 (/_login/maklernews/) Index
Doc 39528 229 (Übersicht) Liste eigener Beiträge
Doc 39530 232 (Editieren) Bearbeiten
Doc 39818 234 (Erstellen) Neuer Beitrag
Doc 39817 233 (Löschen) Delete-Endpoint
Doc 39820 235 (Sichtbarkeit) Publish/Unpublish-Toggle

Zusätzlich gibt es die öffentliche News-Seite (Template index-branchennews_intern.tmpl, ID 124) unter „Meine Daten → Branchennews", die nur publizierte Beiträge (aller Autoren) zeigt.

Siehe auch