Added honey pot function
authorMarcel Werk <burntime@woltlab.com>
Thu, 13 Jun 2013 00:03:37 +0000 (02:03 +0200)
committerMarcel Werk <burntime@woltlab.com>
Thu, 13 Jun 2013 00:03:37 +0000 (02:03 +0200)
com.woltlab.wcf/templates/register.tpl
wcfsetup/install/files/lib/form/RegisterForm.class.php
wcfsetup/install/files/lib/util/UserRegistrationUtil.class.php

index 8ab4031b000f12b6d64cffcecf6bac4a8cc2b038..d11aef5eb288541795a124365284468397d5e57c 100644 (file)
                                'wcf.user.confirmPassword.error.notEqual' : '{lang}wcf.user.confirmPassword.error.notEqual{/lang}'
                        });
                        
-                       new WCF.User.Registration.Validation.EmailAddress($('#email'), $('#confirmEmail'), null);
-                       new WCF.User.Registration.Validation.Password($('#password'), $('#confirmPassword'), null);
-                       new WCF.User.Registration.Validation.Username($('#username', null, {
+                       new WCF.User.Registration.Validation.EmailAddress($('#{@$randomFieldNames[email]}'), $('#{@$randomFieldNames[confirmEmail]}'), null);
+                       new WCF.User.Registration.Validation.Password($('#{@$randomFieldNames[password]}'), $('#{@$randomFieldNames[confirmPassword]}'), null);
+                       new WCF.User.Registration.Validation.Username($('#{@$randomFieldNames[username]}', null, {
                                minlength: {@REGISTER_USERNAME_MIN_LENGTH},
                                maxlength: {@REGISTER_USERNAME_MAX_LENGTH}
                        }));
                });
                //]]>
        </script>
+       
+       <style type="text/css"> 
+               #fieldset1 {
+                       height: 0;
+                       overflow: hidden;
+                       position: absolute;
+                       left: -9000px;
+                       max-width: 8000px; 
+               }
+       </style>
 </head>
 
 <body id="tpl{$templateName|ucfirst}">
                        
                        <dl{if $errorType.username|isset} class="formError"{/if}>
                                <dt>
-                                       <label for="username">{lang}wcf.user.username{/lang}</label>
+                                       <label for="{@$randomFieldNames[username]}">{lang}wcf.user.username{/lang}</label>
                                </dt>
                                <dd>
-                                       <input type="text" id="username" name="username" value="{$username}" required="required" class="medium" />
+                                       <input type="text" id="{@$randomFieldNames[username]}" name="{@$randomFieldNames[username]}" value="{$username}" required="required" class="medium" />
                                        {if $errorType.username|isset}
                                                <small class="innerError">
                                                        {if $errorType.username == 'empty'}{lang}wcf.global.form.error.empty{/lang}{/if}
                        {event name='usernameFields'}
                </fieldset>
                
+               <fieldset id="fieldset1">
+                       <legend>{lang}wcf.user.honeyPot{/lang}</legend>
+                       
+                       <small>{lang}wcf.user.honeyPot.description{/lang}</small>
+                       
+                       <dl>
+                               <dt>
+                                       <label for="username">{lang}wcf.user.username{/lang}</label>
+                               </dt>
+                               <dd>
+                                       <input type="text" id="username" name="username" value="" autocomplete="off" class="medium" tabindex="998" />
+                               </dd>
+                       </dl>
+                       
+                       <dl>
+                               <dt>
+                                       <label for="username">{lang}wcf.user.email{/lang}</label>
+                               </dt>
+                               <dd>
+                                       <input type="email" id="email" name="email" value="" autocomplete="off" class="medium" tabindex="999" />
+                               </dd>
+                       </dl>
+                       
+                       {event name='honeyPotFields'}
+               </fieldset>
+               
                <fieldset>
                        <legend>{lang}wcf.user.email{/lang}</legend>
                        
                        <dl{if $errorType.email|isset} class="formError"{/if}>
                                <dt>
-                                       <label for="email">{lang}wcf.user.email{/lang}</label>
+                                       <label for="{@$randomFieldNames[email]}">{lang}wcf.user.email{/lang}</label>
                                </dt>
                                <dd>
