Extend flood_is_allowed() to be used in contrib/core as a spam blocking function.

Created on 4 December 2012, over 12 years ago
Updated 3 August 2023, almost 2 years ago

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

✨ Feature request
Status

Postponed: needs info

Version

9.5

Component
BaseΒ  β†’

Last updated about 8 hours ago

Created by

πŸ‡¨πŸ‡¦Canada j0rd

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024