CMS:USER_TOKEN

Gibt das Sicherheits-Token (CSRF-Token) für ein Formular aus, das einen schreibenden CMS:USER_*-Befehl auslöst.

(CMS:USER_TOKEN [parameter=wert …])

Methode: Modules\Record\RecordUser::cmsToken()

Parameter

Parameter Wert Standard Pflicht Beschreibung
format "field" / "value" "field" field: verstecktes Eingabefeld <input type="hidden" name="_token">, der Wert mit htmlspecialchars maskiert. value: nur das Token (für Ajax), unmaskiert.
set Array-Index von $set – Die Ausgabe wird nicht ausgegeben, sondern in $set gespeichert. Das Token steht zusätzlich immer in $set['user_token'].
formguard true / false false true: zusätzlich Zeitstempel und ein unsichtbares Köderfeld ausgeben (Formularschutz gegen Robots).

Anwendung

Das Token verhindert, dass eine fremde Website im Namen Ihrer Besucher Formulare abschickt (Cross-Site Request Forgery): Anmelden, Registrieren, Passwort-Reset, Beiträge speichern oder löschen, Abmelden, Warenkorb ändern. Diese Befehle prüfen das Token und brechen ohne gültiges Token mit einer Meldung (Index token) ab:

Befehl geprüft
USER_LOGIN, USER_REGISTER, USER_PW, USER_INPUT, USER_2FA wenn submit gefüllt ist (die Anmeldung per hash nicht)
USER_LOGIN_CODE wenn submit oder resend gesetzt ist
USER_DELETE immer
USER_LOGOUT immer – mit submit nur, wenn submit gefüllt ist
USER_BASKET bei add, update, update_addon – load nicht; ohne gültiges Token wird nur gelesen

Das Token hängt an einem Cookie. Der erste Aufruf auf einer Seite muss deshalb vor jeder Ausgabe stehen – am Anfang des Templates (bzw. im Kopf-Include vor <!doctype>), mit set, damit dort nichts ausgegeben wird. Danach schreiben Sie (CMS:USER_TOKEN) in jedes Formular, das einen dieser Befehle auslöst:

(CMS:USER_TOKEN set=token)
<?php $submit = $_POST['submit'] ?? ''; ?>
(CMS:USER_LOGIN container=members submit="$submit" successtemplate=u_welcome)
<!doctype html>
…
<form method="post">
  (CMS:USER_TOKEN)
  <input name="data[nickname]"> <input type="password" name="data[password]">
  <button name="submit" value="1">Anmelden</button>
</form>

Formularschutz gegen Robots

(CMS:USER_TOKEN formguard=true) gibt zusätzlich einen signierten Zeitstempel und ein Köderfeld aus, das Besucher nicht sehen. Befehle mit formguard=true (CMS:USER_REGISTER, CMS:USER_PW, CMS:EMAIL) weisen das Formular ab, wenn das Köderfeld gefüllt ist oder es schneller als nach drei Sekunden bzw. später als nach einer Stunde abgeschickt wurde. Beide Zeiten stellt der Systemadministrator ein (user.formguard_min_seconds, formguard_max_seconds); für ein einzelnes Formular setzt formguard=5 am Befehl die Mindestzeit auf fünf Sekunden – etwa für ein langes Formular, das niemand in drei Sekunden ausfüllt. Das hält Robots auf, die blind jedes Formular füllen – kein Captcha, kein fremder Dienst. Ein externes Captcha kann der Systemadministrator zusätzlich anbinden (security.form_challenge); dessen Widget binden Sie dann selbst ein.

<form method="post">
  (CMS:USER_TOKEN formguard=true)
  …
</form>

Für Ajax-Aufrufe schicken Sie das Token als POST-Feld _token oder im Header X-Camindo-Token mit. Ein FormData aus einem Formular mit (CMS:USER_TOKEN) enthält es bereits:

<script>
fetch('/0,basket_api', {
  method: 'POST',
  headers: { 'X-Camindo-Token': '(CMS:USER_TOKEN format=value)' },
  body: new URLSearchParams({ product: 42 })
});
</script>

Steht der erste Aufruf zu spät, gibt es kein Token: an Stelle des Feldes steht ein HTML-Kommentar mit Hinweis, und das Formular scheitert mit der Meldung token.

Das Cookie (ucsrf) gilt für alle Formulare der Website und überlebt die Anmeldung. Im Query-String (GET) wird es nicht angenommen – schreibende Aktionen gehören in POST-Formulare.

Die Prüfung lässt sich je Befehl mit csrf=false abschalten, der Systemadministrator kann sie mit user.csrf = false global abschalten. Beides öffnet die Befehle für fremde Websites und ist nur für Übergangszeiten gedacht.


← Übersicht

Stand: camindo CMS 9.1.3