-                                       <input type="email" id="email" name="email" value="{$email}" required="required" class="medium" />
+                                       <input type="email" id="{@$randomFieldNames[email]}" name="{@$randomFieldNames[email]}" value="{$email}" required="required" class="medium" />
                                        {if $errorType.email|isset}
                                                <small class="innerError">
                                                        {if $errorType.email == 'empty'}{lang}wcf.global.form.error.empty{/lang}{/if}
                        
                        <dl{if $errorType.confirmEmail|isset} class="formError"{/if}>
                                <dt>
-                                       <label for="confirmEmail">{lang}wcf.user.confirmEmail{/lang}</label>
+                                       <label for="{@$randomFieldNames[confirmEmail]}">{lang}wcf.user.confirmEmail{/lang}</label>
                                </dt>
                                <dd>
-                                       <input type="email" id="confirmEmail" name="confirmEmail" value="{$confirmEmail}" required="required" class="medium" />
+                                       <input type="email" id="{@$randomFieldNames[confirmEmail]}" name="{@$randomFieldNames[confirmEmail]}" value="{$confirmEmail}" required="required" class="medium" />
                                        {if $errorType.confirmEmail|isset}
                                                <small class="innerError">
                                                        {if $errorType.confirmEmail == 'notEqual'}{lang}wcf.user.confirmEmail.error.notEqual{/lang}{/if}
                                
                                <dl{if $errorType.password|isset} class="formError"{/if}>
                                        <dt>
-                                               <label for="password">{lang}wcf.user.password{/lang}</label>
+                                               <label for="{@$randomFieldNames[password]}">{lang}wcf.user.password{/lang}</label>
                                        </dt>
                                        <dd>
-                                               <input type="password" id="password" name="password" value="{$password}" required="required" class="medium" />
+                                               <input type="password" id="{@$randomFieldNames[password]}" name="{@$randomFieldNames[password]}" value="{$password}" required="required" class="medium" />
                                                {if $errorType.password|isset}
                                                        <small class="innerError">
                                                                {if $errorType.password == 'empty'}{lang}wcf.global.form.error.empty{/lang}{/if}
                                
                                <dl{if $errorType.confirmPassword|isset} class="formError"{/if}>
                                        <dt>
-                                               <label for="confirmPassword">{lang}wcf.user.confirmPassword{/lang}</label>
+                                               <label for="{@$randomFieldNames[confirmPassword]}">{lang}wcf.user.confirmPassword{/lang}</label>
                                        </dt>
                                        <dd>
-                                               <input type="password" id="confirmPassword" name="confirmPassword" value="{$confirmPassword}" required="required" class="medium" />
+                                               <input type="password" id="{@$randomFieldNames[confirmPassword]}" name="{@$randomFieldNames[confirmPassword]}" value="{$confirmPassword}" required="required" class="medium" />
                                                {if $errorType.confirmPassword|isset}
                                                        <small class="innerError">
                                                                {if $errorType.confirmPassword == 'notEqual'}{lang}wcf.user.confirmPassword.error.notEqual{/lang}{/if}
