Getting Started

Choose the right plan

Must-Have Captcha is an intelligent form protection plugin based on real human interactions. There are 2 available plans:

Single plan

You can use Must-Have Captcha with the Single plan for 1 WordPress site. It's perfect if you have a single site or want to test the plugin's capabilities.

Unlimited plan

We created the Unlimited plan for freelancers and agencies who manage multiple sites. This plan can be used on unlimited sites, perfect for protecting forms across all your WordPress installations.


Install Must-Have Captcha

  1. Login to My account on musthaveplugins.com
  2. Download the Must-Have Captcha installer from the Must-Have Captcha box
  3. Login to your WordPress admin where you would like to install Must-Have Captcha
  4. Go to Plugins > Add new and click to upload plugin
  5. Select the downloaded ZIP file (must-have-captcha.zip) and click to install
  6. Activate the plugin - it works immediately with default settings

Configuration

Must-Have Captcha works automatically after installation with no configuration required. However, you can fine-tune the protection to suit your site's needs from the plugin settings page in WordPress admin.

Protection Level

Choose how strict the plugin should be when blocking suspicious submissions by adjusting the threshold setting:

  • Basic: Basic bot protection without affecting legitimate users, best for personal blogs and low-traffic websites
  • Normal: Balanced protection that blocks most automated attacks, ideal for business websites and community sites
  • Strict: Maximum protection against sophisticated bots and spam, recommended for e-commerce sites and websites with high spam traffic

Logged In Users

When enabled, the plugin will skip captcha validation for logged-in users. This is useful for sites where users have already been verified through the registration process. Use this setting to provide a smoother experience for your registered users while maintaining protection for anonymous visitors.

Expiry

Determine how long to keep blocked requests in the database for review. Options range from 1 day to keeping forever:

  • 1 day: Minimal storage period, saves database space but gives less time to review blocked submissions
  • 1 week: Short-term storage that works for most sites to review blocked requests
  • 1 month: Standard setting for sites with moderate traffic that need more time to review
  • 1 year: Long-term storage for thorough analysis of blocked submissions
  • Keep forever: Never delete blocked requests, maximum ability to review all blocked submissions

Longer expiry periods give administrators more time to review and potentially recover legitimate submissions that were incorrectly blocked.

Custom 403 Page

When enabled, you can select a WordPress page to display when submissions are blocked. This allows you to create a more informative and user-friendly experience when spam or bot submissions are detected, perhaps explaining why they were blocked or providing alternative contact methods.


Custom Rules

Create custom protection rules to whitelist specific URLs or IP addresses:

  • Type: URL or IP address
  • Value: The URL pattern or IP address (supports CIDR notation for IP ranges)
  • Protection Level: How strictly to apply protection to this rule
  • Note: Optional information to remember why you created the rule

Protection Levels for Custom Rules

When creating custom rules, you can choose from these protection levels:

  • Never Block: Always allow requests, regardless of suspicion level (whitelist)
  • Basic: Block only highly suspicious requests
  • Normal: Apply balanced protection
  • Strict: Maximum protection against bots
  • Block & Ignore: Always block but don't store in the blocked requests database
  • No Logging: Use the global protection level but do not log blocked requests

Blocked Requests

The Blocked Requests dashboard shows all submissions that have been blocked by the plugin. For each blocked request, you can view:

  • URL: The page where the submission was attempted
  • Type: The form type that was blocked (comment, contact form, etc.)
  • IP: The visitor's IP address
  • Score: The trustability score assigned (and why it was too low)
  • User Agent: Information about the browser and device used
  • Date: When the submission was blocked
  • Form Data: The actual content of the blocked submission
  • Request Headers: HTTP headers sent with the submission request

You can filter, sort, and search through blocked requests to identify patterns of spam attacks or find legitimate submissions that were incorrectly blocked.


Replaying Blocked Requests

One of Must-Have Captcha's unique features is the ability to replay blocked submissions that were mistakenly flagged as spam:

  1. Go to the Blocked Requests tab in the plugin dashboard
  2. Click "View Details" on any blocked submission
  3. Review the submission content to ensure it's legitimate
  4. Click "Accept" to process the submission as if it was just submitted

