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\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Services\SuperAdminService;
|
||||
use Framadate\Utils;
|
||||
|
||||
@ -39,18 +40,19 @@ $logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||
$superAdminService = new SuperAdminService($connect);
|
||||
$securityService = new SecurityService();
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
if (!empty($_POST['delete_poll'])) {
|
||||
$delete_id = filter_input(INPUT_POST, 'delete_poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-z0-9]+$/']]);
|
||||
if (!empty($_POST['delete_poll']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||
$delete_id = filter_input(INPUT_POST, 'delete_poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$poll_to_delete = $pollService->findById($delete_id);
|
||||
}
|
||||
|
||||
// Traitement de la confirmation de suppression
|
||||
if (!empty($_POST['delete_confirm'])) {
|
||||
$poll_id = filter_input(INPUT_POST, 'delete_confirm', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-z0-9]+$/']]);
|
||||
if (!empty($_POST['delete_confirm']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||
$poll_id = filter_input(INPUT_POST, 'delete_confirm', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$adminPollService->deleteEntirePoll($poll_id);
|
||||
}
|
||||
|
||||
@ -60,5 +62,6 @@ $polls = $superAdminService->findAllPolls();
|
||||
$smarty->assign('polls', $polls);
|
||||
$smarty->assign('poll_to_delete', $poll_to_delete);
|
||||
$smarty->assign('log_file', is_readable('../' . LOG_FILE) ? LOG_FILE : null);
|
||||
$smarty->assign('crsf', $securityService->getToken('admin'));
|
||||
|
||||
$smarty->display('admin/polls.tpl');
|
||||
|
@ -3,18 +3,32 @@ namespace Framadate\Security;
|
||||
|
||||
class Token {
|
||||
|
||||
private $tokan_name;
|
||||
private $time;
|
||||
private $value;
|
||||
|
||||
function __construct($tokan_name, $time) {
|
||||
$this->tokan_name = $tokan_name;
|
||||
$this->time = $time;
|
||||
$this->value = $this->generate();
|
||||
function __construct() {
|
||||
$this->time = time() + TOKEN_TIME;
|
||||
$this->value = $this->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() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (!isset($_SESSION['token']) || !isset($_SESSION['token'][$tokan_name])) {
|
||||
$_SESSION['token'][$tokan_name] = new Token($tokan_name, 60*5);
|
||||
if (!isset($_SESSION['tokens'])) {
|
||||
$_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'}
|
||||
<form action="" method="POST">
|
||||
<input type="hidden" name="csrf" value="{$crsf}"/>
|
||||
{if $poll_to_delete}
|
||||
<div class="alert alert-warning text-center">
|
||||
<h3>{_("Confirm removal of the poll ")}"{$poll_to_delete->id}"</h3>
|
||||
|
Loading…
Reference in New Issue
Block a user