> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Sicherung Zahlungsvorgang gegen Brute-Force-Angriffe

> Wiederholte automatisierte Fehlversuche bei einer Zahlungsart erkennen und sperren, je Sitzung und je IP-Adresse, wahlweise mit CAPTCHA-Zwang.

Wer gestohlene Kreditkartennummern besitzt, weiß zunächst nicht, welche davon noch gültig sind. Um das herauszufinden, braucht er einen Shop, in dem er automatisiert eine Zahlung nach der anderen auslösen kann. Jeder Durchlauf kostet ihn nichts, Sie dagegen Rechenzeit, Gebühren beim Zahlungsdienstleister und im schlimmsten Fall Ihren Ruf als Händler.

Genau dagegen richtet sich dieses Feature. Es erkennt wiederholte fehlgeschlagene Zahlungsversuche und sperrt die betroffene Zahlungsart vorübergehend, ohne den Bestellvorgang insgesamt abzubrechen. Der Käufer kann jederzeit mit einer anderen Zahlungsart weitermachen.

## Wie der Schutz wirkt

Der Schutz arbeitet auf zwei Ebenen, die sich ergänzen.

| Ebene | Wirkung | Gemerkt wird |
| - | - | - |
| Sitzung | sperrt die Zahlungsart für diesen Browser und diese Sitzung | in der Sitzung selbst |
| IP-Adresse | sperrt die Zahlungsart für alle Anfragen von dieser IP-Adresse | in einer Datenbanktabelle |

Die Sitzungsebene allein reicht nicht aus. Ein automatisierter Angriff holt sich einfach eine neue Sitzung und zählt von vorn. Erst die IP-Ebene setzt dem eine Grenze, weil sie über Sitzungsgrenzen hinweg zählt.

Gesperrt wird immer nur die einzelne Zahlungsart, nie der Bestellvorgang. Wer versehentlich mehrfach eine falsche Kartennummer eingegeben hat, kann seine Bestellung weiterhin abschließen, nur eben beispielsweise per Rechnung oder Vorkasse. Das ist der Grund, warum die Hinweismeldungen im Template den Käufer ausdrücklich auf die anderen Zahlungsarten hinweisen sollten.

Zusätzlich lässt sich ab einer bestimmten Anzahl von Fehlversuchen ein CAPTCHA erzwingen. Das ist die mildere Stufe: Der Käufer wird nicht ausgesperrt, muss aber nachweisen, dass er keine Maschine ist.

## Schritt 1: Den Schutz in der `global.config` einrichten

Der Schutz wird im Abschnitt `<PaymentBruteForceProtection>` der `global.config` eingerichtet, nicht in der `shop.config`.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<PaymentBruteForceProtection>
   ProtectedPayments-List                    = 1,21
   BlockTimesPerSession-List                 = (5:300)(10:1800)(20:permanent)
   BlockTimesPerIP-List                      = (10:600)(25:3600)
   BlockTimesPerIP-ObservationWindowInMinutes = 60
   ForceCaptchaAfterXAttempts                = 3
   UseCaptcha                                = FriendlyCaptcha
   CaptchaErrorHandling                      = fail-open
