Yii 1.1: Activate captcha after unsuccessful login attempts


Like gmail, if you have tree or more unsuccessful login attemps a captcha appears

But, how to do this with Yii ?

Modify your login Model like that

class LoginForm extends CFormModel {
     public $verifyCode;
     public function rules() {
        return array(
            array('username, password', 'required'),
            array('rememberMe', 'boolean'),
            array('password', 'authenticate'),
            array('verifyCode', 'captcha', 'allowEmpty' => !CCaptcha::checkRequirements(), 'on' => 'withCaptcha'), //only on withCaptcha scenario

In your controller

public function actionLogin() {
        $model = new LoginForm;
        if (Yii::app()->user->getState('attempts-login') > 3) { //make the captcha required if the unsuccessful attemps are more of thee
            $model->scenario = 'withCaptcha';
        if (isset($_POST['LoginForm'])) {
            $model->attributes = $_POST['LoginForm'];
            if ($model->validate() && $model->login()) {
                Yii::app()->user->setState('attempts-login', 0); //if login is successful, reset the attemps
            } else {  //if login is not successful, increase the attemps 
                Yii::app()->user->setState('attempts-login', Yii::app()->user->getState('attempts-login', 0) + 1);
                if (Yii::app()->user->getState('attempts-login') > 3) { 
                    $model->scenario = 'withCaptcha'; //useful only for view
        $this->render('login', array('model' => $model));
Finally in your view login add this to the form
<?php if ($model->scenario == 'withCaptcha' && CCaptcha::checkRequirements()): ?>
            <div class="row">
                <?php echo $form->labelEx($model, 'verifyCode'); ?>
                    <?php $this->widget('CCaptcha'); ?>
                    <?php echo $form->textField($model, 'verifyCode'); ?>
                <?php echo $form->error($model, 'verifyCode'); ?>
        <?php endif; ?>

Total 20 comments

#19162 report it
ajith at 2015/03/31 12:39am

thanks man it worked for me... :)

#17803 report it
Kostas Apazidis (KonApaz) at 2014/07/24 05:40am
RE: 17802

Thanks for the sharing :)

#17802 report it
Milan Zivkovic at 2014/07/24 05:13am
Just to add this link with really great idea how to solve this kind of issue


Here is blog post with one really great idea how to solve such kind of issue. In summary its not about cookies, session and IPs, since all of them can be not safe, but what we can track safe is what user or machine trying to do. So we will need to care about using same username/email with different passwords, or using same password with different emails. Also good idea is to not block on some time, instead of that simulate slow server response, so real user will still have chance to login to system and than use it normal, but machine will be almost useless.

#17616 report it
Rohit Suthar at 2014/07/08 05:12am
nice articles

Thank You very much for your patience and sharing your knowledge..

#16092 report it
hshfcb at 2014/01/19 10:46am

This is vey good..thank a lot

#15399 report it
adreno at 2013/11/06 10:25am
Nice post

I used this in combination with http://www.yiiframework.com/forum/index.php/topic/44996-defender-class-to-manage-failed-logins/ Works well enough.

#13984 report it
Kostas Apazidis (KonApaz) at 2013/07/10 02:29pm
Re: Re: unsafe

Google and other websites could not authenticate the users (SESSION ID) if cookies not allowed except if the SID pass through the URL on each request.

So, the same thing will be occurred with bots (just by removing sid from the url as you said that the same thing happens with cookies), so the problem remains with or not cookies.

I agree with you that there are advantages and disadvantages using combination of IP, cookies, sessions etc checks and time delays. (Securing vs Resources vs user facility)

So if you or someone else find the golden ratio please make an extension for that :)

#13969 report it
este at 2013/07/09 07:48pm

I wrote a "Defender" class that helps with failed login attempts, IPs, locks, bans, using the db: it works, but you should test and improve it to use in production. I do not know if someone did an extension for Yii, that would be simple and I think you should stay simple. The goal is to avoid giving the attacker a way to make an even more devastating DOS. Only one very simple query is necessary to determine if the IP is locked, and code should be optimized as much as possible.

See here this Defender class, to be considered as a starting point: Defender class to manage failed logins and more

#13968 report it
este at 2013/07/09 07:41pm
Re: unsafe

KonApaz, I do not think Google doesn't allow cookie-less hosts mostly for security reasons. Cookie-less users are useless for their business and services. But this is another subject.

The point is that you can write a program that just deletes the cookie after every post request, and the game would be over. The next request the host will simply be a new host for your application, even if you store a key into the session and test it during the post request.

You are totally right when you say that even checking IPs is not enough to protect from **everything** and that a combination of IP records and sessions could be good: yes, if you can afford it there are many things you could do (really A LOT), but you are also adding complexity and using resources (memory, cpu) and maybe you do not really need it or sometimes you risk to even help the attacker, if your defense system had some leaks. Best test is the community i think: submit a solution and ask people to find the leaks.

Actually a good DOS attack may be done from hundreds of different IPs, but even then, an IP check solution would still be a bit more reliable and help somehow, because no human fails loggin in 100 or 10000 times in 10 minutes, and you could at least get quickly rid of many of them, trying to save your site from being killed too easily.

#13967 report it
trond at 2013/07/09 06:52pm

I'm sure you are right. So many good things are emerging from the Yii community. The ideas outlined by este seems to be the way to go.

#13965 report it
Kostas Apazidis (KonApaz) at 2013/07/09 05:20pm
RE: Extension

Dear trond

I think all Yii users belong to big and qualified community

So, somebody write a wiki, another one tips, posts, answers etc. Thought all of them, Yii user could be create a such extension :)

If this extension it could be so useful, lets somebody makes one :) (or I will make it)

#13964 report it
Kostas Apazidis (KonApaz) at 2013/07/09 05:06pm
Re: Unsafe

Dear este

As I mentioned in this comment http://www.yiiframework.com/wiki/515/activate-captcha-after-unsuccessful-login-attempts/#c13845 there are issues either using ip or user id.

A better way to make it more secured is the combination user id and ip and only with enabled cookies.

The attempts not stored on client side but on server side with session. So why did you say that is unsafe?

In cookies the only stored info is the unique ID that was generated by $_SESSION, so if anyone or something modify or delete the session will be signed as invalid.

In this case you can prevent the specific user to login (without accepted SESSION no one can be login in the system). Google (gmail) not permit you to login without cookies.

I didn't write this wiki to make the most secured system but to provide a little bit secure (related without it or a similar one)

#13959 report it
trond at 2013/07/09 12:47pm

Anyone written an extension that does that?

#13958 report it
este at 2013/07/09 11:37am

This is important to say, as noticed on the other Wiki about the same subject, that this is totally unsafe and unfortunately useless. A safe (or at least safer) solution should rely on IPs and store failed logins on the db. Don't think Google relies on cookies to protect its mails. See my proposition here: http://www.yiiframework.com/forum/index.php/topic/44996-defender-class-to-manage-failed-logins/

On the other hand this is a good solution for logged users, if you want to limit repeated actions in little time (like posting many times or similar).

#13846 report it
ibrahimd at 2013/07/01 03:13pm
another security layer

@KonApaz Actually we're talking about samething. If someone is able to bypass this implementation by simply disabling cookies, that means we're doing something wrong :)

We need to lock that user account's login action for a time period. Because, captcha is required for humans, not bots if cookies disabled. It's nonsense to force an actual user to prove that he is a human when competetors are also human.

In conclusion there are 2 ways that make sense: 1- Activate captcha always. Don't count attempts. 2- Forget about captcha. Just block that account to login action after 5 failed attempts for 15 minutes.

#13845 report it
Kostas Apazidis (KonApaz) at 2013/07/01 02:57pm
About securing

Dear ibrahimd

both Yii::app()->user->getState and Yii::app()->session not working if cookies are disabled on client side (PHPSESSID cookie is required)

On the other hand it is not useful to store the attempts foreach user id. Think, your account forcing by bot or another user and then you(the real user) attempt on the first time with unexpected captcha! or the forcing take place more than one user

Think also you are on internet in your university pc and the external ip is only one, all the other users will get a captcha.

May you could combine user id and ip in one but even in this case there are also issues

The best way to solve this problem is to prevent user (or bot) from the website when no cookies accepted (as the google - gmail does)

#13844 report it
ibrahimd at 2013/07/01 02:12pm
an addition

using sessions ( getState ) isn't secure enough. if the client doesn't support or disabled receiving cookies, login attempts counter won't work. you should track this info in the database with user id or ip etc.

#13763 report it
zitter at 2013/06/23 07:30pm
Don't worry

KonApaz no problem: two wikis is better than one ;)

#13761 report it
Kostas Apazidis (KonApaz) at 2013/06/23 06:36pm
About another wiki

I am asking apologies from Yii community, this wiki is similar with one that zitter mentioned.

I wrote this wiki based on the fact that no given wiki-answering in the forum post: http://www.yiiframework.com/forum/index.php/topic/43999-activate-a-captcha-after-of-several-times/page__p__208650__fromsearch__1#entry208650

#13758 report it
zitter at 2013/06/23 12:47pm
Another wiki about this

Leave a comment

Please to leave your comment.

Write new article