Mercurial > prosody-modules
changeset 6322:f110bce35630
mod_block_registrations: Support blocking confusable usernames (UTS 39)
This prevents registering e.g. "admin" but with a Cyrillic 'a' U+0430
and other such variations, including keming like "adrnin".
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 06 Sep 2025 21:02:26 +0200 |
| parents | 2f01497b04c9 |
| children | 6216d85162dc |
| files | mod_block_registrations/README.md mod_block_registrations/mod_block_registrations.lua |
| diffstat | 2 files changed, 24 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_block_registrations/README.md Sat Sep 06 19:25:15 2025 +0200 +++ b/mod_block_registrations/README.md Sat Sep 06 21:02:26 2025 +0200 @@ -24,6 +24,7 @@ block_registrations_users *See source code* A list of reserved usernames block_registrations_matching `{ }` A list of [Lua patterns](http://www.lua.org/manual/5.1/manual.html#5.4.1) matching reserved usernames (slower than block_registrations_users) block_registrations_require `nil` A pattern that registered user accounts MUST match to be allowed + block_registrations_confusable `true` Block usernames that look similar to the reserved usernames (requires Prosody be built with ICU) Some examples: @@ -37,6 +38,6 @@ ============= ------ ------- + 13.0 Should work (please test) 0.12 Works - 0.11 Work ------ -------
--- a/mod_block_registrations/mod_block_registrations.lua Sat Sep 06 19:25:15 2025 +0200 +++ b/mod_block_registrations/mod_block_registrations.lua Sat Sep 06 21:02:26 2025 +0200 @@ -1,12 +1,29 @@ -local st = require "util.stanza"; local nodeprep = require "util.encodings".stringprep.nodeprep; +local normal = nodeprep; +if module:get_option_boolean("block_registrations_confusable", true) then + local confusable = require "util.encodings".confusable; + if not confusable then + module:log("error", "Prosody not built with ICU, confusables mapping is unavailable."); + module:log("error", "Rebuild or disable this feature with 'block_registrations_confusable = false'"); + end + function normal(username) + if username then + username = nodeprep(username); + end + if username then + username = confusable.skeleton(username); + end + return username; + end +end + local block_users = module:get_option_set("block_registrations_users", { "abuse", "admin", "administrator", "hostmaster", "info", "news", "noc", "operator", "owner", "postmaster", "register", "registration", "root", "security", "service", "signup", "support", "sysadmin", "sysop", "system", "test", "trouble", "webmaster", "www", "xmpp", -}); +}) / normal; local block_patterns = module:get_option_set("block_registrations_matching", {}); local require_pattern = module:get_option_string("block_registrations_require"); @@ -14,6 +31,9 @@ -- Check if the username is simply blocked if block_users:contains(username) then return true; end + local normalized_username = normal(username); + if block_users:contains(normalized_username) then return true; end + for pattern in block_patterns do if username:find(pattern) then return true;
