CVS edit link for alex.a

I want to publish a drupal module that prevents user impersonation that exploits the use
of greek characters that look identical with latin characters.

The site that I participate in, www.podilates.gr has been subjected to this impersonation.

I wrote a simple drupal module that validates user names in the registration form.
Other drupal sites may have the same need, especially sites with Greek users.
Going through drupal.org would make this module available to them, and also improve the quality of the module.
I searched through the drupal modules (not an easy task), and did not find this issue addressed.

Aside from this module, I may decide to write more modules relating to bicycle advocacy.

I include the module's detailed explanation from its README file below:
----------------------------------------------------------------------------------------------------------

Several Greek characters look identical to Latin (ascii) characters.
Greek-speaking users familiar with this fact have exploited this
to impersonate other users by constructing a username that is
different but looks the same as the user they want to impersonate.

For example, a user can register using the name "nikοs"
and start posting content that seems to be authored by "nikos".
These two names look identical in UTF-8, but they are different,
as you can see by viewing this file using another encoding.

More than half the Latin uppercase characters have Greek look-alikes:
ABEZHIKMNOPTYX opv
ΑΒΕΖΗΙΚΜΝΟΡΤΥΧ ορν

This module uses the hook_user drupal API to reject user names
that have mixed latin and non-ascii characters.
It affects only the user_register form
and displays an error message to the user.

To install, unpack into the modules directory.
There is no configuration other than enabling the module.

To test, enable the module and try to register using a name like 'aβ'.
You can leave the email address blank to make sure the registration
doesn't go through.

Alexandros Athanasopoulos

Comments

alex.a’s picture

StatusFileSize
new8.31 KB
alex.a’s picture

Status: Postponed (maintainer needs more info) » Needs review
alex.a’s picture

I didn't see any guidelines about language use. Does everything need to be in English? How about the strings in module.info? Are those translatable?
Originally I had the module strings in Greek, but in order to submit it to drupal, I changed them to English, and made the one code string translatable.

avpaderno’s picture

Issue tags: +Module review

Hello, and thanks for applying for a CVS account. I am adding the review tags, and some volunteers will review your code, pointing out what needs to be changed.

Comments, strings used in the user interface, and variable names should be in English. User interface strings should be translatable through t(), which require the source string to be in English; comments, and variable names should be in English to not stop who is able to provide patches for the module to contribute.

dawehner’s picture

Status: Needs review » Needs work
 * 
 * This module is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2 of the License.
 * This module is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this module.  If not, see <http://www.gnu.org/licenses/>.

Afaik you should remove it, the d.o script automatically creates the license.txt for every release.



function podi_has_english( $name ) {
  $len = strlen( $name );
  for( $i = 0; $i < $len; $i++) {
    $c = $name[$i];
    if ( ('a' <= $c && $c <= 'z') || ('A' <= $c && $c <= 'Z')) {
      return true;
    }
  }
  return false;
}

You should use the offiical code style of drupal, so for example TRUE instead of true, or function podi_has_english($name) {

avpaderno’s picture

For more details on how the code should be formatted, see http://drupal.org/coding-standards.

alex.a’s picture

StatusFileSize
new1.74 KB

followed drupal code conventions:
capitalized TRUE/FALSE
fixed spaces in function calls and control structures
removed licence info from podi.module.
removed LICENSE.txt

alex.a’s picture

Status: Needs work » Needs review
avpaderno’s picture

Assigned: Unassigned » avpaderno

I will review the code tomorrow, or the day after.

alex.a’s picture

Thanks for looking at this. I was wondering whether it "druped" through the cracks and I should publish it somewhere else.

avpaderno’s picture

Status: Needs review » Needs work
  1.         $msg = 'The username %user is not valid.';
            $msg = t($msg, array('%user' => $name));
            form_set_error($form_id, $msg);
    

    The first argument of t() must be a literal string; differently, the script that extracts the string to translate to create the translation template will not be able to extract the string, which would not be translatable (if not in the case another module uses the same exact string, but it's rather difficult it happens, when the string is dynamically changed).
    The first argument of form_set_error() is the identifier of the form field containing the error, not the form ID.

    Then, the three lines of code can be rewritten in only one.

  2. The code should use the Drupal Unicode functions, when available. The complete list is probably reported in http://drupal.org/coding-standards.
  3. package = www.podilates.gr
    version = 6.x-0.5.1
    

    The package is used for a different purpose, and it's not necessary for a single module. The version line must be removed, as it is already added by the packaging script, and having two lines like that confuses the update manager, which could not pick up the correct version.

alex.a’s picture

Status: Needs work » Needs review
StatusFileSize
new2.97 KB

Thanks for the code review. Corrected as follows (see new attachment):
1. Use string literal in t(). Fixed argument to form_set_error.
Also entered an issue in drupal.org to add 'literal' to the documentation of the t() function, but it was marked "won't fix". Congratulations for the quick processing: http://drupal.org/node/811668
3. Removed version and package from .info file.

2. I did not use drupal_strlen. I read about utf8 and decided that the code does what it is intended to do with strlen. I added a comment in the code.
Incidentally, I added a utf8 to unicode decoder which is used in the new page (see below). I may use it in the validation to fix the problem with rejecting mixed ASCII and non-ASCII latin characters.
Shouldn't these changes be happening within drupal version control?

Other Changes:
* Moved most code out of the .module file, so that it gets included only when it is used.
* Added a page that displays all existing user names that do not pass the name validation.

I also want to add: a) A Greek translation. b) A unit test. Don't know how to do these yet.

