Files
oddmuse/modules/honeypot.pl
2015-08-18 10:48:03 +02:00

128 lines
4.0 KiB
Perl

use strict;
use v5.10;
=head1 NAME
honeypot - an Oddmuse module that reduces wiki spam
=head1 SYNOPSIS
This module adds parameters to the page edit form. These parameters are special
because they are invisible to humans (using style information). If a spam bot
sets these parameters to anything, the edit will be rejected. Another hidden
parameter contains a timestamp. If a spam bot plays back recorded actions and
provides the timestamp of the recording, the edit will be rejected because it is
too old.
More information:
L<http://nedbatchelder.com/text/stopbots.html>
=head1 INSTALLATION
Installing a module is easy: Create a modules subdirectory in your
data directory, and put the Perl file in there. It will be loaded
automatically.
=cut
AddModuleDescription('honeypot.pl', 'Comments on Monitor Extension');
=head1 CONFIGURATION
=head2 $HoneyPotOk and $HoneyPotTimestamp
C<$HoneyPotOkThis> is used to hold the timestamp. If a form is posted with a
timestamp older than C<$HoneyPotTimestamp> seconds, it will be rejected.
Example:
$HoneyPotOkThis = 'friend';
$HoneyPotTimestamp = 6 * 60 * 60; # six hours
By default, the parameter is called "ok" and the timestamp may not be older than
one hour (3600 seconds).
=head2 $HoneyPotIdiot1 and $HoneyPotIdiot2
These two variables should not be posted or they should be empty. Providing any
values will result in the form being rejected.
Example:
$HoneyPotIdiot1 = 'spam';
$HoneyPotIdiot2 = 'scum';
By default, these have the values of "idiot" and "looser", for obvious reasons.
=cut
our ($q, $Now, @MyInitVariables, $QuestionaskerRememberAnswer, $QuestionaskerSecretKey);
our ($HoneyPotOk, $HoneyPotIdiot, $HoneyPotTimestamp, $HoneyPotIdiot1, $HoneyPotIdiot2);
$HoneyPotOk = 'ok';
$HoneyPotIdiot1 = 'idiot';
$HoneyPotIdiot2 = 'looser';
$HoneyPotTimestamp = 3600;
*HoneyPotOldGetFormStart = \&GetFormStart;
*GetFormStart = \&HoneyPotNewGetFormStart;
my $HoneyPotWasHere = 0;
sub HoneyPotNewGetFormStart {
my $html = HoneyPotOldGetFormStart(@_);
my ($ignore, $method) = @_;
return $html unless not $method or lc($method) eq 'post';
if (not $HoneyPotWasHere) {
$HoneyPotWasHere = 1;
$html .= '<div style="display: none">';
$html .= $q->textfield({-name=>$HoneyPotOk, -id=>$HoneyPotOk,
-default=>time,
-size=>40, -maxlength=>250}) if $HoneyPotOk;
$html .= $q->label({-for=>$HoneyPotIdiot1}, 'Leave empty:') . ' ' .
$q->textfield({-name=>$HoneyPotIdiot1, -id=>$HoneyPotIdiot1,
-size=>40, -maxlength=>250}) if $HoneyPotIdiot1;
$html .= $q->textarea(-name=>$HoneyPotIdiot2, -id=>$HoneyPotIdiot2,
-rows=>5, -columns=>78) if $HoneyPotIdiot2;
$html .= '</div>';
}
return $html;
}
# kill requests that contain the idiot or looser parameters
# and requests that have a timestamp that is too old
push(@MyInitVariables, \&HoneyPotInspection);
sub HoneyPotInspection {
if (not UserIsEditor()
# we're making an edit
and GetParam('title', '')
# override from questionasker.pl
and not ($QuestionaskerRememberAnswer and GetParam($QuestionaskerSecretKey, 0))
# the parameters we use in our form
and (GetParam($HoneyPotIdiot1) or GetParam($HoneyPotIdiot2)
or ($HoneyPotOk
and $Now - GetParam($HoneyPotOk) > $HoneyPotTimestamp))) {
ReportError(T('Edit Denied'), '403 FORBIDDEN');
}
}
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2011 Alex Schroeder <alex@gnu.org>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
=cut