</PaymentBruteForceProtection>
```

| Parameter | Bedeutung |
| - | - |
| `ProtectedPayments-List` | die zu schützenden Zahlungsarten, als **numerische Zahlungsarten-Codes**, durch Komma getrennt. Leerzeichen werden ignoriert |
| `BlockTimesPerSession-List` | die Sperrstufen je Sitzung |
| `BlockTimesPerIP-List` | die Sperrstufen je IP-Adresse |
| `BlockTimesPerIP-ObservationWindowInMinutes` | der Zeitraum, über den Fehlversuche einer IP-Adresse gezählt werden |
| `ForceCaptchaAfterXAttempts` | ab wie vielen Fehlversuchen ein CAPTCHA verlangt wird |
| `UseCaptcha` | welcher CAPTCHA-Dienst verwendet wird |
| `CaptchaErrorHandling` | wie sich der Shop verhält, wenn der CAPTCHA-Dienst nicht antwortet |

> [!WARNING]
>
> `ProtectedPayments-List` erwartet Zahlencodes, keine Namen. `CreditCard` schützt nichts, `1` schon. Die Codes entnehmen Sie der Referenz der Zahlungsarten. Eine Zahlungsart, die nicht in dieser Liste steht, ist von dem gesamten Feature nicht betroffen.

Referenz: [Zahlungsarten und ihre Codes](https://dokumentation.websale.de/v8s/materialien/zahlungsarten-codes.md)

### Die Sperrstufen schreiben

Beide Sperrlisten haben dasselbe Format. Jede Stufe steht in einem eigenen Klammerpaar, davor die Zahl der Fehlversuche, dahinter die Sperrzeit in Sekunden.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
BlockTimesPerSession-List = (5:300)(10:1800)(20:permanent)
```

Gelesen: Ab dem fünften Fehlversuch wird fünf Minuten gesperrt, ab dem zehnten eine halbe Stunde, ab dem zwanzigsten dauerhaft.

Es gilt immer die höchste Stufe, deren Schwelle erreicht ist. Die Reihenfolge in der Konfiguration spielt deshalb keine Rolle, Sie dürfen die Stufen auch unsortiert notieren. Lesbar bleibt es aufsteigend.

> [!WARNING]
>
> Verwenden Sie niemals `0` als Schwelle. Der Shop liest die Liste nur bis zur ersten Stufe mit der Schwelle `0`, alle folgenden Stufen fallen ersatzlos weg. Aus `(0:60)(10:600)` wird damit keine Sperre.
>
> `permanent` funktioniert nur in `BlockTimesPerSession-List`. In `BlockTimesPerIP-List` führt eine als `permanent` markierte Stufe dazu, dass **überhaupt keine** IP-Sperre gesetzt wird. Der Shop sperrt IP-Adressen bewusst nie dauerhaft, weil hinter einer IP-Adresse ganze Firmen oder Mobilfunknetze stehen können. Notieren Sie für die IP-Liste deshalb ausschließlich Sekundenwerte.

Die Sperrzeit ist auf 172800 Sekunden begrenzt, also auf 48 Stunden. Ein höherer Wert wird stillschweigend auf diese Grenze gesetzt. Dasselbe gilt für `BlockTimesPerIP-ObservationWindowInMinutes`, das auf 2880 Minuten begrenzt ist.

### Das Beobachtungsfenster

`BlockTimesPerIP-ObservationWindowInMinutes` legt fest, wie weit der Shop beim Zählen der Fehlversuche einer IP-Adresse zurückschaut. Bei `60` zählen nur die Fehlversuche der letzten Stunde.

Ein kurzes Fenster verzeiht schnell und trifft geteilte Anschlüsse seltener. Ein langes Fenster erkennt auch langsame, über Stunden verteilte Angriffe. Fangen Sie eher mit einer Stunde an und verlängern Sie erst, wenn Sie einen verteilten Angriff tatsächlich beobachten.

### Das CAPTCHA

`ForceCaptchaAfterXAttempts` legt fest, ab wie vielen Fehlversuchen der Käufer ein CAPTCHA lösen muss. `UseCaptcha` bestimmt den Dienst.

| Wert von `UseCaptcha` | Dienst |
| - | - |
| `ReCaptchaV3` | Google reCAPTCHA v3 |
| `FriendlyCaptcha` | Friendly Captcha |
| `CaptchaEU` | captcha.eu |

> [!WARNING]
>
> Nur diese drei Werte werden erkannt. Jede andere Schreibweise, auch ein Tippfehler wie `friendly-captcha`, schaltet das CAPTCHA stillschweigend ab. Es gibt dafür keine Fehlermeldung.

