You are here

function _seckit_csp_report_flooding_detected in Security Kit 7

Check for CSP violation report flooding.

Return value

(bool) TRUE if flooding is detected (report logging should be inhibited). FALSE if it is safe to proceed with logging the report.

1 call to _seckit_csp_report_flooding_detected()
_seckit_csp_report in ./seckit.module
Log CSP violation reports to watchdog.

File

./seckit.module, line 419
Allows administrators to improve security of the website.

Code

function _seckit_csp_report_flooding_detected() {
  $options = _seckit_get_options();
  $flood_options = $options['seckit_advanced']['csp_limits']['flood'];

  // The global limit provides some DDOS protection.
  $global_limit = $flood_options['limit_global'];
  $global_window = $flood_options['window_global'];

  // flood_is_allowed() does not presently allow us to ignore the identifier,
  // meaning we would need to log two flood events per CSP report in order to
  // check both the global and per-user counts using the API function. This
  // query enables us to do this while only registering one event per report.
  // @see https://www.drupal.org/node/2472941
  $sql = "\n    SELECT COUNT(*)\n      FROM {flood}\n     WHERE event = 'seckit_csp_report'\n       AND timestamp > :timestamp\n  ";
  $args = array(
    ':timestamp' => REQUEST_TIME - $global_window,
  );
  $global_count = db_query($sql, $args)
    ->fetchField();
  if ($global_count >= $global_limit) {
    return TRUE;

    // Flooding is in effect
  }

  // Per-user limit.
  $user_limit = $flood_options['limit_user'];
  $user_window = $flood_options['window_user'];
  if (!flood_is_allowed('seckit_csp_report', $user_limit, $user_window)) {
    return TRUE;

    // Flooding is in effect
  }

  // Flooding is not in effect. Log this event, and return the status.
  flood_register_event('seckit_csp_report', $user_window);
  return FALSE;

  // No flooding
}