Lw firewall registration guard
Skill Lonsdale201/wp-agent-skills/lw-plugins/lw-firewall-registration-guard
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill lw-firewall-registration-guardAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Integrate custom WordPress registration forms with LW Firewall's registration spam protection. Use when code renders or validates custom signup forms, AJAX/REST registration endpoints, Woo/CRM/LMS registration flows, or files referencing `RegisterGuard::render_fields`, `RegisterGuard::validate`, `RegisterToken::issue`, `RegisterToken::verify`, `lw_fw_reg_token`, `lw_fw_url`, `registration_errors`, honeypot fields, proof-of-render tokens, single-use tokens, or spam auto-ban behavior.
SKILL.md
7.1 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it
LW Firewall: registration spam guard
Use this when a plugin/theme renders its own registration form and still wants LW Firewall's proof-of-render token, honeypot, single-use replay protection, and rejected-registration auto-ban.
LW Firewall automatically protects only the default WordPress registration form
via register_form and registration_errors, and only when users_can_register
is enabled. Custom forms must opt in.
Core contract
Verified field names:
| Field | Purpose |
|---|---|
lw_fw_reg_token | signed HMAC proof-of-render token |
lw_fw_url | honeypot text field; must stay empty |
Verified public methods:
| Method | Use |
|---|---|
LightweightPlugins\Firewall\Rules\RegisterGuard::render_fields() | echo hidden token and optional honeypot |
LightweightPlugins\Firewall\Rules\RegisterGuard::validate( WP_Error $errors ) | validate current $_POST, record reject, add generic error |
LightweightPlugins\Firewall\Rules\RegisterToken::issue() | issue token for headless/custom rendering |
LightweightPlugins\Firewall\Rules\RegisterToken::verify() | verify token manually |
LightweightPlugins\Firewall\Rules\RegisterTracker::record_reject() | count reject and auto-ban after threshold |
Do not call private methods or edit worker/lw-firewall-worker.php.
Preferred integration
If the form is server-rendered PHP, render fields directly inside the form:
use LightweightPlugins\Firewall\Rules\RegisterGuard;
if ( class_exists( RegisterGuard::class ) ) {
RegisterGuard::render_fields();
}
Then validate before creating the user:
use LightweightPlugins\Firewall\Rules\RegisterGuard;
$errors = new WP_Error();
if ( class_exists( RegisterGuard::class ) ) {
$errors = RegisterGuard::validate( $errors );
}
if ( $errors->has_errors() ) {
return $errors;
}
// Create the user only after the guard passes.
This path keeps the plugin's own behavior intact: honeypot check, token age check, optional single-use storage, reject counting, whitelist skip, and auto-ban through the shared firewall ban store.
Headless or REST form
If the form is not rendered by PHP output, issue the token server-side and send it in the response that renders the form:
use LightweightPlugins\Firewall\Options;
use LightweightPlugins\Firewall\Rules\RegisterToken;
$payload['lwFirewall'] = [
'enabled' => class_exists( RegisterToken::class ),
'token' => class_exists( RegisterToken::class ) ? RegisterToken::issue() : '',
'tokenName' => 'lw_fw_reg_token',
'honeyName' => 'lw_fw_url',
'honeypot' => (bool) Options::get( 'register_honeypot', true ),
];
Render the honeypot as a hidden/off-screen text input and submit both fields with the registration request. Do not create a public "give me a token" endpoint that can be spammed independently from the form render.
Manual validation
Use manual validation only when RegisterGuard::validate() cannot fit the
handler shape:
use LightweightPlugins\Firewall\Options;
use LightweightPlugins\Firewall\Rules\RegisterToken;
use LightweightPlugins\Firewall\Rules\RegisterTracker;
$honeypot = isset( $_POST['lw_fw_url'] )
? sanitize_text_field( wp_unslash( $_POST['lw_fw_url'] ) )
: '';
if ( Options::get( 'register_honeypot', true ) && '' !== $honeypot ) {
RegisterTracker::record_reject();
return new WP_Error( 'lw_fw_spam', __( 'Registration failed, please try again.', 'text-domain' ) );
}
$token = isset( $_POST['lw_fw_reg_token'] )
? sanitize_text_field( wp_unslash( $_POST['lw_fw_reg_token'] ) )
: '';
$storage = null;
if ( Options::get( 'register_single_use', true ) && function_exists( 'lw_firewall_resolve_storage' ) ) {
$storage = lw_firewall_resolve_storage( (string) Options::get( 'storage', 'auto' ) );
}
$ok = RegisterToken::verify(
$token,
(int) Options::get( 'register_min_fill_time', 2 ),
(int) Options::get( 'register_token_max_age', 3600 ),
$storage
);
if ( ! $ok ) {
RegisterTracker::record_reject();
return new WP_Error( 'lw_fw_spam', __( 'Registration failed, please try again.', 'text-domain' ) );
}
Use a generic error. Do not tell bots whether the honeypot, token age, expiry, or single-use check failed.
Important behavior
- Missing token is spam.
- Filled honeypot is spam when
register_honeypotis enabled. - Token age lower than
register_min_fill_timeis spam. - Token age higher than
register_token_max_ageis spam. - Reused token is spam when
register_single_useis enabled. RegisterTracker::record_reject()skips whitelisted IPs.- After
register_ban_thresholdrejects, the IP is banned forregister_ban_duration. - Auto-ban is written to the same storage used by the MU-plugin worker, so later requests are blocked before WordPress fully loads.
Checklist
- Render the guard fields inside every custom registration form.
- Preserve both fields through AJAX/REST serialization.
- Validate before calling
wp_insert_user(),wp_create_user(), Woo customer creation, CRM contact creation, or LMS enrollment. - Keep normal CSRF nonce/capability checks; LW Firewall token is anti-spam, not a WordPress nonce.
- Test too-fast submit, expired token, reused token, filled honeypot, and valid submit.
- Confirm whether your custom form should respect
users_can_register; LW Firewall's automatic core hook does.
Cross-references
- Run
wp-security-auditfor nonce/sanitization/escaping checks around the form. - Run
lw-firewall-rate-limit-workerwhen the endpoint also needs rate limiting. - Run
wp-rest-apiif the form submits through a REST route.
What this skill does NOT cover
- Captcha provider integration.
- Non-registration contact-form spam.
- Editing LW Firewall internals or the MU-plugin worker.
References
- Official documentation: https://github.com/lwplugins/lw-firewall
- Verified source paths:
wp-content/plugins/lw-firewall/includes/Plugin.phpwp-content/plugins/lw-firewall/includes/Rules/RegisterGuard.phpwp-content/plugins/lw-firewall/includes/Rules/RegisterToken.phpwp-content/plugins/lw-firewall/includes/Rules/RegisterTracker.phpwp-content/plugins/lw-firewall/includes/Rules/AutoBanner.phpwp-content/plugins/lw-firewall/includes/Options.phpwp-content/plugins/lw-firewall/includes/helpers.phpwp-content/plugins/lw-firewall/tests/register-token-test.phpwp-content/plugins/lw-firewall/CHANGELOG.md