Cerrojo Security Toolkit releases
Cerrojo Security Toolkit provides focused WordPress security posture diagnostics and seven reversible security tools: five under Hardening, plus dedicated Security headers and REST API tools. It reports evidence, not a guarantee of invulnerability.
by Carlos Carrillo · github.com/carlose119/bastion-security-wp · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/carlose119/bastion-security-wp/releases/download/v0.2.2/cerrojo-security-toolkit.zipReadme
Cerrojo Security Toolkit
Cerrojo Security Toolkit provides focused WordPress security posture diagnostics and eight reversible security tools: six under Hardening, plus dedicated Security headers and REST API tools. It reports evidence, not a guarantee of invulnerability.
Quick navigation
Open Tools > Cerrojo Security Toolkit as an administrator with manage_options, then choose the tab for the job:
| Tab | Purpose |
|---|---|
| Overview | Summary counts, the twelve Cerrojo diagnostics, and a link to native WordPress Site Health. |
| Hardening | Six reversible tools: the WordPress file-editor lock, Login Protection, XML-RPC Pingback Protection, plugin activity email alerts, Administrator Account Alerts, and URL Change Alerts. |
| Security headers | Baseline and optional policy state, selected batch actions, individual controls, coverage guidance, and rollback. |
| REST API | Active registered route-template catalog, method checkboxes, selected/stale state, impact guidance, and clear-all rollback. |
Only the active tab is rendered. Unknown or malformed tab values fall back to Overview.
Safe activation path
- Review the twelve diagnostics on Overview.
- Open Security headers, select the conservative baseline, and choose Enable selected.
- Verify final response headers and site behavior in browser developer tools and, when applicable, at the CDN edge.
- Select only the optional groups you intend to enable. One aggregate acknowledgement covers the selected high-impact groups; it is not required for the baseline or
legacy_cross_domainalone. - Treat HSTS as the final step. If
hsts_trialis selected, Cerrojo confirms that the current request, WordPress Address, and Site Address all use HTTPS before writing any part of that enable-selected batch.
Current scope
The plugin adds twelve deterministic direct tests to WordPress Site Health, in stable order:
- HTTPS and admin transport posture.
- File editor posture.
- Login Protection setting and limitations.
- XML-RPC Pingback Protection setting and limitations.
- REST Route Controls configuration and limitations.
- Plugin activity email alert configuration.
- Administrator Account Alerts configuration.
- Security header preset preference.
- File modification and update posture.
- Runtime compatibility notice.
- Read-only pending plugin-update compatibility.
- Read-only REST surface inventory.
The assessments remain request-local and fail open per check. WordPress has no unscored Site Health status, so unavailable or unsupported assessments use its supported recommended status rather than reporting a successful security observation. The Cerrojo dashboard presents the same results with Site Health-inspired, accessible details/summary markup and links to native WordPress Site Health for the full suite.
Plugin update compatibility boundaries
The diagnostic reads WordPress's existing plugin-update site transient and installed plugin metadata. It performs no network request, update check, install, update, package retrieval, plugin callback, or cache/option write, and it provides no update button or action.
Inventory is shown only to users who can update plugins. On multisite, the user must also be able to manage network plugins. Without those permissions, Cerrojo does not read or render plugin names or versions. The cache must be structurally complete, no more than 12 hours old, not implausibly future-dated, and consistent with installed versions; otherwise the result is Not assessed. Cache age describes freshness only and does not prove that a remote check succeeded.
Each installed plugin with a cached pending update receives exactly one conservative classification based only on the target update's declarations:
- Declared requirements met: valid WordPress and PHP minimums are present and met, and the publisher's tested-through WordPress version covers the current version. This does not guarantee compatibility or absence of conflicts.
- Blocked by declared requirements: the current WordPress or PHP version is below a valid declared minimum. Every failed minimum is named.
- Compatibility unknown: required metadata is missing or malformed, or the current WordPress version is newer than the publisher-tested-through value. Tested-through is not treated as a maximum.
Installed plugin headers are not used as fallback target requirements. Results are deterministically sorted, limited to 50 displayed updates, and report total, shown, and omitted counts. Cached entries that do not match an installed plugin are ignored without exposing their identifiers.
Reversible tools
WordPress file-editor lock
On single-site installations, an administrator can enable or disable a plugin-owned preference through a nonce-protected POST action. When enabled, Cerrojo defines DISALLOW_FILE_EDIT as true early in each request only if the constant is not already defined.
Cerrojo writes only its own WordPress option; it never edits wp-config.php or another file. If another source defines DISALLOW_FILE_EDIT, Cerrojo preserves that value, reports its effective result, and does not claim it can override or roll it back. This tool is unavailable on multisite and performs no policy mutation there.
Login Protection
Login Protection is an opt-in, per-site, best-effort throttle for failed WordPress authentication. Enable it under Tools > Cerrojo Security Toolkit > Hardening only after acknowledging that legitimate users can be temporarily blocked, especially when they use a shared proxy address. Disabling it stops enforcement and advances an internal generation so prior temporary buckets are abandoned. Reset temporary blocks also advances that generation, preserves the enabled setting, and preserves aggregate failed/throttled metrics.
Within a 15-minute rolling window, the policy uses these progressive thresholds:
| Dimension | Failures | Cooldown |
|---|---|---|
| Normalized username or email | 5 / 8 / 12 | 60 seconds / 5 minutes / 15 minutes |
| Direct peer address | 50 / 100 / 200 | 60 seconds / 5 minutes / 15 minutes |
There are no permanent locks or sleeps. A successful, non-blocked authentication clears only that normalized identity bucket; it never clears the shared address bucket. The same generic error is returned for either dimension so the response does not identify which bucket matched.
Bucket keys are HMAC SHA-256 values derived with the WordPress authentication secret. Raw usernames, email addresses, and IP addresses are not stored in buckets or rendered in the UI. Rotating that secret naturally abandons the old transient namespace.
Coverage includes standard wp-login.php and every flow through wp_authenticate(), including ordinary XML-RPC authentication. REST Application Password authentication is explicitly not covered. Final enforcement runs after normal authentication work, so it does not avoid WordPress user lookup or password hashing and is not pre-authentication cost protection.
Only the directly connected peer from REMOTE_ADDR is considered. Forwarded and X-Forwarded-For are never trusted. This avoids accepting caller-controlled forwarding data, but sites behind a reverse proxy can place many users in one shared address bucket. Confirm the deployment topology and retain independent recovery access before enabling the tool.
Enforcement uses expiring WordPress transients and read-modify-write updates. Transient eviction or concurrent requests can weaken enforcement, while aggregate metrics can undercount. Login Protection is not a WAF, DDoS defense, availability guarantee, or general security guarantee.
Safe smoke check
- Keep a separate recovery path available, such as hosting control-panel or CLI access; do not test against the only administrator session.
- Enable Login Protection and confirm its diagnostic changes to Good, meaning only that the setting is enabled.
- Use a disposable non-administrator identity for any failed-login check, and stop before reaching a threshold unless you intentionally have recovery access.
- Confirm Reset temporary blocks preserves metrics, then disable Login Protection to verify rollback.
XML-RPC Pingback Protection
XML-RPC Pingback Protection is an opt-in, per-site control under Tools > Cerrojo Security Toolkit > Hardening. Enable it only after confirming that the site does not depend on native inbound pingbacks. No acknowledgement checkbox is required, but native pingback consumers stop working while the setting is enabled.
When enabled, Cerrojo registers surgical filters at PHP_INT_MAX with one accepted argument:
xmlrpc_methodsremoves exactlypingback.pingandpingback.extensions.getPingbacks. Every other method key, callback/value, and order remains unchanged.wp_headersremoves every case-insensitiveX-Pingbackkey. Every other WordPress-filtered header spelling, value, and order remains unchanged.
Malformed filter inputs and unreadable or malformed option state fail open without exposing read or write exceptions. A Good Site Health result means only that the readable per-site setting is enabled; it is not proof of absolute enforcement. A later filter at the same priority can re-add a method or header. Theme-authored pingback links, RSD metadata, and headers emitted directly or supplied by a server, proxy, cache, or CDN are outside this filter boundary.
This tool does not disable xmlrpc.php, authenticated XML-RPC methods, REST, Application Passwords, trackbacks, outbound pings, theme-authored pingback links, or RSD metadata. It performs no request inspection, logging, counting, rate limiting, firewall action, or network-wide enforcement, and it does not provide WAF or DDoS protection.
On multisite, the option remains local to the current site. Cerrojo does not call switch_to_blog, fan out changes, provide a network setting, or claim network-wide enforcement.
Safe compatibility check
- Confirm that no publishing workflow or integration requires inbound WordPress pingbacks.
- Enable XML-RPC Pingback Protection and confirm its diagnostic changes to Good, meaning only that the setting is enabled.
- Verify the site's authenticated XML-RPC, REST, and Application Password workflows that must remain available, and inspect final headers at every serving edge.
- Disable the setting to stop Cerrojo filtering. Components other than Cerrojo may still remove the methods or header, so disabling cannot restore their changes.
Read the full README on GitHub →