`CaptchaErrorHandling = fail-open` bestimmt, was passiert, wenn der CAPTCHA-Dienst selbst nicht erreichbar ist. Mit `fail-open` lässt der Shop den Käufer in diesem Fall durch. Das hält Ihren Shop bestellbar, wenn ein externer Dienst ausfällt, öffnet aber genau in diesem Moment die Tür. Ohne diesen Wert wird ein nicht prüfbares CAPTCHA als nicht bestanden gewertet.

## Schritt 2: Die Hinweismeldungen ins Template einbauen

Ergänzen Sie das Template der Bestellübersichtsseite, üblicherweise `ws_place_order.htm`, um die folgenden Meldungen. Sie gehören **außerhalb** des Formulars der Bestellübersicht.

| Tag | Wird angezeigt, wenn |
| - | - |
| `PBP-Blocked` | die aktuelle Zahlungsart gesperrt ist, aus welchem der beiden Gründe auch immer |
| `PBP-Blocked_infinite` | die Sperre für diese Sitzung dauerhaft ist |
| `PBP-Blocked_untilTimestamp` | ein Ende der Sperre feststeht. Als einzelnes Tag liefert es den Zeitpunkt als Unix-Zeitstempel |
| `PBP-Captcha_Needed` | der Käufer ein CAPTCHA lösen muss |
| `PBP-Captcha_Failed` | das CAPTCHA nicht bestanden wurde |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PBP-Blocked}
   <p>
      Eine Bezahlung mit der gewählten Zahlungsart "~WS-Payment~" ist leider
      vorübergehend nicht möglich. In dieser Sitzung gab es eine ungewöhnlich
      hohe Anzahl an fehlgeschlagenen Zahlungsversuchen. Aus Sicherheitsgründen
      haben wir die Bezahlung mit "~WS-Payment~" daher vorübergehend gesperrt.
   </p>

   {!PBP-Blocked_infinite}
      {PBP-Blocked_untilTimestamp}
         <p>
            Eine Zahlung mit "~WS-Payment~" ist bis
            ~DC-DateTime_setunixtimestamp($PBP-Blocked_untilTimestamp$)~
            ~DC-DateTime_hours~:~DC-DateTime_minutes~ Uhr am
            ~DC-DateTime_day~.~DC-DateTime_month~.~DC-DateTime_year~
            nicht möglich.
         </p>
      {/PBP-Blocked_untilTimestamp}

      <p>
         Versuchen Sie es nach Ablauf der Sperre erneut oder schließen Sie Ihre
         Bestellung mit einer anderen Zahlungsart ab.
      </p>
   {/!PBP-Blocked_infinite}

   {PBP-Blocked_infinite}
      <p>
         Für diese Sitzung ist eine Zahlung per "~WS-Payment~" leider dauerhaft
         deaktiviert. Bitte wählen Sie eine andere Zahlungsart, um Ihre
         Bestellung abzuschließen.
      </p>
   {/PBP-Blocked_infinite}
{/PBP-Blocked}

{PBP-Captcha_Needed}
   <p>
      Aufgrund mehrerer fehlgeschlagener Versuche beim Bezahlvorgang mit
      "~WS-Payment~" ist eine zusätzliche Verifizierung erforderlich. Bitte
      bestätigen Sie, dass Sie kein Roboter sind, indem Sie das CAPTCHA lösen.
      Sollte das nicht möglich sein, nutzen Sie bitte eine andere Zahlungsart.
   </p>
{/PBP-Captcha_Needed}