This feature ensures you never lose legitimate form submissions due to false positives, particularly useful for contact forms, orders, or registrations from real users who might have triggered protection rules.

Note: Requests containing masked sensitive data (like passwords, credit card numbers, etc.) cannot be replayed because sensitive data is not stored for security reasons.


Available Filters

Customize Must-Have Captcha's behavior using these developer hooks:

mhcaptcha/threshold

Modify the captcha threshold for specific pages, post types, or conditions:

// Modify the captcha threshold based on page context
add_filter('mhcaptcha/threshold', function($threshold) {
   if (defined('DOING_AJAX') && $_POST['action'] == 'my-whitelisted-ajax-action'){
      return 15; // Basic protection for whitelisted AJAX action
   }

   return $threshold; // Default for everything else
});

mhcaptcha/score

Fine-tune the scoring system for specific user groups or contexts:

// Customize captcha scoring logic
add_filter('mhcaptcha/score', function($score, $cookie_value) {
    // Add points for specific countries by Cloudflare country id
    if (isset($_SERVER['HTTP_CF_IPCOUNTRY']) && $_SERVER['HTTP_CF_IPCOUNTRY'] == 'DE') {
        $score += 10; // Add points for visitors from trusted countries
    }

    return $score;
}, 10, 2);

mhcaptcha/is_trustable_request

Bypass captcha checks for specific request types:

// Bypass captcha for specific scenarios
add_filter('mhcaptcha/is_trustable_request', function($is_trustable) {
    // Skip captcha for specific form submissions
    if (isset($_POST['form_id']) && $_POST['form_id'] === 'internal_form') {
        return true; // Mark as trustable, bypassing checks
    }

    return $is_trustable; // Default behavior for other requests
});

mhcaptcha/store_blocked_request

Control whether blocked requests should be stored in the database:

// Prevent storing certain blocked requests
add_filter('mhcaptcha/store_blocked_request', function($store_request) {
    // Don't store blocked requests from specific URLs
    if (strpos($_SERVER['REQUEST_URI'], '/high-volume-form/') !== false) {
        return false; // Don't store these blocked requests
    }
    
    return $store_request; // Default behavior for other requests
});

mhcaptcha/blocked_status_header

Customize the HTTP status code sent when a request is blocked:

// Change the HTTP status code for blocked requests
add_filter('mhcaptcha/blocked_status_header', function($status_code) {
    // Use 429 (Too Many Requests) instead of 403 (Forbidden)
    return 429;
});

mhcaptcha/default_score

Modify the default score assigned to requests:

// Change the default score
add_filter('mhcaptcha/default_score', function($default_score) {
    // Set a more lenient default score
    return 15;
});

mhcaptcha/cloud_rules

Customize the cloud rules used for IP-based filtering:

// Modify cloud rules
add_filter('mhcaptcha/cloud_rules', function($rules) {
    // Add custom IPs to the whitelist
    if (!isset($rules['whitelist'])) {
        $rules['whitelist'] = array();
    }
    
    // Add your office IP range to whitelist
    $rules['whitelist'][] = '203.0.113.0/24';
    
    return $rules;
});

mhcaptcha/get_template

Customize the HTML templates used by the plugin:

// Add a custom message to the blocked template
add_filter('mhcaptcha/get_template', function($template_html, $template_name) {
    // Only modify the blocked template
    if ($template_name === 'blocked') {
        // Simply add a message at the end of the template
        $template_html .= '<div class="custom-message">If you believe this is an error, please contact us.</div>';
    }
    
    return $template_html;
}, 10, 2);

mhcaptcha/get_svg

Customize SVG icons used in the plugin interface:

// Customize SVG icons
add_filter('mhcaptcha/get_svg', function($svg, $file) {
    // Replace the lock icon with a custom version
    if ($file === 'lock') {
        return '<svg><!-- Your custom SVG code here --></svg>';
    }
    
    return $svg;
}, 10, 2);

mhcaptcha/request_type

