Skip to content
Witen

Application protection

WordPress plugin guide

Witen Blocker blocks password guessing, exploit probes, and unwanted bots inside WordPress, on any host. It works on its own with no account. Connect it to the Witen network for the shared threat feed, or to Warden on the same server for firewall bans.

Quickstart

  1. Open Plugins → Add New Plugin, search for Witen Blocker, then install and activate it. Login lockout, comment checks, and daily scans start immediately.
  2. Add your own address under Witen → Firewall → Never-block list. Behind a proxy or CDN? Check the client address first.
  3. Choose which crawlers may read your site under Witen → Firewall → Bots and AI crawlers.
  4. Set up two-factor sign-in from your user profile and keep the recovery codes somewhere safe.
  5. Review Witen → Dashboard and Witen → Scan. Never test a ban against your own address.

Everything above works without a Witen account. Connecting one is optional and covered below.

Requirements

  • WordPress 6.2 or newer and PHP 8.1 or newer.
  • An administrator account that can install plugins.
  • For shared intelligence: a Witen account and a free slot on your plan. Local login protection, bot controls, and file-integrity checks work without enrollment.
  • To connect: outbound HTTPS to Witen, or access to Warden's ingest socket on the same server.

Install from a ZIP instead

  1. Sign in and download the current witen-blocker ZIP from Downloads.
  2. Check its SHA-256 checksum against the published value.
  3. Open Plugins → Add New Plugin → Upload Plugin and install the ZIP.

Check it's working

  • Witen → Settings shows the installed version.
  • Witen → Firewall → Never-block list and Witen → Firewall → Bots and AI crawlers show the addresses and policies you chose.
  • A run of Witen → Scan completes. Check each finding before deleting anything; some are false positives.
  • Witen → Dashboard fills with activity as requests arrive. An empty list is normal on a quiet site.

These checks do not require an enrollment token or a connection.

Login limits

Five failed logins in five minutes earn a one-hour ban. Add your own address to the allowlist before you change anything, and keep SFTP or hosting-panel access as a way back in.

Open Witen → Login to save limits or restore the configured defaults. The same controls are available in Settings. With WP-CLI, set them directly (seconds, failures, seconds):

wp option update witen_login_window_sec_override 300
wp option update witen_login_max_failures_override 5
wp option update witen_login_ban_sec_override 3600

Limits: a window up to 86,400 seconds, up to 100 failures, and a ban up to 864,000 seconds. On Multisite, add --url=https://your-site.example. Saved overrides take precedence over WITEN_LOGIN_* constants, which take precedence over built-in defaults. Delete the three options or restore defaults in Login to use your configured constants again. Changing a limit doesn't lift an existing ban.

Locked out? Follow Recover login access.

Connect to the Witen network

Connecting adds the shared threat feed and sends security events to Witen. See what's shared first.

  1. In your Witen dashboard, open Add Protected Asset and choose WordPress.
  2. Name the site and generate a one-time enrollment token.
  3. Paste the token into Witen → Settings, or define it in wp-config.php above the “stop editing” line.
define( 'WITEN_ENROLLMENT_TOKEN', 'wte-one-time-token' );

// Only for a self-hosted collector.
define( 'WITEN_COLLECTOR_URL', 'https://collector.example' );

// Only when Warden runs on the same server.
define( 'WITEN_SOCKET_PATH', '/run/witen/warden-ingest.sock' );
define( 'WITEN_WARDEN_CREDENTIAL_FILE', '/var/lib/witen-wordpress/caller.token' );

// Optional: a fixed site ID instead of the generated one.
define( 'WITEN_SITE_ID', 'shop-production' );
define( 'WITEN_SYNC_INTERVAL', 300 );

Collector mode

For shared hosting. The plugin talks to Witen over HTTPS: it exchanges the token, syncs blocklists and signed catalogs, and sends security events. Blocking happens inside WordPress.

Warden socket mode

When Warden runs on the same server. The plugin reports to Warden over a local socket, and Warden bans attackers at the firewall, before PHP loads.

Check the connection

Connected installations only.

  • Witen → Settings shows a credential and a recent maintenance run.
  • The Dashboard shows the mode you expect: Warden socket or collector HTTPS.
  • A blocklist sync has completed without errors.
  • Your Witen dashboard lists the site with a recent report.
  • WordPress cron runs. If maintenance stalls for ten minutes, administrators see a warning.

