Bergen Shield
Plugin for reducing spam on WordPress sites
by Bergen Technologies · github.com/joetortorelli/bergen-spam-plugin · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/joetortorelli/bergen-spam-plugin/archive/refs/heads/main.zipInvisible multi-layer anti-spam protection for WordPress.
Zero friction for real users. Zero spam getting through.
Bergen Shield protects your WordPress forms, comments, and registration pages using seven independent detection layers -- all working silently in the background. There are no CAPTCHAs, no checkboxes, no puzzles. Legitimate visitors never know it is there. Bots never get through.
Version: 1.0.0 Requires PHP: 8.0+ Requires WordPress: 6.0+ License: GPLv2 or later
Supported integrations: Everest Forms, WPForms, Contact Form 7, WordPress Comments, User Registration, and WooCommerce.
Table of Contents
- Why Not CAPTCHA
- The Seven Layers
- How Scoring Works
- Silent Reject
- Supported Integrations
- Installation
- Configuration
- Admin Dashboard
- Allowlist and Blocklist
- File Structure
- License
Why Not CAPTCHA
CAPTCHAs solve spam at the expense of your users. They introduce friction, frustrate visitors, hurt conversion rates, and create accessibility barriers. Modern bots can solve most CAPTCHAs anyway, and CAPTCHA services often track your visitors across the web.
Bergen Shield takes a fundamentally different approach. Instead of asking humans to prove they are human, it observes the signals that distinguish real users from bots -- timing, behavior, browser environment, network reputation, and content patterns. Each signal on its own might produce false positives. Combined across seven independent layers with weighted scoring, they form a detection system that is both highly accurate and completely invisible.
Real users fill out your forms exactly as they always have. They never see a challenge, never solve a puzzle, never wonder why your site is making them click on traffic lights. The protection is entirely transparent.
The Seven Layers
Bergen Shield evaluates every form submission against seven independent detection layers. Each layer produces a score. The scores are combined using a weighted aggregation to determine whether the submission is spam.
1. Honeypot Fields
Three hidden form fields are injected into every protected form: one text input, one email input, and one textarea. The field names are randomized on each page load. The fields are positioned off-screen using CSS so they are invisible to human users but visible to bots that parse the DOM and fill in every field they find.
Each filled honeypot field adds 40 points to the spam score.
Bots that blindly fill all form fields will trigger all three honeypots, generating 120 points -- well above the default threshold.
2. Time Analysis
When the form renders, Bergen Shield embeds an AES-256-CBC encrypted timestamp. On submission, the plugin decrypts it and calculates how long the user spent on the form.
| Time Spent | Points Added |
|---|---|
| Less than 3s | 80 |
| Less than 5s | 50 |
| Less than 8s | 20 |
| 8s or more | 0 |
Humans need time to read, think, and type. Bots submit forms in milliseconds. The encryption prevents bots from forging the timestamp.
3. Interaction Proof
A lightweight JavaScript module tracks genuine user interaction with the page:
- Mouse movement (including distance traveled)
- Click events
- Keypress events
- Scroll events
- Touch events (for mobile)
- Focus events
The interaction data is submitted alongside the form. If no interaction is detected at all, the layer adds 60 points. Automated scripts that submit forms without rendering a browser produce zero interaction signals.
4. Cryptographic Token
Bergen Shield generates a one-time-use AES-encrypted token for each form render. The token contains:
- A unique nonce
- The form ID
- A timestamp
- A hash of the visitor's IP address
On submission, the token is decrypted and validated. It can only be used once. If the token is missing, invalid, or reused, the layer adds 70 points.
This prevents replay attacks, cross-site form submissions, and direct POST requests that bypass the form entirely.
5. Content Analysis
The submitted content is analyzed for patterns commonly found in spam:
- Spam phrases -- approximately 30 known spam phrases and patterns are checked against the submission content.
- Excessive URLs -- submissions stuffed with links are flagged.
- HTML and BBCode injection -- raw markup in plain-text fields indicates automated submissions.
- Disposable email addresses -- approximately 30 known disposable email domains (e.g., mailinator.com, guerrillamail.com) are checked.
- ALL CAPS text -- a high ratio of uppercase characters suggests spam.
- Repetitive content -- repeated words or phrases are flagged.
Each detected pattern contributes to the layer's score based on severity.
6. Browser Fingerprint
Client-side JavaScript collects a set of browser environment signals:
- WebDriver detection -- checks for the
navigator.webdriverproperty that is set by headless Chrome, Puppeteer, Selenium, and similar automation tools. - Canvas fingerprinting -- verifies that the canvas API behaves consistently with a real browser.
- Screen properties -- validates screen resolution and color depth.
- Timezone -- checks for consistency between the reported timezone and other signals.
- Language -- verifies that the browser language settings are present and plausible.
- CPU cores -- checks
navigator.hardwareConcurrencyfor values typical of real devices.
Headless browsers and automation frameworks leave distinct fingerprints that differ from real user environments.
7. IP Reputation
The visitor's IP address is evaluated through multiple checks:
- Rate limiting -- tracks submission frequency per IP using WordPress transients. The default limits are 5 submissions per hour and 15 per day.
- Spamhaus ZEN DNSBL -- performs a DNS-based blocklist lookup against the Spamhaus ZEN combined list, which includes known spam sources.
- Local blocklist -- checks the IP against a manually maintained blocklist (supports individual IPs and CIDR ranges).
- Datacenter IP detection -- performs a reverse DNS lookup to identify IPs belonging to hosting providers and datacenters, which are commonly used by bots but rarely by legitimate visitors.
How Scoring Works
Each detection layer produces a raw score. These scores are then combined using weighted aggregation to produce a final spam score.
Layer weights:
| Layer | Weight |
|---|---|
| Honeypot | 1.0 |
| Time Analysis | 0.8 |
| Interaction Proof | 0.9 |
| Cryptographic Token | 0.7 |
| Content Analysis | 0.8 |
| Browser Fingerprint | 0.6 |
| IP Reputation | 0.7 |
The final score is compared against a configurable threshold. The default threshold is 50. Any submission scoring at or above the threshold is classified as spam.
Special scoring rules:
- If the honeypot score is 40 or higher (at least one honeypot field was filled), the final score is forced to a minimum of 85, regardless of other layers.
- If the time analysis score is 50 or higher AND the interaction proof score is 50 or higher, the final score is forced to a minimum of 80.
These rules ensure that strong signals from individual layers cannot be diluted by low scores elsewhere.
Silent Reject
When Bergen Shield determines that a submission is spam, it does not display an error message. Instead, it shows a fake success message -- the same confirmation the user would see after a legitimate submission.
This is a deliberate design choice. If a bot receives an error, it knows the submission was blocked and can adapt its approach. If it receives a success response, it believes the spam was delivered and moves on to the next target. Silent rejection removes the feedback loop that bots rely on to refine their attacks.
Silent reject is enabled by default and can be toggled in the plugin settings.
Supported Integrations
Bergen Shield integrates with six WordPress form and registration systems. Each integration hooks into the appropriate render and validation points for its target plugin.
Everest Forms
The primary integration target. Bergen Shield injects its detection fields before the submit button and validates submissions during initial processing.
- Render hook:
everest_forms_display_submit_before - Validation hook:
everest_forms_process_initial_errors
WPForms
- Render hook:
wpforms_frontend_output_before - Validation hook:
wpforms_process_before
Contact Form 7
- Render hook:
wpcf7_form_elements - Validation hook:
wpcf7_validate
WordPress Comments
Protects the native WordPress comment form.
- Render hook:
comment_form_after_fields - Validation hook:
preprocess_comment
User Registration
Protects the WordPress user registration page.
- Render hook:
register_form - Validation hook:
registration_errors
WooCommerce
Protects both the WooCommerce registration form and the checkout process. The checkout integration uses a higher spam threshold to minimize false positives during purchases.
- Render hooks:
woocommerce_register_form,woocommerce_checkout_process - Validation hooks:
woocommerce_process_registration_errors,woocommerce_checkout_process
Installation
- Upload the
bergen-shielddirectory to/wp-content/plugins/. - Activate the plugin through the WordPress admin Plugins screen.
- Navigate to Bergen Shield in the admin menu to review the default settings.
No additional configuration is required. Bergen Shield begins protecting all detected forms immediately upon activation with sensible defaults.
Requirements
- PHP 8.0 or higher
- WordPress 6.0 or higher
- The OpenSSL PHP extension (for AES-256-CBC encryption)
Configuration
All settings are stored under the bergen_shield_settings option in the WordPress database. They can be managed through the Bergen Shield > Settings admin page.
General Settings
| Setting | Default | Description |
|---|---|---|
spam_threshold |
50 |
Spam score threshold. Submissions scoring at or above this value are blocked. |
silent_reject |
true |
Show a fake success message when spam is detected. |
log_retention_days |
30 |
Number of days to retain blocked submission logs. |
allowed_roles |
administrator, editor |
WordPress roles that can access the Bergen Shield admin pages. |
Detection Layer Toggles
Each of the seven detection layers can be individually enabled or disabled. All layers are enabled by default.
Rate Limiting
| Setting | Default | Description |
|---|---|---|
rate_limit_per_hour |
5 |
Maximum form submissions allowed per IP per hour. |
rate_limit_per_day |
15 |
Maximum form submissions allowed per IP per day. |
Content Analysis
| Setting | Default | Description |
|---|---|---|
check_disposable_emails |
true |
Flag submissions from known disposable email providers. |
Admin Dashboard
Bergen Shield adds three admin pages under its menu in the WordPress admin sidebar.
Dashboard
The main dashboard provides an overview of protection activity over the last 30 days:
- Statistics -- total submissions blocked, block rate, and daily trends.
- Block reasons -- breakdown of which detection layers are triggering most frequently.
- Protection status -- at-a-glance view of which layers are active and which integrations are loaded.
Blocked Submissions Log
A detailed log of every blocked submission, stored in the bergen_shield_log database table. Features include:
- Filtering -- filter by date range, detection layer, IP address, or form type.
- Pagination -- browse large logs without performance issues.
- CSV export -- export the filtered log for external analysis.
Daily aggregate statistics are stored separately in the bergen_shield_stats table for efficient dashboard rendering.
Settings
The settings page provides a visual interface for all configuration options, including:
- Per-layer enable/disable toggles
- A threshold slider for adjusting the spam score cutoff
- Rate limiting configuration
- Content analysis options
Allowlist and Blocklist
Bergen Shield supports manual allowlists and blocklists for IP addresses.
- Allowlist -- IP addresses on the allowlist bypass all detection layers entirely. Use this for known-good IPs such as office networks or trusted services.
- Blocklist -- IP addresses on the blocklist are immediately rejected without running the full detection pipeline.
Both lists support:
- Individual IPv4 and IPv6 addresses
- CIDR notation for IP ranges (e.g.,
192.168.1.0/24,2001:db8::/32)
Allowlists and blocklists are managed through the Bergen Shield admin interface.
File Structure
bergen-shield/
├── bergen-shield.php # Main plugin file
├── readme.txt # WordPress.org readme
├── uninstall.php # Clean uninstall handler
├── assets/
│ ├── css/
│ │ ├── admin.css # Admin page styles
│ │ └── shield.css # Frontend detection field styles
│ └── js/
│ └── shield.js # Client-side detection (interaction, fingerprint, token)
├── includes/
│ ├── class-bergen-shield.php # Core plugin class
│ ├── class-bergen-shield-activator.php # Activation and database table creation
│ ├── detection/
│ │ ├── class-layer-honeypot.php # Layer 1: Honeypot fields
│ │ ├── class-layer-time-analysis.php # Layer 2: Time analysis
│ │ ├── class-layer-interaction.php # Layer 3: Interaction proof
│ │ ├── class-layer-token.php # Layer 4: Cryptographic token
│ │ ├── class-layer-content.php # Layer 5: Content analysis
│ │ ├── class-layer-fingerprint.php # Layer 6: Browser fingerprint
│ │ └── class-layer-reputation.php # Layer 7: IP reputation
│ ├── integrations/
│ │ ├── class-everest-forms.php # Everest Forms integration
│ │ ├── class-wpforms.php # WPForms integration
│ │ ├── class-cf7.php # Contact Form 7 integration
│ │ ├── class-comments.php # WordPress comments integration
│ │ ├── class-registration.php # User registration integration
│ │ └── class-woocommerce.php # WooCommerce integration
│ ├── admin/
│ │ ├── class-bergen-shield-admin.php # Admin menu and page routing
│ │ ├── class-admin-settings.php # Settings page logic
│ │ ├── class-admin-dashboard.php # Dashboard page logic
│ │ └── class-admin-log.php # Blocked submissions log logic
│ └── utils/
│ ├── class-logger.php # Submission logging
│ ├── class-scoring.php # Weighted score aggregation
│ ├── class-ip-utils.php # IP address utilities
│ └── class-blocklist.php # Allowlist and blocklist management
└── templates/
└── admin/
├── dashboard.php # Dashboard page template
├── settings.php # Settings page template
└── log.php # Log page template
License
Bergen Shield is free software released under the GNU General Public License v2 or later.
You may redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.