1RateLimit(3)          User Contributed Perl Documentation         RateLimit(3)
2
3
4

NAME

6       CGI::Application::Plugin::RateLimit - limits runmode call rate per user
7

SYNOPSIS

9         use CGI::Application::Plugin::RateLimit;
10
11         sub setup {
12           ...
13
14           # call this in your setup routine to set
15           my $rate_limit = $self->rate_limit();
16
17           # set the database handle to use
18           $rate_limit->dbh($dbh);
19
20           # set the table name to use for storing hits, the default is
21           # 'rate_limit_hits'
22           $rate_limit->table('rate_limit_hits');
23
24           # keep people from calling 'send' more often than 5 times in 10
25           # minutes and 'list' more often than once every 5 seconds.
26           $rate_limit->protected_modes(send => {timeframe => '10m',
27                                                 max_hits  => 5
28                                                },
29                                        list => {timeframe => '5s',
30                                                 max_hits  => 1
31                                                });
32
33           # you can also protect abstract actions, for example to prevent a
34           # flood of failed logins
35           $rate_limit->protected_actions(failed_login => {timeframe => '10s',
36                                                           max_hits  => 2
37                                                          });
38
39           # call this runmode when a violation is detected
40           $rate_limit->violation_mode('too_fast_buddy');
41
42           # or, run this callback
43           $rate_limit->violation_callback(sub { die(...) });
44
45           # override the default identity function
46           # ($ENV{REMOTE_USER} || $ENV{REMOTE_IP})
47           $rate_limit->identity_callback(sub { ... });
48         }
49
50         # record a hit for an action (not needed for run-modes which are
51         # handled automatically)
52         $rate_limit->record_hit(action => 'failed_login');
53
54         # check for a violation on an action and handle
55         return $self->slow_down_buddy
56           if( $rate_limit->check_violation(action => 'failed_login') );
57
58         # revoke the most recent hit for this user, preventing it from
59         # counting towards a violation
60         $rate_limit->revoke_hit();
61
62         # examine the violation in violation_mode or violation_callback:
63         $mode   = $rate_limit->violated_mode;
64         $action = $rate_limit->violated_action;
65         $limits = $rate_limit->violated_limits;
66

DESCRIPTION

68       This module provides protection against a user calling a runmode too
69       frequently.  A typical use-case might be a contact form that sends
70       email.  You'd like to allow your users to send you messages, but
71       thousands of messages from a single user would be a problem.
72
73       This module works by maintaining a database of hits to protected
74       runmodes.  It then checks this database to determine if a new hit
75       should be allowed based on past activity by the user.  The user's
76       identity is, by default, tied to login (via REMOTE_USER) or IP address
77       (via REMOTE_IP) if login info is not available.  You may provide your
78       own identity function via the identity_callback() method.
79
80       To use this module you must create a table in your database with the
81       following schema (using MySQL-syntax, although other DBs may work as
82       well with minor alterations):
83
84         CREATE TABLE rate_limit_hits (
85            user_id   VARCHAR(255)      NOT NULL,
86            action    VARCHAR(255)      NOT NULL,
87            timestamp UNSIGNED INTEGER  NOT NULL,
88            INDEX (user_id, action, timestamp)
89         );
90
91       You may feel free to vary the storage-type and size of user_id and
92       action to match your usage.  For example, if your identity_callback()
93       always returns an integer you could make user_id an integer column.
94
95       This table should be periodically cleared of old data.  Anything older
96       than the maximum timeframe being used can be safely deleted.
97
98       IMPORTANT NOTE: The protection offered by this module is not perfect.
99       Identifying a user on the internet is very hard and a sophisticated
100       attacker can work around these checks, by switching IPs or automating
101       login creation.
102

INTERFACE

