{"id":22069,"date":"2026-06-01T14:53:09","date_gmt":"2026-06-01T18:53:09","guid":{"rendered":"https:\/\/membermouse.com\/?post_type=ht_kb&#038;p=22069"},"modified":"2026-06-01T14:53:11","modified_gmt":"2026-06-01T18:53:11","slug":"wp-nonce-validation-for-login","status":"publish","type":"ht_kb","link":"https:\/\/membermouse.com\/es\/docs\/wp-nonce-validation-for-login\/","title":{"rendered":"WP Nonce Validation for Login"},"content":{"rendered":"<p><strong>Setting location:<\/strong> MemberMouse \u2192 WordPress Settings \u2192 Login Page \u2192 <em>&#8220;Use the WP nonce validation for login.&#8221;<\/em><\/p>\n\n\n\n<p>When enabled, a login submitted through the MemberMouse login form is rejected unless it carries a valid WordPress nonce.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>This checkbox turns on <strong>CSRF (cross-site request forgery) protection<\/strong> for the MemberMouse front-end login form.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>OFF (default):<\/strong> the login AJAX request is processed without checking a nonce.<\/li>\n\n\n\n<li><strong>ON:<\/strong> the login AJAX request must include a valid WordPress nonce (<code>mm-security<\/code>, tied to the <code>mm-login<\/code> action). If the nonce is missing or invalid, login is rejected <strong>antes de<\/strong> credentials are ever checked (<code>wp_signon()<\/code> is never called).<\/li>\n<\/ul>\n\n\n\n<p>It is <strong>no<\/strong> brute-force protection, rate-limiting, or a CAPTCHA. It only ensures the login POST originated from a MemberMouse-rendered login form on this site, not a forged\/cross-origin request.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Why it matters <\/h2>\n\n\n\n<p>Without nonce validation, MemberMouse's login endpoint will accept a login POST from anywhere \u2014 including a form on a malicious third-party page that auto-submits credentials to your site (a classic CSRF vector, and a vector for some automated login-abuse tooling that posts directly to the endpoint).<\/p>\n\n\n\n<p>A WordPress nonce is a short-lived, per-action token embedded in the form when WordPress renders it. Because an attacker on another origin can't read the freshly-generated token out of your page, requiring a valid nonce means the request must have come from a real, recently-served MemberMouse login form. Enabling this hardens the login endpoint at essentially zero cost to legitimate users.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">How to turn it on<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Ir a <strong>MemberMouse \u2192 WordPress Settings \u2192 Login Page<\/strong>.<\/li>\n\n\n\n<li>Consulte <strong>&#8220;Use the WP nonce validation for login.&#8221;<\/strong><\/li>\n\n\n\n<li>Save.<\/li>\n<\/ol>\n\n\n\n<p>No other configuration is required for standard MemberMouse login forms.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Caveats & edge cases (read before enabling)<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>The nonce field rides with the password field.<\/strong><br>The hidden nonce is emitted inside the <code>contrase\u00f1a<\/code> case of the <code>[MM_Form_Field]<\/code> smart tag (<code>class.loginform.php:177<\/code>). A <strong>customized login form template that omits the password field smart tag<\/strong> will not render the nonce \u2014 and with the setting ON, every login attempt would then fail with <em>&#8220;Invalid request parameters.&#8221;<\/em> Standard\/default forms include the password field, so they are unaffected.<br><\/li>\n\n\n\n<li><strong>Full-page caching of the login page.<\/strong><br>WordPress nonces are time-limited (valid ~12\u201324 hours) and are regenerated per page render. If your login page is served from a <strong>full-page cache<\/strong> (caching plugin\/CDN caching the logged-out HTML), visitors can receive a <strong>stale nonce<\/strong>, causing <em>&#8220;Invalid nonce.&#8221;<\/em> errors. Exclude the login page from full-page caching, or don't cache the logged-out form, when this setting is on.<br><\/li>\n\n\n\n<li><strong>Page left open a long time.<\/strong><br>A login page left open past the nonce lifetime (>~24h) will fail validation on submit. The user simply refreshes the page to get a fresh nonce. (Normal nonce behavior.)<br><\/li>\n\n\n\n<li><strong>Scope.<\/strong> This protects MemberMouse's <strong>AJAX login endpoint<\/strong> (<code>module-handle<\/code> \u2192 <code>MM_LoginFormView<\/code>). It does <strong>no<\/strong> alter WordPress's own <code>wp-login.php<\/code>.<br><\/li>\n\n\n\n<li><strong>Naming note.<\/strong> The stored option key is <code>mm-option-use-mm-nonce-validation<\/code> (internal &#8220;mm-nonce&#8221; naming) even though the UI label says &#8220;WP nonce validation.&#8221; It does use WordPress's native nonce API (<code>wp_nonce_field<\/code> \/ <code>wp_verify_nonce<\/code>).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Error messages a user might see (when ON)<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Message<\/th><th>Cause<\/th><\/tr><\/thead><tbody><tr><td><code>Invalid request parameters.<\/code><\/td><td>En <code>mm-security<\/code> nonce field was not present in the POST (e.g., custom form missing the password field, or a forged request).<\/td><\/tr><tr><td><code>Invalid nonce.<\/code><\/td><td>A nonce was sent but failed <code>wp_verify_nonce<\/code> (expired, cached\/stale page, or forged\/invalid token).<\/td><\/tr><\/tbody><\/table><\/figure>","protected":false},"excerpt":{"rendered":"<p>Setting location: MemberMouse \u2192 WordPress Settings \u2192 Login Page \u2192 &#8220;Use the WP nonce validation for login.&#8221; When enabled, a login submitted through the MemberMouse login form is rejected unless&#8230;<\/p>","protected":false},"author":18796,"comment_status":"open","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"om_disable_all_campaigns":false,"_strive_editorial_status":"not-started","_strive_copy_of":0,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"ht-kb-category":[195],"ht-kb-tag":[],"class_list":["post-22069","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-general-settings-articles"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/ht-kb\/22069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/ht-kb"}],"about":[{"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/users\/18796"}],"replies":[{"embeddable":true,"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/comments?post=22069"}],"version-history":[{"count":1,"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/ht-kb\/22069\/revisions"}],"predecessor-version":[{"id":22070,"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/ht-kb\/22069\/revisions\/22070"}],"wp:attachment":[{"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/media?parent=22069"}],"wp:term":[{"taxonomy":"ht_kb_category","embeddable":true,"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/ht-kb-category?post=22069"},{"taxonomy":"ht_kb_tag","embeddable":true,"href":"https:\/\/membermouse.com\/es\/wp-json\/wp\/v2\/ht-kb-tag?post=22069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}