wiki.pl: Port some fixes from upstream
[Orgmuse.git] / modules / honeypot.pl
blob97639f1fd12cfe0d5dc3ce78e7ee017d7cc38eda
1 =head1 NAME
3 honeypot - an Oddmuse module that reduces wiki spam
5 =head1 SYNOPSIS
7 This module adds parameters to the page edit form. These parameters are special
8 because they are invisible to humans (using style information). If a spam bot
9 sets these parameters to anything, the edit will be rejected. Another hidden
10 parameter contains a timestamp. If a spam bot plays back recorded actions and
11 provides the timestamp of the recording, the edit will be rejected because it is
12 too old.
14 More information:
15 L<http://nedbatchelder.com/text/stopbots.html>
17 =head1 INSTALLATION
19 Installing a module is easy: Create a modules subdirectory in your
20 data directory, and put the Perl file in there. It will be loaded
21 automatically.
23 =cut
25 $ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/honeypot.pl">honeypot.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Comments_on_Monitor_Extension">Comments on Monitor Extension</a></p>';
27 =head1 CONFIGURATION
29 =head2 $HoneyPotOk and $HoneyPotTimestamp
31 C<$HoneyPotOkThis> is used to hold the timestamp. If a form is posted with a
32 timestamp older than C<$HoneyPotTimestamp> seconds, it will be rejected.
34 Example:
36 $HoneyPotOkThis = 'friend';
37 $HoneyPotTimestamp = 6 * 60 * 60; # six hours
39 By default, the parameter is called "ok" and the timestamp may not be older than
40 one hour (3600 seconds).
42 =head2 $HoneyPotIdiot1 and $HoneyPotIdiot2
44 These two variables should not be posted or they should be empty. Providing any
45 values will result in the form being rejected.
47 Example:
49 $HoneyPotIdiot1 = 'spam';
50 $HoneyPotIdiot2 = 'scum';
52 By default, these have the values of "idiot" and "looser", for obvious reasons.
54 =cut
56 package OddMuse;
58 use vars qw($HoneyPotOk $HoneyPotIdiot $HoneyPotTimestamp);
60 $HoneyPotOk = 'ok';
61 $HoneyPotIdiot1 = 'idiot';
62 $HoneyPotIdiot2 = 'looser';
63 $HoneyPotTimestamp = 3600;
65 *HoneyPotOldGetFormStart = *GetFormStart;
66 *GetFormStart = *HoneyPotNewGetFormStart;
68 my $HoneyPotWasHere = 0;
70 sub HoneyPotNewGetFormStart {
71 my $html = HoneyPotOldGetFormStart(@_);
72 my ($ignore, $method) = @_;
73 return $html unless not $method or lc($method) eq 'post';
74 if (not $HoneyPotWasHere) {
75 $HoneyPotWasHere = 1;
76 $html .= '<div style="display: none">';
77 $html .= $q->textfield({-name=>$HoneyPotOk, -id=>$HoneyPotOk,
78 -default=>time,
79 -size=>40, -maxlength=>250}) if $HoneyPotOk;
80 $html .= $q->label({-for=>$HoneyPotIdiot1}, 'Leave empty:'), ' ',
81 $q->textfield({-name=>$HoneyPotIdiot1, -id=>$HoneyPotIdiot1,
82 -size=>40, -maxlength=>250}) if $HoneyPotIdiot1;
83 $html .= $q->textarea(-name=>$HoneyPotIdiot2, -id=>$HoneyPotIdiot2,
84 -rows=>5, -columns=>78) if $HoneyPotIdiot2;
85 $html .= '</div>';
87 return $html;
90 # kill requests that contain the idiot or looser parameters
91 # and requests that have a timestamp that is too old
93 push(@MyInitVariables, \&HoneyPotInspection);
95 sub HoneyPotInspection {
96 if (not UserIsEditor()
97 # we're making an edit
98 and GetParam('title', '')
99 # override from questionasker.pl
100 and not ($QuestionaskerRememberAnswer and GetParam($QuestionaskerSecretKey, 0))
101 # the parameters we use in our form
102 and (GetParam($HoneyPotIdiot1) or GetParam($HoneyPotIdiot2)
103 or ($HoneyPotOk
104 and $Now - GetParam($HoneyPotOk) > $HoneyPotTimestamp))) {
105 ReportError(T('Edit Denied'), '403 FORBIDDEN');
109 =head1 COPYRIGHT AND LICENSE
111 Copyright (C) 2011 Alex Schroeder <alex@gnu.org>
113 This program is free software: you can redistribute it and/or modify it under
114 the terms of the GNU General Public License as published by the Free Software
115 Foundation, either version 3 of the License, or (at your option) any later
116 version.
118 This program is distributed in the hope that it will be useful, but WITHOUT ANY
119 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
120 PARTICULAR PURPOSE. See the GNU General Public License for more details.
122 You should have received a copy of the GNU General Public License along with
123 this program. If not, see <http://www.gnu.org/licenses/>.
125 =cut