Apply firewall security on BaseForm::validateForm
modified: core/lib/Thelia/Controller/BaseController.php modified: core/lib/Thelia/Form/AddressCreateForm.php new file: core/lib/Thelia/Form/FirewallForm.php modified: core/lib/Thelia/Model/FormFirewall.php modified: setup/insert.sql
This commit is contained in:
committed by
Benjamin Perche
parent
b42ff568e0
commit
978f15357c
@@ -25,6 +25,7 @@ use Symfony\Component\Routing\Router;
|
||||
|
||||
use Thelia\Core\Template\TemplateHelper;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Form\FirewallForm;
|
||||
use Thelia\Model\OrderQuery;
|
||||
|
||||
use Thelia\Tools\Redirect;
|
||||
@@ -200,6 +201,14 @@ abstract class BaseController extends ContainerAware
|
||||
$form->bind($aBaseForm->getRequest());
|
||||
|
||||
if ($form->isValid()) {
|
||||
if ($aBaseForm instanceof FirewallForm && !$aBaseForm->isFirewallOk()) {
|
||||
throw new FormValidationException(
|
||||
$this->getTranslator()->trans(
|
||||
"You have too much sent this form. Please wait before trying again."
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
} else {
|
||||
$errorMessage = null;
|
||||
|
||||
@@ -21,7 +21,7 @@ use Thelia\Core\Translation\Translator;
|
||||
* @package Thelia\Form
|
||||
* @author Manuel Raynaud <mraynaud@openstudio.fr>
|
||||
*/
|
||||
class AddressCreateForm extends BaseForm
|
||||
class AddressCreateForm extends FirewallForm
|
||||
{
|
||||
|
||||
/**
|
||||
|
||||
96
core/lib/Thelia/Form/FirewallForm.php
Normal file
96
core/lib/Thelia/Form/FirewallForm.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
namespace Thelia\Form;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Model\FormFirewall;
|
||||
use Thelia\Model\FormFirewallQuery;
|
||||
|
||||
/**
|
||||
* Class FirewallForm
|
||||
* @package Thelia\Form
|
||||
* @author Benjamin Perche <bperche@openstudio.fr>
|
||||
*/
|
||||
abstract class FirewallForm extends BaseForm
|
||||
{
|
||||
/** @var \Thelia\Model\FormFirewall */
|
||||
protected static $cachedInstance;
|
||||
|
||||
public function __construct(Request $request, $type = "form", $data = array(), $options = array())
|
||||
{
|
||||
parent::__construct($request, $type, $data, $options);
|
||||
|
||||
static::$cachedInstance = FormFirewallQuery::create()
|
||||
->filterByFormName($this->getName())
|
||||
->filterByIpAddress($this->request->getClientIp())
|
||||
->findOne()
|
||||
;
|
||||
}
|
||||
|
||||
public function isFirewallOk()
|
||||
{
|
||||
if (null !== $firewallRow = &static::$cachedInstance) {
|
||||
/** @var \DateTime $lastRequestDateTime */
|
||||
$lastRequestDateTime = $firewallRow->getUpdatedAt();
|
||||
|
||||
$lastRequestTimestamp = $lastRequestDateTime->getTimestamp();
|
||||
|
||||
/**
|
||||
* Get the last request execution time in hour.
|
||||
*/
|
||||
$lastRequest = (time() - $lastRequestTimestamp) / 3600;
|
||||
|
||||
if ($lastRequest > $this->getConfigTime()) {
|
||||
$firewallRow->resetAttempts();
|
||||
}
|
||||
|
||||
if ($firewallRow->getAttempts() <= $this->getConfigAttempts()) {
|
||||
$firewallRow->incrementAttempts();
|
||||
} else {
|
||||
/** Set updated_at at NOW() */
|
||||
$firewallRow->save();
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$firewallRow = (new FormFirewall())
|
||||
->setIpAddress($this->request->getClientIp())
|
||||
->setFormName($this->getName())
|
||||
;
|
||||
$firewallRow->save();
|
||||
|
||||
static::$cachedInstance = $firewallRow;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*
|
||||
* The time (in hours) to wait if the attempts have been exceeded
|
||||
*/
|
||||
public function getConfigTime()
|
||||
{
|
||||
return ConfigQuery::read("form_firewall_time_to_wait", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*
|
||||
* The number of allowed attempts
|
||||
*/
|
||||
public function getConfigAttempts()
|
||||
{
|
||||
return ConfigQuery::read("form_firewall_attempts", 2);
|
||||
}
|
||||
}
|
||||
@@ -6,5 +6,21 @@ use Thelia\Model\Base\FormFirewall as BaseFormFirewall;
|
||||
|
||||
class FormFirewall extends BaseFormFirewall
|
||||
{
|
||||
public function resetAttempts()
|
||||
{
|
||||
$this->setAttempts(1)->save();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function incrementAttempts()
|
||||
{
|
||||
$this->setAttempts(
|
||||
$this->getAttempts() + 1
|
||||
);
|
||||
|
||||
$this->save();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,10 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat
|
||||
('front_cart_country_cookie_name','fcccn', 1, 1, NOW(), NOW()),
|
||||
('front_cart_country_cookie_expires','2592000', 1, 1, NOW(), NOW()),
|
||||
('sitemap_ttl','7200', 1, 1, NOW(), NOW()),
|
||||
('feed_ttl','7200', 1, 1, NOW(), NOW());
|
||||
('feed_ttl','7200', 1, 1, NOW(), NOW()),
|
||||
|
||||
('form_firewall_time_to_wait', '1', 1, 1, NOW(), NOW()),
|
||||
('form_firewall_attempts', '3', 1, 1, NOW(), NOW());
|
||||
|
||||
|
||||
INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES
|
||||
|
||||
Reference in New Issue
Block a user