Great module! It's simple and straight to the point!

When using Services, data is submitted via Form API to perform data validation. Since the form is submitted by the server, the form is created, filled out, and submitted in well under a second. After implementing hook_honeypot_time_limit() to return (time limit + 1) * -1, Services requests are able to bypass the minimum amount of time:

function custom_service_3_honeypot_time_limit($honeypot_time_limit, $form_values, $number) {
  $additions = 0;
  // If 'bypass_honey' is set, make time required 0
  // Have to pass back honeypot_time_limit +1 because _honeypot_time_restriction_validate checks for time() < instead of time() <= (line 217).
  if (!empty($form_values['bypass_honey']) && $form_values['bypass_honey'] == 'bypass') {
    $additions = (variable_get('honeypot_time_limit', 5)+1) * -1;
  }
  return $additions;
}

However, I am not confident in this code working long term because honeypot_get_time_limit() may change that minimum time based on a user's attempt to submit another form too fast (line 261). Is there a better way of doing this? Do I need to include line 261 in my hook to get the right amount of time?

I was thinking it would be nice to have another field that allows us to bypass the time requirement in special instances, such as using Services, so that the forms are still protected by the time limit check for normal use cases. I saw #1833192: Make honeypot harder to autodetect is requesting you to change the way you create the honeypot_time field, so I know my patch would need to be updated to follow suit. However, here's my idea!

Comments

MD3’s picture

geerlingguy’s picture

Status: Active » Needs review

Thanks for the patch; something like this is definitely worthwhile, I don't know if I want to add another form field to do it; maybe just offer a way of disabling the timestamp protection through a hook instead.

MD3’s picture

I totally understand not wanting to add another field.

For anyone using the method I have prescribed, I would highly advise that you copy honeypots hook_form_alter() function when adding the field. I was adding the bypass field to all forms which killed the website's infinite scrolling abilities! I also solved the variable time per user issue by copying the honeypot_get_time_limit() function. My function now looks like:

function custom_service_3_honeypot_time_limit($honeypot_time_limit, $form_values, $number) {
  $additions = 0;
  $bypass_honeypot_element = variable_get('SERVICES_BYPASS_HONEYPOT','bypass_honey');
  // If $bypass_honeypot_element is set, make time required 0
  if (!empty($form_values[$bypass_honeypot_element]) && $form_values[$bypass_honeypot_element] == 'bypass') {
    global $user;
    $honeypot_time_limit = variable_get('honeypot_time_limit', 5);
    // Only calculate time limit if honeypot_time_limit has a value > 0.
    if ($honeypot_time_limit) {
      // Get value from {honeypot_user} table for authenticated users.
      if ($user->uid) {
        $number = db_query("SELECT COUNT(*) FROM {honeypot_user} WHERE uid = :uid", array(':uid' => $user->uid))->fetchField();
      }
      // Get value from {flood} table for anonymous users.
      else {
        $number = db_query("SELECT COUNT(*) FROM {flood} WHERE event = :event AND identifier = :hostname AND timestamp > :time", array(
          ':event' => 'honeypot',
          ':hostname' => ip_address(),
          ':time' => time() - variable_get('honeypot_expire', 300),
        ))->fetchField();
      }
      // Have to pass back honeypot_time_limit +1 because _honeypot_time_restriction_validate
      // checks for time() < instead of time() <= (line 217).
      $additions = ($honeypot_time_limit + (int) exp($number) + 1) * -1;
    }
  }
  return $additions;
}
geerlingguy’s picture

Title: Bypass time requirement for Services Form Submissions » Allow manual disabling of timestamp protection for certain forms
Version: 7.x-1.13 » 7.x-1.x-dev

Updating metadata.

geerlingguy’s picture

Status: Needs review » Closed (duplicate)

You should be able to use hook_honeypot_form_protections_alter() to do what you need. See the documentation in honeypot.api.php. We added this hook as part of #1778296: add hook in honeypot_add_form_protection .