index 7052daaea697fc69763d6c8bfa299a626d880214..29645cb40d14e335d67fdcf1f5afbf746b88131a 100644 (file)
@@ -75,6 +75,12 @@ class RegisterForm extends UserAddForm {
         */
        public $useCaptcha = true;
        
+       /**
+        * field names
+        * @var array
+        */
+       public $randomFieldNames = array();
+       
        /**
         * min number of seconds between form request and submit
         * @var integer
@@ -112,25 +118,40 @@ class RegisterForm extends UserAddForm {
                }
        }
        
-       /**
-        * wcf\acp\form\AbstractOptionListForm::initOptionHandler()
-        */
-       protected function initOptionHandler() {
-               $this->optionHandler->setInRegistration();
-               parent::initOptionHandler();
-       }
-       
        /**
         * @see wcf\form\IForm::readFormParameters()
         */
        public function readFormParameters() {
                parent::readFormParameters();
+       
+               if (!empty($this->username) || !empty($this->email)) {
+                       throw new PermissionDeniedException();
+               }
+               
+               $this->randomFieldNames = WCF::getSession()->getVar('registrationRandomFieldNames');
+               if ($this->randomFieldNames === null) {
+                       throw new PermissionDeniedException();
+               }
+               
+               if (isset($_POST[$this->randomFieldNames['username']])) $this->username = StringUtil::trim($_POST[$this->randomFieldNames['username']]);
+               if (isset($_POST[$this->randomFieldNames['email']])) $this->email = StringUtil::trim($_POST[$this->randomFieldNames['email']]);
+               if (isset($_POST[$this->randomFieldNames['confirmEmail']])) $this->confirmEmail = StringUtil::trim($_POST[$this->randomFieldNames['confirmEmail']]);
+               if (isset($_POST[$this->randomFieldNames['password']])) $this->password = $_POST[$this->randomFieldNames['password']];
+               if (isset($_POST[$this->randomFieldNames['confirmPassword']])) $this->confirmPassword = $_POST[$this->randomFieldNames['confirmPassword']];
                
                $this->groupIDs = array();
                if (isset($_POST['recaptcha_challenge_field'])) $this->challenge = StringUtil::trim($_POST['recaptcha_challenge_field']);
                if (isset($_POST['recaptcha_response_field'])) $this->response = StringUtil::trim($_POST['recaptcha_response_field']);
        }
        
+       /**
+        * wcf\acp\form\AbstractOptionListForm::initOptionHandler()
+        */
+       protected function initOptionHandler() {
+               $this->optionHandler->setInRegistration();
+               parent::initOptionHandler();
+       }
+       
        /**
         * @see wcf\form\IForm::validate()
         */
@@ -167,6 +188,17 @@ class RegisterForm extends UserAddForm {
                        }
                        
                        WCF::getSession()->register('registrationStartTime', TIME_NOW);
+                       
+                       // generate random field names
+                       $this->randomFieldNames = array(
+                               'username' => UserRegistrationUtil::getRandomFieldName('username'),
+                               'email' => UserRegistrationUtil::getRandomFieldName('email'),
+                               'confirmEmail' => UserRegistrationUtil::getRandomFieldName('confirmEmail'),
+                               'password' => UserRegistrationUtil::getRandomFieldName('password'),
+                               'confirmPassword' => UserRegistrationUtil::getRandomFieldName('confirmPassword')
+                       );
+                       
+                       WCF::getSession()->register('registrationRandomFieldNames', $this->randomFieldNames);
                }
        }
        
@@ -186,7 +218,8 @@ class RegisterForm extends UserAddForm {
                RecaptchaHandler::getInstance()->assignVariables();
                WCF::getTPL()->assign(array(
                        'isExternalAuthentication' => $this->isExternalAuthentication,
-                       'useCaptcha' => $this->useCaptcha
+                       'useCaptcha' => $this->useCaptcha,
+                       'randomFieldNames' => $this->randomFieldNames
                ));
        }
        
@@ -438,6 +471,8 @@ class RegisterForm extends UserAddForm {
                // login user
                UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $this->username, $this->password);
                WCF::getSession()->unregister('recaptchaDone');
+               WCF::getSession()->unregister('registrationRandomFieldNames');
+               WCF::getSession()->unregister('registrationStartTime');
                $this->saved();
                
                // forward to index page
index a60f3c8bb7d593ea9817cb298011e13b8dd5f5ef..680ac424d0d6b6dec638450c68057a1bd341a501 100644 (file)
@@ -95,4 +95,15 @@ final class UserRegistrationUtil {
        public static function getActivationCode($length = 9) {
                return MathUtil::getRandomValue(pow(10, $length - 1), pow(10, $length) - 1);
        }
+       
+       /**
+        * Generates a random field name.
+        * 
+        * @param       string          $fieldName
+        * @return      string
+        */
+       public static function getRandomFieldName($fieldName) {
+               $hash = StringUtil::getHash($fieldName . StringUtil::getRandomID());
+               return substr($hash, 0, mt_rand(8, 16));
+       }
 }