GSB 7.0 Standardlösung

Schutzmechanismen

Um Formulare gegen eine unberechtigte Nutzung durch SPAM-BOTs oder andere Automatismen zu schützen, können in der Standardlösung nun entsprechende Schutzmechanismen für Formulare konfiguriert werden.

Captcha

Beim Schutzmechanismus Captcha wird in das Formular ein zusätzliches Element mit entsprechendem Feld-Validator integriert. Dieses gibt dann ein dynamisch generiertes Bild - das sog. Captcha- sowie ein Eingabefeld aus. Um das Formular zu versenden, muss nun durch den Website-Nutzer der im Captcha dargstellte Text im Eingabefeld hinterlegt werden. Andernfalls wird eine entsprechende Fehlerseite ausgegeben.

JCaptcha

Die JCaptcha-Validierung wird lokal in der GSB-Infrastruktur durchgeführt und erfordert keine Kommunikation mit externen Servern wie bei der ReCaptcha-Validierung.

GSB-SL Konfiguration

In der Standardlösung findet sich eine exemplarische Konfiguration eines JCaptcha-Formulars im Dokument /standardlsg/SiteGlobals/Forms/Kontakt/Kontakt_JCaptcha_Formular.

Grundsätzlich benötigt das JCaptcha zwei Formularfelder (Dokumenttyp: HFTextInputField) für die Erzeugung und Validierung des Captchas. Das erste Formularfeld (Dokument: Kontakt_JCaptcha_SessionID) enthält als verstecktes Formularfeld die SessionID des jeweiligen Nutzers, das zweite Feld (Dokument: Kontakt_JCaptcha) beinhaltet das eigentliche Captcha.

Die Einbindung der Captcha-Formularfelder kann dem folgenden Screenshot entnommen werden. Die beiden JCaptcha-Formularelemente sind farblich umrandet dargestellt:

JCaptcha Formular JCaptcha Formular

Das Formularfeldes "Kontakt_JCaptcha_SessionID" wird wie folgt definiert:

JCaptcha SessionID JCaptcha SessionID

Das eigentliche Captcha-Formularfeld "Kontakt_JCaptcha" wird wie folgt definiert. Hierbei ist insbesondere die Einbindung des JCaptcha-Validators wichtig (im Screenshot farblich umrandet):

Kontakt JCaptcha Kontakt JCaptcha

HONEY-POT

Beim Schutzmechanismus HONEY-POT wird in das Formular ebenfalls ein zusätzliches Feld mit entsprechendem Feld-Validator integriert. Dieses wird jedoch nur einem SPAM-BOT oder andere Automatismen, nicht aber einem Website-Nutzer dargestellt. Screenreader, die die "display:none"-Spezifikation in CSS2.1 korrekt umsetzen, ignorieren das Feld ebenfalls.

SPAM-BOTs oder andere Automatismen neigen dazu, alle Felder eines Formulars zu befüllen. Beim Versenden des Formulars prüft nun der Validator des HONEY-POT-Felds, ob der Inhalt weiterhin leer ist. Wurde das Feld von einem Automatismus befüllt, wird keine Nachricht an den Formular-Empfänger gesendet.

GSB-SL Konfiguration

In der Standardlösung findet sich eine exemplarische Konfiguration eines HONEY-POT-Formulars im Dokument /standardlsg/SiteGlobals/Forms/Kontakt/Kontakt_Honeypot_Formular. Bei der Konfiguration der Formularactions muss darauf geachtet werden, dass die Honey-Pot-Action als erste Action in das Formular eingebunden wird:

HoneyPot Formular

Die Formularaction wird wie folgt konfiguriert:

HoneyPotAction HoneyPotAction

CSRF-Zugriffsschutz

Cross-Site-Request-Forgery-Angriffe oder Session-Riding-Attacken sind problematisch, da der Angreifer eine vorhandene Session des Opfers für einen Angriff nutzen kann. Details zu CSRF finden sich auf bzw. auf

Ein Schutz vor CSRF wird über ein Shared-Secret-Token realisiert, welches in der Session und in den Formularen oder Links gespeichert wird. Beim Abschicken eines Formulars werden die beiden Token (Formular, Session) verglichen. Stimmen sie nicht überein, so handelt es sich um einen Angriff.

Im GSB wird der Schutz für einzelne Formulare konfiguriert (Property „HFForm.csrfProtection“).

Beim Rendern des Formulars wird das Token aus der Session gelesen, bzw. wird beim ersten Zugriff ein Token erzeugt und in der Session gespeichert.

Beim Abschicken eines geschützten Formulars wird das Formular- mit dem Session-Token verglichen. Stimmen die Token nicht überein, wird dies als Attacke gewertet. Das Abschicken des Formulars wird verhindert, dem Nutzer wird eine Fehlerseite präsentiert. So wird sichergestellt, dass ein Angreifer eine vorhandene Session eines Opfers nicht für eine unberechtigte Ausführung von Formular gestützten Aktionen nutzen kann.

Funktionsweise

