I was going to write a patch for this, but D8 is now moved to an OOP way of doing this, and it's too much learning, so I figured I'd still explain my point. I'm going to do it from a D7 perspective, because it's easier for me, but it still applies to D8 (or D9, since feature requests are over).
flood_is_allowed() is a pretty simple function which helps us detect actions per amount of time, based off a single identifier. Currently the default identifier is ip address. We currently use this on items like signup & contact form.
The problem is it's not very robust. It's obviously been ported over from version to version of Drupal with the sole purpose of restricting by IP address.
If we could detect off multiple identifiers it could be a very useful entry point other modules could use for spam detection.
I would suggest something more like this.
flood_is_allowed($name, $threshold, $window, array $identifier);
For all core modules which use flood_is_allowed, their calls would be modified as such.
flood_is_allowed('contact', 5, 3600, array('ip' => ip_address()));
The {flood} table would need to be modified to include the key => value pairs as well. It would look something like this.
+-----+---------+------+---------------+------------+------------+
| fid | event | type | value | timestamp | expiration |
+-----+---------+------+---------------+------------+------------+
| 1 | contact | ip | 192.168.2.131 | 1354601670 | 1354605270 |
+-----+---------+------+---------------+------------+------------+
1 row in set (0.00 sec)
flood_clear_event() and flood_register_event() would also need to be modified to take key => value pairs as well.
That would allow you to register events which over more than a single case to prevent more spam.
For instance contact floods could be done as
flood_register_event('contact', 3600, array('ip' => ip_address(), 'uid' => $user->uid));
then tests could be written as
flood_is_allowed('contact', 5, 3600, array('ip' => ip_address(), 'uid' => $user->uid));
If either IP or UID tests fail for the counts, then the function would return false and spam would be prevented. This could also be expanded to other cases.
Ideally some extensibility would be provided as well for site developers like me, who would like to add something like an additional UID check....via a hook.
I think you can do this currently if you call flood_is_allowed with unique identifiers like 'uid-$uid', but it would be much better if it was keyed.
Something a little more robust could probably be thought up, but I wanted to get my thoughts into an issue. Feel free to discuss different methods would could prove more robust.
Semi related issue:
π
Missing critical way to alter flood protection before it denies
Closed: outdated