Cypress North Password Policy
Cypress North Password Policy enforces a strong, modern password policy on your WordPress site. Defaults align with NIST 800-63B guidance: length over composition rules, denylist screening, breach-corpus checks, and rate-limited login. Every setting is admin-configurable.
What you get
- A password rule engine that validates on user registration, password reset, and profile updates — covering minimum length, character requirements, breach-corpus check via the Have I Been Pwned k-anonymity API, denylist of common passwords, edit-distance check against the current password, and a per-user history check.
- Layered failed-login lockout: separate thresholds per IP and per username, with rolling windows and auto-release. Generic “invalid credentials” error responses so locked state is not disclosed to attackers.
- A soft-force interstitial that catches users at next login when their password is expired, breached, or below the active policy — they cannot escape without choosing a compliant new password.
- Daily email summary for administrators when attack rates spike.
- Per-user notification emails on password change, lockout, and expiration warnings.
- GDPR exporter + eraser that integrate with WordPress’s built-in Personal Data tools.
- Audit log of every relevant event (login failures, lockouts, password changes, compliance state transitions) viewable in the admin.
- Cleanup cron that trims old failed-attempt rows on a configurable schedule.
- WP-CLI
wp cnpp unlockcommand to release a stuck IP or username without opening the admin. - Multisite-aware: super-admin can globally configure or delegate per-site management.
Designed to coexist with WordPress core
The plugin uses WordPress’s own password hashing (wp_hash_password) and never stores plaintext. The built-in zxcvbn strength meter is left intact. All integration is via documented WP filters and actions — deactivating the plugin removes its behavior cleanly.
External services
This plugin connects to an API to check for known breached passwords.
The Have I Been Pwned API (api.pwnedpasswords.com) receives only the first five characters of a SHA-1 hash — k-anonymity. No personally identifying information leaves the site and no plain text is transmitted. The check can be disabled entirely from Settings → Password Policy → Policy.
This service is provided by Have I Been Pwned (https://haveibeenpwned.com/) : terms of use , privacy policy
Privacy
This plugin processes data necessary to enforce account security. The full privacy disclosure is contributed to Tools → Privacy Policy Guide when the plugin is active.
What is collected
- Failed login attempts (IP, username attempted, timestamp).
- Lockout events (identifier, lockout-until timestamp).
- Password-change audit-log rows.
- Per-user: timestamp of last password change, compliance flag, a small queue of one-way hashes of previous passwords, and the most recent HIBP breach-check result (if enabled).
Lawful basis
Legitimate interest in preventing brute-force credential attacks, plus regulatory and contractual obligations around password hygiene where applicable.
Retention
- Failed-attempt rows: pruned daily by cron, default kept for the duration of the lockout window (typically 24 hours).
- Audit-log rows: default 90 days, configurable.
- Per-user compliance and history data: kept while the user account exists; removed via the GDPR eraser on request.
Third parties
The Have I Been Pwned API (api.pwnedpasswords.com) receives only the first five characters of a SHA-1 hash — k-anonymity. No personally identifying information leaves the site. The check can be disabled entirely from Settings → Password Policy → Policy.
Exporter + eraser
The plugin registers with WordPress’s built-in Personal Data tools (Tools → Export Personal Data, Tools → Erase Personal Data). Exports return four groups (failed attempts, lockouts, password-change events, compliance state). Erasure removes the password-change audit rows and every plugin-specific user_meta entry; lockout and failed-attempt rows are retained with the username field redacted so aggregate-attack statistics remain intact but the rows can no longer be linked to the individual.