alex.a’s picture

Status: Needs review » Needs work

I will work on this some more. I found out that the menu page that I added uses t() incorrectly.

alex.a’s picture

Status: Needs work » Needs review
StatusFileSize
new3.72 KB

removed t() from menu title. Added greek translation.

alex.a’s picture

I should also replace $base_url with l(). Should I post a new tar file or can I do it in cvs later?

avpaderno’s picture

Status: Needs review » Needs work
  1. See http://drupal.org/coding-standards to understand how a module should be written. In particular, see how the code should be formatted.
  2. function podi_decode_utf8($s) {
      $len = strlen($s);
      $codes = array();
      $n = 1;
      for ($i = 0; $i < $len; $i += $n) {
        $c = ord($s[$i]);
        $v = $c;    
        if (($c & 0x80) == 0) {
          // first bit is 0:  1-byte ASCII character
          $n = 1;
        }  else if (($c & 0xe0) == 0xc0) {
          // first 3 bits are 110:  2-byte character
          $n = 2;
          $v = $c & 0x1f;
        }  else if (($c & 0xf0) == 0xe0) {
          // first 4 bits are 1110:  3-byte character
          $n = 3;
          $v = $c & 0xf;
        }  else if (($c & 0xf8) == 0xf0) {
          // first 5 bits are 11110:  4-byte character
          $n = 4;
          $v = $c & 7;
        }
        for ($j = 1; $j < $n && $i+$j < $len; $j++) {
          $c = ord($s[$i+$j]);
          $v = $v * 64 + ($c & 0x3f);       
        }
        $codes[] = $v;
      }
      return $codes;
    }
    

    Why isn't the function doing like the function drupal_convert_to_utf8() is doing?

  3. /**
     * Implemementation of hook_user
     */
    function podi_user($op, &$edit, &$account, $category = NULL) {
      if ($op == 'validate') {
        if ($edit['form_id'] == 'user_register') {
          // only prevent user registration.  User administration is not subject to this validation.
          $name = $edit['name'];
          module_load_include( 'inc', 'podi' );
          if (podi_is_mixed_language($name)) {       
            form_set_error('name', t('The username %user is not valid.', array('%user' => $name)));
          }
        }
      }
    }
    

    I am not sure that is the correct way to validate the username; the code should probably use hook_form_alter(), or hook_form_FORM_ID_alter().

  4. The comment for hook implementations should be Implements hook_user()., in example. The comments for hooks report Implemementation of.
avpaderno’s picture

Status: Needs work » Closed (won't fix)
avpaderno’s picture

Component: Miscellaneous » new project application
Assigned: avpaderno » Unassigned
Issue summary: View changes

Please read the following links as this is very important information about CVS applications.

Drupal.org has moved from CVS to Git! This is a very significant change for the Drupal community and for these applications. Please read Migrating from CVS Applications to (Git) Full Project Applications and Applying for permission to opt into security advisory coverage on how this affects and benefits you and the application process. In short, every user has now the permissions necessary to create new projects, but they need to apply for opt into security advisory coverage. Without applying, the projects will have a warning on projects that says:

This project is not covered by Drupal’s security advisory policy.