Plugin pages

PageWhat it's forWorth knowing
DashboardConnection health, block counts, recent events, and blocks.An event is evidence, not necessarily a block.
FirewallIP Blocklist, Never-block list, Bots and AI crawlers, and Server rules.A crawler must come from its published network, not just claim the name. Apache server rules require a host that reads .htaccess.
LoginLogin limits and the custom login address.Saved login limits override constants; restoring defaults uses your configured constants again.
ScanIntegrity, malware patterns, suspicious PHP, risky users, and hardening.Review evidence before changing a file.
SettingsOptional connection, threat-feed selection, sync, and login-limit controls.Expand connection diagnostics for version and credential status.

Without Warden, the plugin bans for repeated login failures itself. With Warden, the plugin reports the failures and Warden decides, counting each attempt once. Warden then holds the ban, and the Witen blocklist, in the server firewall. The IP Blocklist marks those addresses Held by Warden and shows how to lift them on the server.

Security scan

  1. Open Witen → Scan and start with the summary.
  2. For each finding, check the file path, type, evidence, and severity.
  3. Compare unexpected files with a clean copy or backup.
  4. Remove or quarantine a file only once you're sure it isn't legitimate code.
  5. Scan again and check the site still works.

Connected sites download signed detection catalogs. The plugin checks each catalog's signature, hash, and version before using it, and never runs catalog content as code.

Data and privacy

Sent once connected

  • Attacking addresses, event type, request method and URL, user agent, and limited context.
  • The site's identity and software versions, for compatibility and vulnerability matching.
  • Attempted usernames from failed logins. Never passwords, cookies, or form contents.

Kept on your site

  • A queue of events waiting to send.
  • Recent events and blocks, your allow and block lists, and the last verified catalog.
  • Anything observed before you connected. It is never uploaded afterwards.

WITEN_NO_TELEMETRY turns off the daily WordPress, PHP, and plugin version report. To stop reporting entirely, remove the stored credential, unused tokens, and any socket settings. The full field list is in What data Witen receives.

WordPress Multisite

Each site in a network keeps its own state, queue, and identity. Unless you define WITEN_SITE_ID, each gets a generated ID starting with wordpress-. If you set one, keep it unique per site.

  • Activate and connect each site in its own context.
  • Check each site appears in your Witen dashboard.
  • Never copy a credential from one site to another.
  • Test cron and blocklist sync on each site, not just the main one.

Upgrade and remove

Upgrade

  1. Back up the database and files.
  2. Update through WordPress, or deploy a verified ZIP, without deleting Witen's settings first.
  3. Check the version, connection, last maintenance run, blocklist sync, and scan catalog.

Rotate a credential

Rotate it from your Witen dashboard. If it lives in wp-config.php, update WITEN_SENSOR_CREDENTIAL at the same time. Enrollment tokens work once.

Uninstall

Uninstalling removes the plugin's settings, scheduled tasks, and tables. Events already sent to Witen are deleted through your account, not by uninstalling. See Disconnect or remove Witen.

Troubleshooting

Enrollment stays pending

  • Check the token starts with wte- and hasn't been used.
  • Check WordPress cron and the last maintenance run.
  • Check outbound HTTPS and the server clock; a wrong clock breaks TLS and signature checks.
  • Remove the legacy WITEN_API_KEY; it's rejected on purpose.

Socket mode isn't working

  • Check Warden is running and the path is its ingest socket.
  • Give the PHP user only the group access the ingest socket needs.
  • Check the socket's owner and mode after Warden restarts.
  • The ingest socket can't ban, unban, or change settings; that's by design.

Blocklists or catalogs are out of date

  • Check the last maintenance run and that Witen is reachable.
  • Check the credential is still valid.
  • During an outage the plugin keeps using the last verified copy, and it refuses a replacement that fails its signature or version check.

A real visitor is blocked

  • Find the address and its source under Witen → Firewall → IP Blocklist.
  • Check the client address setup before you add an exception, or you may exempt your proxy instead of the visitor.
  • Without Warden: add the exact address to the Never-block list, then remove the block.
  • With Warden: rows marked Held by Warden can only be lifted on the server. Sign-in lockouts never appear in the list at all. Lift a Warden firewall block with warden unban or Warden’s never_block list.