Use CSRF tokens on admin page
This commit is contained in:
parent
e7ebd55299
commit
1df48988a6
@ -20,6 +20,7 @@
|
|||||||
use Framadate\Services\AdminPollService;
|
use Framadate\Services\AdminPollService;
|
||||||
use Framadate\Services\LogService;
|
use Framadate\Services\LogService;
|
||||||
use Framadate\Services\PollService;
|
use Framadate\Services\PollService;
|
||||||
|
use Framadate\Services\SecurityService;
|
||||||
use Framadate\Services\SuperAdminService;
|
use Framadate\Services\SuperAdminService;
|
||||||
use Framadate\Utils;
|
use Framadate\Utils;
|
||||||
|
|
||||||
@ -39,18 +40,19 @@ $logService = new LogService();
|
|||||||
$pollService = new PollService($connect, $logService);
|
$pollService = new PollService($connect, $logService);
|
||||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||||
$superAdminService = new SuperAdminService($connect);
|
$superAdminService = new SuperAdminService($connect);
|
||||||
|
$securityService = new SecurityService();
|
||||||
|
|
||||||
/* PAGE */
|
/* PAGE */
|
||||||
/* ---- */
|
/* ---- */
|
||||||
|
|
||||||
if (!empty($_POST['delete_poll'])) {
|
if (!empty($_POST['delete_poll']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||||
$delete_id = filter_input(INPUT_POST, 'delete_poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-z0-9]+$/']]);
|
$delete_id = filter_input(INPUT_POST, 'delete_poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||||
$poll_to_delete = $pollService->findById($delete_id);
|
$poll_to_delete = $pollService->findById($delete_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traitement de la confirmation de suppression
|
// Traitement de la confirmation de suppression
|
||||||
if (!empty($_POST['delete_confirm'])) {
|
if (!empty($_POST['delete_confirm']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||||
$poll_id = filter_input(INPUT_POST, 'delete_confirm', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-z0-9]+$/']]);
|
$poll_id = filter_input(INPUT_POST, 'delete_confirm', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||||
$adminPollService->deleteEntirePoll($poll_id);
|
$adminPollService->deleteEntirePoll($poll_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,5 +62,6 @@ $polls = $superAdminService->findAllPolls();
|
|||||||
$smarty->assign('polls', $polls);
|
$smarty->assign('polls', $polls);
|
||||||
$smarty->assign('poll_to_delete', $poll_to_delete);
|
$smarty->assign('poll_to_delete', $poll_to_delete);
|
||||||
$smarty->assign('log_file', is_readable('../' . LOG_FILE) ? LOG_FILE : null);
|
$smarty->assign('log_file', is_readable('../' . LOG_FILE) ? LOG_FILE : null);
|
||||||
|
$smarty->assign('crsf', $securityService->getToken('admin'));
|
||||||
|
|
||||||
$smarty->display('admin/polls.tpl');
|
$smarty->display('admin/polls.tpl');
|
||||||
|
@ -3,18 +3,32 @@ namespace Framadate\Security;
|
|||||||
|
|
||||||
class Token {
|
class Token {
|
||||||
|
|
||||||
private $tokan_name;
|
|
||||||
private $time;
|
private $time;
|
||||||
private $value;
|
private $value;
|
||||||
|
|
||||||
function __construct($tokan_name, $time) {
|
function __construct() {
|
||||||
$this->tokan_name = $tokan_name;
|
$this->time = time() + TOKEN_TIME;
|
||||||
$this->time = $time;
|
|
||||||
$this->value = $this->generate();
|
$this->value = $this->generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generate() {
|
private function generate() {
|
||||||
// TODO
|
return sha1(uniqid(mt_rand(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTime() {
|
||||||
|
return $this->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue() {
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isGone() {
|
||||||
|
return $this->time < time();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function check($value) {
|
||||||
|
return $value === $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,44 @@ class SecurityService {
|
|||||||
function __construct() {
|
function __construct() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a CSRF token by name, or (re)create it.
|
||||||
|
*
|
||||||
|
* It creates a new token if :
|
||||||
|
* <ul>
|
||||||
|
* <li>There no token with the given name in session</li>
|
||||||
|
* <li>The token time is in past</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param $tokan_name string The name of the CSRF token
|
||||||
|
* @return Token The token
|
||||||
|
*/
|
||||||
function getToken($tokan_name) {
|
function getToken($tokan_name) {
|
||||||
if (!isset($_SESSION['token']) || !isset($_SESSION['token'][$tokan_name])) {
|
if (!isset($_SESSION['tokens'])) {
|
||||||
$_SESSION['token'][$tokan_name] = new Token($tokan_name, 60*5);
|
$_SESSION['tokens'] = [];
|
||||||
|
}
|
||||||
|
if (!isset($_SESSION['tokens'][$tokan_name]) || $_SESSION['tokens'][$tokan_name]->isGone()) {
|
||||||
|
$_SESSION['tokens'][$tokan_name] = new Token();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $_SESSION['token'][$tokan_name]->getValue();
|
return $_SESSION['tokens'][$tokan_name]->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given value is corresponding to the token in session.
|
||||||
|
*
|
||||||
|
* @param $tokan_name string Name of the token
|
||||||
|
* @param $csrf string Value to check
|
||||||
|
* @return bool true if the token is well checked
|
||||||
|
*/
|
||||||
|
public function checkCsrf($tokan_name, $csrf) {
|
||||||
|
$checked = $_SESSION['tokens'][$tokan_name]->getValue() === $csrf;
|
||||||
|
|
||||||
|
if($checked) {
|
||||||
|
unset($_SESSION['tokens'][$tokan_name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{block 'admin_main'}
|
{block 'admin_main'}
|
||||||
<form action="" method="POST">
|
<form action="" method="POST">
|
||||||
|
<input type="hidden" name="csrf" value="{$crsf}"/>
|
||||||
{if $poll_to_delete}
|
{if $poll_to_delete}
|
||||||
<div class="alert alert-warning text-center">
|
<div class="alert alert-warning text-center">
|
||||||
<h3>{_("Confirm removal of the poll ")}"{$poll_to_delete->id}"</h3>
|
<h3>{_("Confirm removal of the poll ")}"{$poll_to_delete->id}"</h3>
|
||||||
|
Loading…
Reference in New Issue
Block a user