From c28dc0d3d24360385f0ab9bd9481cde40c3f7aad Mon Sep 17 00:00:00 2001 From: calzoneman Date: Fri, 19 Jun 2015 16:44:25 -0400 Subject: [PATCH] Fix #489 Channels are occasionally plagued by trolls who confuse users by "hijacking" names of other users in the channel. This is accomplished by replacing certain letters with visually similar letters (in fact, indistinguishable in some sans-serif fonts), e.g. replacing lowercase 'l' with capital 'I' This commit replaces capital 'I', lowercase 'l', digit '1', lowercase 'o', uppercase 'O', and digit '0' with '_' and changes the matching for isUsernameTaken() to a LIKE query. Since '_' is a single character wildcard, this causes the database to treat a username with one of these simple replacements as already registered. --- lib/database/accounts.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/database/accounts.js b/lib/database/accounts.js index 51f0a101..f270e5d7 100644 --- a/lib/database/accounts.js +++ b/lib/database/accounts.js @@ -7,6 +7,15 @@ var Logger = require("../logger"); var registrationLock = {}; var blackHole = function () { }; +/** + * Replaces look-alike characters with "_" (single character wildcard) for + * use in LIKE queries. This prevents guests from taking names that look + * visually identical to existing names in certain fonts. + */ +function wildcardSimilarChars(name) { + return name.replace(/[Il1oO0]/g, "_"); +} + module.exports = { init: function () { }, @@ -15,7 +24,7 @@ module.exports = { * Check if a username is taken */ isUsernameTaken: function (name, callback) { - db.query("SELECT name FROM `users` WHERE name=?", [name], + db.query("SELECT name FROM `users` WHERE name LIKE ?", [wildcardSimilarChars(name)], function (err, rows) { if (err) { callback(err, true);