In jedem geschützten Request wird ein versteckter Parameter mit einem Token mitgesendet. Dieser wird im HFForm-Template renderStandardHiddenFields erzeugt, sofern die Property csrfProtection einen Wert > 0 hat.

Wenn die HFForm-Property csrfProtection den Wert 1 hat, wird das Token beim ersten Rendern eines betroffenen Formulars erzeugt und in der Benutzersession gespeichert. Es wird dann für alle Formulare dieser Session verwendet.

Wenn die HFForm-Property csrfProtection den Wert 2 hat, wird das Token statt in der Session im Cookie mit dem Namen csrfToken gesucht. Dieses kann es durch ein clientseitiges Javascript gesetzt worden sein (Stichwort "Double Submit Cookies"). Dieses Verfahren wird jedoch nicht empfohlen, da es keinen echten Schutz bietet.

Wenn die HFForm-Property csrfProtection den Wert 3 hat, wird das Token in der Datenbank gesucht. Gültige Tokens werden anschließend aus der Datenbank gelöscht. Daher können sie im Gegensatz zu den Session-Tokens nur ein einziges Mal genutzt werden. Datenbank-Tokens sind mit einem Erstellungs-Datum versehen, das bei Bedarf von der ValidateTimedTokenAction ausgewertet werden kann.

Nach dem Absenden des Formulars wird vom Formular-Framework (Klasse CmsActionForm) geprüft, ob das Formular wirklich von der aktuellen Benutzersession abgesendet wurde. Das ist genau dann der Fall, wenn der Request-Parameter csrftoken mit dem in der Session gespeicherten Token übereinstimmt. Im Fehlerfall wird die globale ActionMessage invalidCSRFToken gesetzt. Die Formular-Actions werden dann nicht ausgeführt. Der Request wird auf die im Formular konfigurierte Fehlerseite weitergeleitet.

Cache-Problematik:

CSRF-geschützte Formulare können grundsätzlich nicht statisch (z.B. vom OSCache) gecached werden. Daher empfiehlt es sich, diese nie auf der Startseite eines Webauftritts oder eines Bereiches einzubinden.

Erweiterter Spamschutz mit Datenbank-Tokens

Die ValidateTimedTokenAction ist eine Formular-Action, mit der die Gültigkeitsdauer von Datenbank-CSRF-Tokens (HFForm.csrfProtection=3) geprüft werden kann.

Standardmäßig überprüft das Formular-Framework die übergebenen CSRF-Tokens (egal welchen Typs) lediglich darauf, ob sie valide sind. Da die Datenbank-Tokens aber auch mit einem Erstellungs-Zeitpunkt versehen sind, kann dieser anschließend mit Hilfe der ValidateTimedTokenAction geprüft werden. Zu diesem Zweck wird das Token (ein Objekt der Klasse BkcmsCsrfToken) im Request-Attribut CmsActionForm_csrfToken bereitgestellt.

Die Action kennt die folgenden Properties:

NameFunktion
minSecondsWenn seit Erstellung des Tokens nicht mindestens die hier angegebene Anzahl Sekunden vergangen ist, wird je nach Konfiguration entweder der Fehlercode tokenTooNew oder das Request-Attribut ValidateTimedTokenAction_TokenError mit dem Integer-Wert 2 gesetzt. Das Attribut kann von nachfolgenden Actions ausgewertet werden. Das geschieht beispielsweise beim Anlegen von Gästebuch-Einträgen, um zu schnell angelegte Einträge als möglichen Spam zu klassifizieren.
maxSecondsWenn seit Erstellung des Tokens mehr als die hier angegebene Anzahl Sekunden vergangen ist, wird je nach Konfiguration entweder der Fehlercode tokenTooOld oder das Request-Attribut ValidateTimedTokenAction_TokenError mit dem Integer-Wert 1 gesetzt. Das Attribut kann von nachfolgenden Actions ausgewertet werden.
ignoreErrorsStandardmäßig bricht die Formularbearbeitung ab, wenn das Token ungültig ist. Es wird ein Fehlercode gesetzt und die konfigurierte Fehlerseite angezeigt.
Wenn dagegen hier der Wert true angegeben wird, wird die Formularbearbeitung fortgesetzt und anstelle des Fehlercodes nur das Request-Attribut ValidateTimedTokenAction_TokenError gesetzt, auf das nachfolgende Actions reagieren können. Der Wert des Attributs ist vom Typ Integer (0=nicht gefunden, 1=zu alt, 2=zu neu).
Wenn ignoreErrors den Wert true hat, wird das unter errorForward konfigurierte Forward mit dem Default "failure" verwendet.
Wenn ignoreErrors den Wert false hat oder nicht definiert ist, wird das unter errorForward konfigurierte Forward mit dem Default "next" verwendet. Wenn man dort "success" einträgt, wird auf die Erfolgsseite weitergeleitet, ohne dass weitere Actions ausgeführt werden.
errorForwardHier kann das alternative Action-Forward konfiguriert werden, das im Fehlerfall verwendet werden soll. Wenn diese Property nicht definiert ist, ist der Defaultwert abhängig vom Wert der Property ignoreErrors entweder "failure" oder "next".