I really don't think this is that hard, someone just needs to figure out how to do it and I am sure it would be immensely popular. While honeypot does work excellently, it still does not prevent the "tons" a requests that a bad bot hits a website with. On my site, a relatively popular pet related site I literally get thousands of banned posts a day, and multiple ones per minute/second. Check the screen shot:(might only show as an attachment)
Anyway this is a slow day, in either case while I am super happy that honeypot prevents a lot of garbage posts, it would be nice if bad bots could just be IP banned after their 1st, 2nd attempt etc. Let's face it, if someone or something is filling in a field that says "do not fill in you will be banned" then its probably a bot.
Looking through the code, I found the spot where honeypot checks the form for a submission or if the time is below the thresh hold:
function _honeypot_honeypot_validate($element, &$form_state) {
// Get the honeypot field value.
$honeypot_value = $element['#value'];
// Make sure it's empty.
if (!empty($honeypot_value)) {
_honeypot_log($form_state['values']['form_id'], 'honeypot');
form_set_error('', t('There was a problem with your form submission. Please refresh the page and try again.'));
}
}
* Validate honeypot's time restriction field.
*/
function _honeypot_time_restriction_validate($form, &$form_state) {
// Get the time value.
$honeypot_time = $form_state['values']['honeypot_time'];
// Get the honeypot_time_limit.
$time_limit = honeypot_get_time_limit($form_state['values']);
// Make sure current time - (time_limit + form time value) is greater than 0.
// If not, throw an error.
if (time() < ($honeypot_time + $time_limit)) {
_honeypot_log($form_state['values']['form_id'], 'honeypot_time');
$time_limit = honeypot_get_time_limit($form_state['values']);
$form_state['values']['honeypot_time'] = time();
form_set_error('', t('There was a problem with your form submission. Please wait @limit seconds and try again.', array('@limit' => $time_limit)));
}
}
/**
* Log blocked form submissions.
*
* @param $form_id
* Form ID for the form on which submission was blocked.
* @param $type
* String indicating the reason the submission was blocked. Allowed values:
* - 'honeypot'
* - 'honeypot_time'
*/
function _honeypot_log($form_id, $type) {
honeypot_log_failure();
if (variable_get('honeypot_log', 0)) {
$variables = array(
'%form' => $form_id,
'@cause' => ($type == 'honeypot') ? t('submission of a value in the honeypot field') : t('submission of the form in less than minimum required time'),
);
watchdog('honeypot', 'Blocked submission of %form due to @cause.', $variables);
}
return;
}
It would be nice if we could set a variable in the admin section similar to troll:
function troll_blacklist_punishment_form_submit($form, &$form_state) {
variable_set('troll_blacklist_mod_requests', $form_state['values']['mod_requests']);
variable_set('troll_blacklist_stutter', $form_state['values']['stutter']);
<strong> variable_set('troll_blacklist_alt_page', $form_state['values']['alt_page']);
variable_set('troll_blacklist_alt_url', $form_state['values']['alt_url']);</strong>
drupal_set_message(t('The settings have been updated.'));
Then call that variable when Honeypot checks to form state to see if it has been filled in and redirect them to a page the automatically blacklists them, similar to this function in troll:
function troll_boot() {
$ip = ip_address();
if (troll_is_blacklisted()) {
$alt_page = variable_get('troll_blacklist_alt_page', 0);
if ($alt_page) {
switch ($alt_page) {
case 'blank':
watchdog('troll', 'Alternate blank page displayed to @ip', array('@ip' => $ip), WATCHDOG_INFO);
exit;
break;
case '404':
// drupal_not_found() can make a mess in admin logs with watchdog()
drupal_set_header('HTTP/1.0 404 Not Found');
drupal_set_title(t('Page not found'));
watchdog('troll', 'Alternate 404 page displayed to @ip', array('@ip' => $ip), WATCHDOG_INFO);
print theme('page', '');
exit;
break;
case 'redirect':
// The default value of troll_blacklist_alt_url should not be an
// empty string because then we redirect to ourselves; so use 127.0.0.1.
$url = variable_get('troll_blacklist_alt_url', 'http://127.0.0.1');
watchdog('troll', '@ip redirected to @url', array('@ip' => $ip, '@url' => $url), WATCHDOG_INFO);
header('Location: '. $url);
exit;
break;
}
}
Granted the variable is already set in this case.. but we could add the redirect at the bottom of the Honeypot check form state to redirect them to a page like this:
goodbye_byatch.php
<?php
$filename = '/path/to/.htaccess'; // CHANGE IF NECESSARY
if ($fp = fopen($filename, 'a')) {
if (flock($fp, LOCK_EX)) {
$remote_addr = $_SERVER['REMOTE_ADDR'];
fwrite($fp, "deny from $remote_addr\n");
}
flock($fp, LOCK_UN);
fclose($fp);
}
header('HTTP/1.1 403 Forbidden');
echo "Forbidden!"; // Add any other HTML here
exit();
// EOF
?>
Which would automatically write their IP into the .htaccess and ban them. Thus saving my poor server, hundred, thousands, of failed form requests, and saving me hours of going through and manually banning the ips..
I'm not a php guy but maybe something along the lines of
function custom_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'form_set_error':
$form['#redirect'] = 'goodbye_byatch.php';
break;
}
}
Again I'm not a php guy so I may be way off with the above script idea.. but a simple redirect based upon whether they failed validation does not seem that difficult.
Ideas?
Comment | File | Size | Author |
---|---|---|---|
#28 | Spammer Ip Addresses.txt | 180.88 KB | zeroyon |
#10 | bad bot ips.txt | 3.47 KB | zeroyon |
badbotlog.png | 61.1 KB | zeroyon |
Comments
Comment #0.0
zeroyon CreditAttribution: zeroyon commentedformatting
Comment #1
zeroyon CreditAttribution: zeroyon commentedIn the time that it took me to write the above post:
My poor server, it would be so cool, if after the first attempt their IP was just banned...
Comment #2
zeroyon CreditAttribution: zeroyon commentedA temporary external solution that seems to work... but I'm sure this could be included in the module...
I created a file called byebye.php in it I put
I went into honeypot.module and added the following line around 198 and 220
I know its a cheap and unsophisticated hack (that to be honest I am not sure won't mess something else up) but it seems to be working as it is adding the following at the bottom of my .htaccess
deny from 120.28.225.250
deny from 173.83.251.72
deny from 173.246.46.224
deny from 195.14.0.201
Comment #3
zeroyon CreditAttribution: zeroyon commentedSeems to be working as it does not even give a spammer a chance to figure out what the hell happened.. One strike on the honeypot field and their out and banned from the server. "403 Denied, You do not have access to:"
Comment #4
geerlingguy CreditAttribution: geerlingguy commentedHaha, often those are the best :)
Anyways, I know some sites that simply have a custom module that looks at every blocked submission (you can hook into Honeypot's different actions—see the .api.php file with the module for more), and then bans people using Drupal's built in IP blocking system.
I might just need to work on making it easier to use this module along with Rules, Troll, or other modules to hook in and ban a user based on whatever rules you want, without having to code anything.
Comment #5
zeroyon CreditAttribution: zeroyon commentedI was thinking about that, checking the recent log entries and for example. Upon a Captcha failure have it look to see if %ip had failed x times before.. I understand real users will occasionally flub the Captcha test but if it done x times in x seconds then they are probably a spammer, and if they fail x times then they are probably to dumb to use the site even if they are a real user.. But I have no idea how I would code that in or add it..
Great idea though..
Comment #6
zeroyon CreditAttribution: zeroyon commentedHere is some code that I found, that basically gives a report of failed Captcha attempts. I am sure you (being a php guy) could add in or apply the logic so as it finds failed Honeypot attempts as well.. Then add a function that adds the "deny from $ipaddress" into the .httaccess. or adds a threshold limit for captcha and honeypot that any amount of attempts above x or attempts above x in y time. Executes the function and bans them..
this of course could morph into a completely separate module all together but a useful one I am sure as it currently does not exist..
If there is anyone good with php, they could probably change the line that turns the ip address in to a linkable field and sends you to what's my ip into a function that just adds that IP to the .htaccess file..
The code I use right now inconjunction with the Honeypot module to autoban IP's.. If this could be turned into a function and inserted into the code above so you could just browse the report and click on them and their gone that would be cool.. Or if someone could dechiper the code above and put allow a variable of X attempts to be performed and the the the code below is executed that would be even better
Comment #7
geerlingguy CreditAttribution: geerlingguy commentedThanks! For the future, though, try to stick bits of code like that in a file, and attach the file to your post—makes scrolling through these issues much easier :)
Comment #8
geerlingguy CreditAttribution: geerlingguy commentedUpdating title to reflect what I'm thinking here; I could either write a little submodule that does an automated ban in certain situations, and has some configuration options there, or I could make sure there are easy ways for Honeypot to work with Troll, Ban User, or some other banning module.
I'm inclined to go down the route of a submodule, maybe honeypot_ban, which would integrate with Honeypot and allow configuration of how many times a certain IP would be logged as spam before being either permanently or temporarily banned.
Comment #9
zeroyon CreditAttribution: zeroyon commentedI would say if you are going to go the route of a sub-module ie..honey-pot ban.. then perhaps you may as well make it universally popular and just call it bad-bot or ban bot.. and have it check the access logs for failed attempt, (honeypot, captcha etc) and ban based on the total number of failed attempts.. Seems simple enough.. Also if you going to go that route, integrate the report code I supplied earlier into the module so it shows honeypot failures as well, and you can one click write their IP to the .httaccess from there.. Sorry not trying to sound like I am ordering at a restaurant as I know you time I am sure is valuable, just tossing out ideas..
My cheap hack seemed to have an effect on the "honeypot related failures.. I think it's been five days and my .httaccess has 150+ entries.. see attachment and add to your own bad bot list if you choose..
Considering each one of those 150 or so IP's would have made 100's if not thousands of requests to my server, or jammed up the site battling captcha, and trying to register.. I would call it a success..
Comment #10
zeroyon CreditAttribution: zeroyon commentedWould have helped if I would have actually attached the IP's in the previous post... list of bad spam bots I have caught trying to fill in honeypot over the last 5 days..
Comment #11
zeroyon CreditAttribution: zeroyon commentedNo word of any progress yet?
Comment #12
geerlingguy CreditAttribution: geerlingguy commented@zeroyon - I simply haven't had the time for it lately, but I'd still like to do it someday. If anyone else would like to work on a separate module in the meantime, be my guest :)
Comment #13
dshields CreditAttribution: dshields commentednot to be a pest, but this WOULD be a great submodule or independent module
Comment #14
geerlingguy CreditAttribution: geerlingguy commented@dshields - you're not a pest at all! I like when people offer their input, since it shows me more people are interested in a particular feature. I'm leaning towards creating a new 'Honeypot Ban' module (separate from this module, so it's easier to maintain), and then adding this functionality there.
Comment #15
dshields CreditAttribution: dshields commentedAwesome!
Your approach of a second module sounds like a good one.
It is certainly additional functionality that isn't required by many Honeypot users, so it's probably best to keep it as a separate project.
If there is anything I can do to help, please don't hesitate to ask.
Comment #16
a_lawry CreditAttribution: a_lawry commentedHas any work started on this? If not I'd be happy to start development of a 'Honeypot Ban' module. Don't want to double up in case someone is already working on it.
Comment #17
geerlingguy CreditAttribution: geerlingguy commentedNot yet; be my guest!
Comment #18
dshields CreditAttribution: dshields commenteda_lawry, that would be fantastic if you could get something going for 'Honeypot Ban' module!!
Comment #19
a_lawry CreditAttribution: a_lawry commentedI've started looking at implementing the honepot ban module.
I have an admin form that sets a limit on form submissions and the period over which those form submission attempts occurred before blocking the IP address.
Given that you are already registering a flood event when honeypot blocks a form submission this seems like a good way to track which IPs have had form submissions blocked by honeypot and when.
flood_is_allowed() provides the test for how many times the flood event occured during a period of time.
So what is the best way to hook into honeypot to call the flood_is_allowed() when a form submission fails? It looks like hook_honeypot_add_form_protection($options, $form) is close but not quite what I would need. I could add my own validation function that calls flood_is_allowed() but it seems inefficient to do the check even when the form has passed the honeypot validation test.
Comment #20
a_lawry CreditAttribution: a_lawry commentedActually I think what we need is to make a hook_honeypot_failure($form_id, $type) that is called within _honeypot_log()
That way we can provide integration to other modules: eg.
honeypot_ban: Uses core IP banning system to block the IP address
honeypot_rules: Implements a rules event and triggers it using this hook
I'm happy to write the patch just wanted to get some feedback on the idea before going ahead further with it.
Comment #21
geerlingguy CreditAttribution: geerlingguy commentedI've opened #1969212: Add hook_honeypot_reject so other modules can react to rejected form submissions, so you'll have your hook in just a little bit.
Comment #22
geerlingguy CreditAttribution: geerlingguy commented@a_lawry: I just committed #1969212-2: Add hook_honeypot_reject so other modules can react to rejected form submissions to Honeypot 7.x-dev. Please check it out and see if that unblocks your work on the Honeypot Ban module. Also, when you get an MVP of the module working, please create a Sandbox for it here on Drupal.org; I'll help review the project, and hopefully we'll be able to get it added as a full project (and it would be the first module you maintain on drupal.org, it seems!).
Comment #23
a_lawry CreditAttribution: a_lawry commentedThanks geerlingguy. I'm hoping to get a sandbox module up next weekend. I'll let you know when it is uploaded.
Comment #24
mgiffordWhat I like about Mollom is that they have a central database of bad users that have been collected & verified by humans. This is really quite powerful. I'm assuming that they also check other sources for blacklisted IPs.
Which got me looking around for Drupal projects that might address blacklisted IP's, and got me to http:BL, which uses the http://www.projecthoneypot.org as a central organizing database.
So how does the Drupal Honeypot module & the Project Honeypot relate to each other, other than that the like bees?
Comment #25
dshields CreditAttribution: dshields commentedAny progress on Honeypot Ban?
Comment #26
zeroyon CreditAttribution: zeroyon commented?
Comment #27
geerlingguy CreditAttribution: geerlingguy commented@zeroyon - could you put that list into a .txt file, delete the list from your last comment, and post the .txt file as an attachment to a new comment—it takes a while to scroll through this issue with the list posted inline.
Comment #28
zeroyon CreditAttribution: zeroyon commentedNo Problem was working on that, I realized what I did right after I put it up..
Comment #28.0
zeroyon CreditAttribution: zeroyon commentedformat
Comment #29
_paul CreditAttribution: _paul commentedI made a really simple module for Drupal 7.x using the hook_honeypot_reject() to fire the drupal core function system_block_ip_action().
So if you are using honeypot and the drupal backoffice ip blocking functionnalities (So not throught the .htaccess), you can install this module http://www.paulplaye.fr/blog/sites/default/files/uploads/hive.tar.gz and find it's source code on the following drupal sandbox : https://drupal.org/sandbox/pwetosaurus/2148397.
I haven't yet read all of this post answers, and I doubt some better solutions weren't already posted here, but as this sandbox and custom module exist, I share it here.
Comment #30
Dave ReidI've filed #2218537: Add Trigger and Rules event support as a related issue so that it would be super easy to set up the block IP action with honeypot rejection just with Drupal core's Trigger module or Rules.
Comment #31
geerlingguy CreditAttribution: geerlingguy commented@_paul / #29 - the module looks fine, but may be a little heavy handed... if someone submits a form quickly and triggers the timestamp protection, they'd be immediately banned from the site. I think adding a little logic, like what I've outlined below, would be helpful to avoid false positives/potentially angry users:
1. If the user entered something in the honeypot field, go ahead and ban the IP. This should never happen unless it's a spammer.
2. If the user is caught by the honeypot timestamp protection, and the time is, say, 4x or 8x the limit (the
honeypot_time_limit
), go ahead and ban the IP. Otherwise, let this submission slide.Users who fail the time limit test once should be allowed to keep trying. Users who fail 2, 3, or 4 times should be banned—and this should probably be configurable. Remember that the time limit increases exponentially every time a user tries submitting again!
@Dave Reid / #30 - I like your approach, which will allow those who need the ability to simply do things when a form is rejected to set everything up via Rules'/Trigger's UI. For many of the people in this thread, your patch will make things work well out of the box (no additional modules necessary!).
Comment #32
_paul CreditAttribution: _paul commentedthanks,
I will make some improvements in order to by-pass time-limit honeypot rejection and use only the hidden field protection. Or use another time limit, like an arbitrary two seconds value.
Anyway, thanks for your review.
Comment #33
_paul CreditAttribution: _paul commentedgeerlingguy, following your thoughts about banning IP upon honeypot field submission (and no more on the time limit form protection), I made some changes in my sandbox.
Thanks for your comments and your work.
Comment #34
candelas CreditAttribution: candelas commented@geerlingguy what about checking about the ip from different attempts to register with different users. I have this problem and I go baning two a week at least. A user that makes a mistake registering is not going to change 3 times the nick. If that was configurable on Honeypot it would be great.
Thanks a lot for this module.
Comment #35
candelas CreditAttribution: candelas commentedOther thing that I see that I will apply as a rule to block the ip is a user that tries
wordpress/wp-login.php
site/wp-login.php
or, since I have installed https://www.drupal.org/project/rename_admin_paths, any user trying to access user/login
Comment #36
candelas CreditAttribution: candelas commentedOther thing would to ban any user that tries node/add and has not a role.
Comment #37
dshields CreditAttribution: dshields commentedRe: #36
What if a client bookmarks the node/add page while familiarizing him or herself with drupal, then clicks that bookmark, assuming he or she is already logged in?
Your suggestion is to ban that ip?
Comment #38
candelas CreditAttribution: candelas commentedRe: #37 If you have configured everything on the site before to go online, you will not have that problem. Yes I would like to be able to ban ips for that.
Comment #39
candelas CreditAttribution: candelas commentedRe: #37 If the user tries to node/add and has not a role, then I would love to ban that ip :)
Comment #40
nithinkolekar CreditAttribution: nithinkolekar commented+1 for #34
along with rename_admin_paths another module internal nodes exist to prevent direct node/* accessing and by enabling this any user trying to view node/* will also be banned..
Comment #41
geerlingguy CreditAttribution: geerlingguy as a volunteer and at Acquia commentedClosing this issue as it's been a long time with not much activity, plus there are a lot of other ways to implement the functionality as described in some of the issue comments.
Comment #42
denix CreditAttribution: denix as a volunteer commentedHi @geerlingguy, as there is no solution yet to this, I think we should keep it open.
Also because other issues have been closed as duplicated of this one.