Customize how request types are detected and categorized:

// Customize request type detection
add_filter('mhcaptcha/request_type', function($type, $post_data, $url, $headers) {
    // Identify a custom form submission
    if (isset($post_data['my_custom_form_id'])) {
        return 'custom_form';
    }
    
    return $type;
}, 10, 4);

mhcaptcha/api_request_args

Customize API request arguments when communicating with the Must-Have Captcha API:

// Customize API request arguments
add_filter('mhcaptcha/api_request_args', function($args) {
    // Increase timeout for API requests
    $args['timeout'] = 30;
    
    return $args;
});

mhcaptcha/sensitive_input_patterns

Define patterns for sensitive data that should be masked in stored requests:

// Add custom sensitive data patterns
add_filter('mhcaptcha/sensitive_input_patterns', function($patterns) {
    // Add pattern for custom sensitive field
    $patterns[] = '/ssn\d*|social.*security/i';
    
    return $patterns;
});

mhcaptcha/custom_rules

Programmatically add or modify custom rules:

// Add custom rules programmatically
add_filter('mhcaptcha/custom_rules', function($rules) {
    // Add a rule to whitelist specific API endpoint
    $rules[] = array(
        'type' => 'url',
        'value' => '/wp-json/custom-api/',
        'protection' => 'none', // No protection for this endpoint
        'order' => 5, // High priority
        'note' => 'API Whitelist - Added programmatically'
    );

    return $rules;
});

Available Actions

Must-Have Captcha provides action hooks that you can use to extend functionality:

mhcaptcha/send_daily_summary

This action is triggered when the daily summary report is scheduled to be sent. You can hook into this to perform additional tasks when summaries are generated:

// Hook into the daily summary generation
add_action('mhcaptcha/send_daily_summary', function() {
    // Perform additional tasks when daily summaries are sent
    // For example, log summary generation to a custom log
    error_log('Must-Have Captcha daily summary generated at ' . date('Y-m-d H:i:s'));
});

mhcaptcha/send_weekly_summary

Similar to the daily summary action, but triggered for weekly summary reports:

// Hook into the weekly summary generation
add_action('mhcaptcha/send_weekly_summary', function() {
    // Perform additional tasks when weekly summaries are sent
});

mhcaptcha/send_monthly_summary

Triggered when monthly summary reports are generated:

// Hook into the monthly summary generation
add_action('mhcaptcha/send_monthly_summary', function() {
    // Perform additional tasks when monthly summaries are sent
});

mhcaptcha/uninstall

This action runs during the plugin uninstallation process. You can hook into it to clean up any custom data or settings you've added:

// Clean up custom data during uninstallation
add_action('mhcaptcha/uninstall', function() {
    // Remove any custom options or database entries you've created
    delete_option('my_custom_mhcaptcha_setting');
});

Compatibility Features

Must-Have Captcha includes several compatibility features to ensure it works well with other plugins and server environments:

WordPress Loopback Request Detection

The plugin automatically detects and allows WordPress loopback requests (when WordPress makes HTTP requests to itself). This prevents the plugin from blocking important internal WordPress functionality like:

  • Site Health checks
  • Auto-updates
  • Post previews
  • REST API internal calls

This is handled by adding a special header to all WordPress HTTP requests and checking for this header when processing incoming requests.

Cross-Server Headers Compatibility

Must-Have Captcha includes a custom implementation of get_all_headers() that works reliably across different server environments, including:

  • Apache with mod_php
  • Nginx with PHP-FPM
  • CGI/FastCGI environments
  • Various hosting configurations

This ensures consistent behavior regardless of your server setup.

If you're also using the Must-Have Cookie plugin for GDPR/cookie compliance, Must-Have Captcha automatically registers its cookies as "essential" so they continue to function even when a visitor hasn't accepted cookies. This ensures your forms remain protected while complying with privacy regulations.


Changelog

0.1.5 – 2025.05.13.
Improve auto whitelist

0.1.4 – 2025.05.06.
Minor bugfixes

0.1.3 – 2025.04.25.
Initial public beta release

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only