104       The object returned from calling "$self->rate_limit" on your CGI::App
105       object supports the following method calls:
106
107   dbh
108          $rate_limit->dbh($dbh);
109
110       Call this to set the database handle the object should use.  Must be
111       set in setup().
112
113   table
114          $rate_limit->table('some_table_name');
115
116       Call this to determine the table to be used to store and lookup hits.
117       The default is 'rate_limit_hits' if not set.  See the DESCRIPTION
118       section for the required table schema.
119
120   protected_modes
121           $rate_limit->protected_modes(send => {timeframe => '10m',
122                                                 max_hits  => 5
123                                                },
124                                        list => {timeframe => '5s',
125                                                 max_hits  => 1
126                                                });
127
128       Takes a list of key-value pairs describing the modes to protect.  Keys
129       are names of run-modes.  Values are hashes with the following keys:
130
131         timeframe - the timeframe to be considered for violations.  Values
132         must be numbers followed by either 's' for seconds, 'm' for minutes
133         or 'h' for hours.
134
135         max_hits - how many hits to allow in the specified timeframe before
136         triggering a violation.
137
138   protected_actions
139           $rate_limit->protected_actions(failed_login => {timeframe => '10s',
140                                                           max_hits  => 2
141                                                          });
142
143       Specifies non-run-mode actions to protect.  These are arbitrary keys
144       you can use with record_hit() and check_violation().  Takes the same
145       data-structure as protected_modes().
146
147   violation_mode
148         $rate_limit->violation_mode('too_fast_buddy');
149
150       Call to set a run-mode to call when a violation is triggered.  Either
151       this or violation_callback must be set.
152
153   violation_callback
154           $rate_limit->violation_callback(sub { ... });
155
156       Callback to call when a violation is detected.  Should either throw an
157       exception or return the run-mode to run.  Called with the CGI::App
158       object as its sole parameter.
159
160   identity_callback
161           $rate_limit->identity_callback(sub { ... });
162
163       Call this to provide a customized mechanism for determining the
164       identity of the user.  The default is:
165
166         sub { $ENV{REMOTE_USER} || $ENV{REMOTE_IP} }
167
168       You might consider adding in session-ID or a hook to your
169       authentication system if it doesn't use REMOTE_USER.  Whatever you
170       write should return a single scalar which is expected to be unique to
171       each user.
172
173   record_hit
174         $rate_limit->record_hit(action => 'failed_login');
175
176       Record a hit for an arbitrary action.  This is not needed for run-mode
177       protection.  Takes the action name as an argument, which must match an
178       action registered with protected_actions().
179
180   check_violation
181         return $self->slow_down_buddy
182           if( $rate_limit->check_violation(action => 'failed_login') );
183
184       Checks for a violation of a protected action.  This is not needed for
185       run-mode protection.  Takes the action name as an argument, which must
186       match an action registered with protected_actions().
187
188       Returns 1 if a violation took place, 0 otherwise.
189
190   revoke_hit
191         $rate_limit->revoke_hit();
192
193       Revokes the last hit for this user.  You might use this to prevent
194       validation errors from counting against a user, for example.
195
196   violated_mode
197         $mode = $rate_limit->violated_mode;
198
199       Returns the mode for the last violation, or undef if an action caused
200       the violation.
201
202   violated_action
203         $mode = $rate_limit->violated_action;
204
205       Returns the action for the last violation, or undef if an action caused
206       the violation.
207
208   violated_limits
209         $limits = $rate_limit->violated_limits;
210
211       Returns the hash-ref passed to protected_actions() or protected_modes()
212       for the violated mode/action.
213

DATABASE SUPPORT

215       I've tested this module with MySQL and SQLite.  I think it's likely to
216       work with many other databases - please let me know if you try one.
217

SUPPORT

219       Please send questions and suggestions about this module to the
220       CGI::Application mailing-list.  To join the mailing list, simply send a
221       blank message to:
222
223         cgiapp-subscribe@lists.erlbaum.net
224

VERSION CONTROL

226       This module is in a public Subversion repository at SourceForge here:
227
228          https://svn.sourceforge.net/svnroot/html-template/trunk/CGI-Application-Plugin-RateLimit
229

BUGS

231       I know of no bugs.  If you find one, let me know by filing a report on
232       http://rt.cpan.org.  Failing that, you can email me at sam@tregar.com.
233       Please include the version of the module you're using and small test
234       case demonstrating the problem.
235

AUTHOR

237       Sam Tregar, sam@plusthree.com
238
240       Copyright (C) 2006 by Sam Tregar
241
242       This library is free software; you can redistribute it and/or modify it
243       under the same terms as Perl itself, either Perl version 5.8.6 or, at
244       your option, any later version of Perl 5 you may have available.
245
246
247
248perl v5.36.0                      2023-01-20                      RateLimit(3)
Impressum