zendframework / zend-captcha

Captcha component from Zend Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

setExpirationHops() bug

ares333 opened this issue · comments

commented

The bug can recur very easily.

<?php
use Zend\Captcha\Figlet;

require 'vendor/autoload.php';

$captcha = new Figlet();

if (empty($_GET['input'])) {
    $captcha->getSession()->setExpirationHops(1);
    echo $id = $captcha->generate() . '<br>';
    echo $word = $captcha->getWord();
} else {
    var_dump(
        $captcha->isValid(
            [
                'id' => $_GET['id'],
                'input' => $_GET['input']
            ]));
}

In generate stage I set expirationHops to 1. Validation stage can be executed many times and will always output bool(true).

I dive into the code and find the cause.
In class Zend\Captcha\AbstractWord (line 253)

    /**
     * Get session object
     *
     * @throws Exception\InvalidArgumentException
     * @return Container
     */
    public function getSession()
    {
        if (! isset($this->session) || (null === $this->session)) {
            $id = $this->getId();
            if (! class_exists($this->sessionClass)) {
                throw new Exception\InvalidArgumentException("Session class $this->sessionClass not found");
            }
            $this->session = new $this->sessionClass('Zend_Form_Captcha_' . $id);
            $this->session->setExpirationHops(1, null);
            $this->session->setExpirationSeconds($this->getTimeout());
        }
        return $this->session;
    }

In validation stage "$this->session->setExpirationHops(1, null);" will reset expirationHops. But expirationHops will not take effect in the same request. So after isValid() hops will always be 1.

This repository has been closed and moved to laminas/laminas-captcha; a new issue has been opened at laminas/laminas-captcha#1.