Form flood protection 

Ban clients that submit a form faster than a real visitor plausibly would. The extension ships a finisher for the TYPO3 Form Framework (EXT:form) that reports every submission of a form to the firewall. An allow2ban rule counts the submissions per client and bans the client once it crosses the threshold; the middleware then rejects further requests early, before TYPO3 boots.

The finisher counts every valid submission, not only suspicious ones: finishers run after the form validation, so rejected submissions are not counted. Unlike a honeypot or CAPTCHA, which target bots, it also stops real visitors who hammer a form. Use it alongside those measures, not instead of them.

Enable it 

  1. In Admin Tools > Settings > Extension Configuration > firewall, enable form flood protection. This registers an allow2ban rule named form-flood with the configured threshold (default 5 submissions), period (default 60 seconds), and ban duration (default 1 hour).
  2. In the form editor, add the Firewall: flood protection finisher to each form you want to protect.

Both steps are needed: without the rule, reported submissions are ignored; without the finisher, nothing reports. The client is identified by IP address, resolved with the same trusted-proxy handling as the rest of the firewall (see Trusted proxies).

Replace the default rule 

For full control over the rule, define form-flood in config/system/phirewall.php yourself. A rule from the configuration file always wins over the generated default:

$config->allow2ban->add(
    'form-flood',
    threshold: 3,
    period: 120,
    banSeconds: 7200,
    // Fed by the finisher; the rule never matches a request on its own.
    filter: static fn(): bool => false,
);
Copied!

Give a form its own counter 

By default every form using the finisher reports to the same form-flood rule, so their submissions share one counter per client: a visitor filling in several different forms counts towards a single limit, and the resulting ban applies site-wide. To count a form on its own, point its finisher at a separate allow2ban rule.

In the form editor, the Firewall: flood protection finisher has a Allow2ban rule identifier field. Enter a name other than form-flood (for example contact-form-flood) to give that form its own counter. The rule must exist, so define it in config/system/phirewall.php (the extension configuration only registers the default form-flood rule):

$config->allow2ban->add(
    'contact-form-flood',
    threshold: 3,
    period: 120,
    banSeconds: 7200,
    // Fed by the finisher; the rule never matches a request on its own.
    filter: static fn(): bool => false,
);
Copied!

A submission reported to a rule name that is not defined is ignored, so a typo in the field silently disables protection for that form; double-check the name matches the rule in phirewall.php.

Change the rule from code 

Before a submission is reported, the finisher dispatches the \Flowd\Typo3Firewall\Event\FloodProtectionFinisherTriggered event with the rule identifier the finisher resolved (the option above, or the default). A listener can change it, for example to derive the rule from the form, or set an empty identifier to skip the submission:

use Flowd\Typo3Firewall\Event\FloodProtectionFinisherTriggered;

final class UseStricterContactFormRule
{
    public function __invoke(FloodProtectionFinisherTriggered $event): void
    {
        $event->ruleIdentifier = 'contact-form-flood';
    }
}
Copied!

Register the class as an event listener in the Services.yaml of your site package. The rule it points to must be defined in config/system/phirewall.php.