{PBP-Captcha_Failed}
   <p>
      Die Sicherheitsüberprüfung konnte leider nicht abgeschlossen werden. Das
      CAPTCHA wurde nicht erfolgreich bestätigt. Bitte versuchen Sie es erneut.
      Alternativ können Sie eine andere Zahlungsart wählen, um den Bestellvorgang
      abzuschließen.
   </p>
{/PBP-Captcha_Failed}
```

> [!WARNING]
>
> Die Verschachtelung von `PBP-Blocked_untilTimestamp` in `{!PBP-Blocked_infinite}` ist nicht Geschmackssache. Bei einer dauerhaften Sperre trägt der Shop intern trotzdem einen Endzeitpunkt ein, und der liegt rechnerisch viele Jahrzehnte in der Zukunft. Ohne die Verschachtelung würde der Käufer eine absurde Jahreszahl lesen.

Alle `PBP`-Tags beziehen sich immer auf die gerade gewählte Zahlungsart. `~WS-Payment~` in den Meldungen benennt deshalb genau die Zahlungsart, um die es geht. Ein zweiter Block für eine andere Zahlungsart ist nicht nötig.

## Schritt 3: Den Schutz testen

Sie können eine fehlgeschlagene Zahlung simulieren, ohne eine echte Zahlung auszulösen. Hängen Sie dazu an einen beliebigen Shop-Aufruf die beiden URL-Parameter `test=on` und `order-failed=on` an.

```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
https://www.ihr-shop.de/?test=on&order-failed=on
```

Die Bestellung schlägt beim Absenden fehl, und der Fehlversuchszähler des Schutzes wird hochgezählt. So prüfen Sie den CAPTCHA-Zwang und Ihre Hinweismeldungen, ohne auf echte Fehlversuche warten zu müssen.

Der Produktivbetrieb Ihres Shops wird dadurch nicht beeinflusst. Die Parameter wirken nur in dem Aufruf, an den Sie sie anhängen.

> [!WARNING]
>
> Testen Sie die IP-Sperre bewusst und nicht nebenbei. Sie gilt für Ihre IP-Adresse und damit möglicherweise für Ihr ganzes Büro. Wählen Sie für den Test eine Zahlungsart, die Sie nicht produktiv brauchen, oder eine kurze Sperrzeit.

## Was der Schutz nicht leistet

Der Schutz zählt Fehlversuche, er bewertet sie nicht. Er unterscheidet nicht zwischen einem Angreifer und einem Käufer, der seine Karte dreimal falsch abgetippt hat. Setzen Sie die Schwellen deshalb nicht zu niedrig an. Drei bis fünf Fehlversuche bis zum CAPTCHA und deutlich mehr bis zur ersten Sperre sind ein brauchbarer Anfang.

Ein verteilter Angriff über viele verschiedene IP-Adressen läuft an der IP-Ebene vorbei. Der Schutz erschwert automatisierte Angriffe erheblich, ersetzt aber nicht die Betrugserkennung Ihres Zahlungsdienstleisters.

## Verwandte Themen

* Wegweiser: [Sicherheitshinweis bei Online-Zahlungsarten](https://dokumentation.websale.de/v8s/zahlungsarten-anlegen/sicherheitshinweis-bei-online-zahlungsarten.md)
* Wegweiser: [Kreditkarte](https://dokumentation.websale.de/v8s/referenz/tags/cc.md)
* Wegweiser: [Bestellübersicht](https://dokumentation.websale.de/v8s/bestelluebersicht-bestelleingangsbestaetigung/bestaetigungs-e-mail-an-den-kaeufer.md), für das Template `ws_place_order.htm`


## Related topics

- [Shopkonfiguration global.config](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-global-config.md)
- [Anmeldung und Registrierung](https://dokumentation.websale.de/v8s/kundenkonto/anmeldung-registrierung.md)
- [general - Allgemeine Shopeinstellungen](https://dokumentation.websale.de/konfiguration/general-allgemeine-shopeinstellungen.md)
- [Formulare mit INQUIRY4](https://dokumentation.websale.de/v8s/upload-modul/formulare-mit-inquiry4.md)
- [LogManager (Logs)](https://dokumentation.websale.de/admin-interface/logmanager-logs.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.