wlsf
Webform Leet Speak Filter (WLF) validates Webform submissions for abusive
language, including evasion techniques such as leet speak character
substitutions, homoglyphs, and repeated character padding.
Features:
- Leet speak normalizer (@→a, 3→e, $→s, v→u, fuuuuck→fuck, fucccck→fuck)
- Word-level exact matching — prevents false positives (ash ≠ ass)
- Per-language word lists for multilingual sites
- Real-time JavaScript detection while the user types
- Server-side PHP validation (works when JS is disabled)
- Configurable error message with @field_label token
- Watchdog logging of blocked submissions with matched word and IP
- Excluded fields list for internal/hidden fields
- Webform Handler plugin — attach per-webform via the Webform UI
Compatible with Drupal 9, 10, and 11.
Installation
Via Composer (Recommended)
composer require drupal/wlsf drush en wlsf -y drush cr
Manual Installation
- Download the module from the project page.
- Place the folder inside
modules/contrib/in your Drupal root. - Go to Extend (
/admin/modules), search for Webform Leet Speak Filter, check the checkbox, and click Install. - Run
drush cror clear caches via Configuration → Performance.
Requirement: The Webform module must be installed before enabling this module.
Configuration
Step 1 — Add your bad words list
- Go to Configuration → Webform → Leet Speak Filter
(/admin/config/webform/webform-leetspeak). - Enter your blocked words in the Global Bad Words List — one word per line.
- You only need to enter the base word. The normalizer automatically catches all
variations —f*ck,fu@k,fvck,
fuuuuck,fucccck,a$$are all caught
by listingfuckandass.
Step 2 — Configure per-language word lists (multilingual sites)
- On the same settings page, expand Per-Language Bad Words Lists.
- Add language-specific words for each active language — one word per line.
- These are merged with the global list at runtime. The active request language
determines which list is used.
Step 3 — Set your error message
- Under Error Messages, enter the message shown to users
when a bad word is detected. - Use the
@field_labeltoken to include the field name in the message.
Example: "The @field_label field contains inappropriate content.
Please review your submission."
Step 4 — Configure options
- Enable real-time JavaScript detection — shows an inline error
while the user is typing, before the form is submitted. Recommended. - Log violations to watchdog — logs every blocked submission
to Reports → Recent log messages
(/admin/reports/dblog) with the matched word, field name,
webform ID, and client IP. - Excluded fields — comma-separated list of field machine names
to skip. Useful for hidden, internal, or token fields that should not be checked.
Example:internal_notes, honeypot_field, submission_token
Click Save configuration when done.
Attaching the Handler to a Webform
The module works as a Webform Handler — you attach it individually
to each webform you want to protect.
- Go to Structure → Webforms (
/admin/structure/webform). - Click Build next to your webform, then go to the
Settings → Emails/Handlers tab.
Or navigate directly:
/admin/structure/webform/manage/YOUR_WEBFORM_ID/handlers - Click Add handler.
- Find Leet Speak Abuse Filter under the
Validation category and click Add handler. - Click Save on the handler configuration screen
(no additional configuration required on the handler itself —
all settings are managed globally at
/admin/config/webform/webform-leetspeak). - Clear caches:
drush cror
Configuration → Performance → Clear all caches.
Repeat steps 1–6 for each webform you want to protect.
How It Works
The module runs two layers of protection:
- Client-side (JavaScript) — detects bad words in real time
as the user types and shows an inline error immediately below the offending
field. The form cannot be submitted while an error is active. - Server-side (PHP) — validates every submission on the server
regardless of whether JavaScript ran. This is the hard safety net — it cannot
be bypassed by disabling JavaScript or manipulating the browser.