Skip to content

Commit

Permalink
CSRF Protection (#235)
Browse files Browse the repository at this point in the history
* Fix alert class name

* feature: csrf protection

* Cosmetics

* Fix token generate

* Admin Panel: changelogs csrf protection

* news/id route

* Refactor admin newses + add csrf

* Use admin.links instead

* Admin panel: Pages csrf

* Menus: better csrf + add success message on reset colors

* Plugins csrf

* Move definitions

* add info function, same as note($message)

* Update mailer.php

* Fix new page/news links

* clear_cache & maintenance csrf

* Formatting

* Fix news type

* Fix changelog link

* Add new changelog link

* More info to confirm dialog

* This is always true
  • Loading branch information
slawkens authored Nov 11, 2023
1 parent a04fbde commit 790d85a
Show file tree
Hide file tree
Showing 89 changed files with 789 additions and 504 deletions.
8 changes: 7 additions & 1 deletion admin/pages/accounts.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
defined('MYAAC') or die('Direct access not allowed!');

$title = 'Account editor';

csrfProtect();

$admin_base = ADMIN_URL . '?p=accounts';
$use_datatable = true;

Expand Down Expand Up @@ -82,7 +85,7 @@
$account = new OTS_Account();
$account->load($id);

if (isset($account, $_POST['save']) && $account->isLoaded()) {
if (isset($_POST['save']) && $account->isLoaded()) {
$error = false;

$_error = '';
Expand Down Expand Up @@ -289,6 +292,7 @@
<div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?>
<div class="col-12 col-sm-12 col-lg-4">
Expand Down Expand Up @@ -581,6 +585,7 @@ class="form-check-input"/>
<div class="row">
<div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post">
<?php csrf(); ?>
<label for="search">Account Name:</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32">
Expand All @@ -590,6 +595,7 @@ class="form-check-input"/>
</div>
<div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post">
<?php csrf(); ?>
<label for="id">Account ID:</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32">
Expand Down
49 changes: 19 additions & 30 deletions admin/pages/changelog.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,29 @@

defined('MYAAC') or die('Direct access not allowed!');

$title = 'Changelog';

csrfProtect();

if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.';
return;
}

$title = 'Changelog';
$use_datatable = true;
const CL_LIMIT = 600; // maximum changelog body length
?>

<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
<script src="<?php echo BASE_URL; ?>tools/js/jquery.datetimepicker.js"></script>
<?php
$id = $_GET['id'] ?? 0;
require_once LIBS . 'changelog.php';

if(!empty($action))
{
$id = $_REQUEST['id'] ?? null;
$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null;
$create_date = isset($_REQUEST['createdate']) ? (int)strtotime($_REQUEST['createdate'] ): null;
$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null;
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null;
$where = isset($_REQUEST['where']) ? (int)$_REQUEST['where'] : null;
$id = $_POST['id'] ?? null;
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null;
$create_date = isset($_POST['createdate']) ? (int)strtotime($_POST['createdate'] ): null;
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null;
$type = isset($_POST['type']) ? (int)$_POST['type'] : null;
$where = isset($_POST['where']) ? (int)$_POST['where'] : null;

$errors = array();

Expand All @@ -46,12 +45,13 @@
$body = '';
$type = $where = $player_id = $create_date = 0;

success("Added successful.");
success('Added successful.');
}
}
else if($action == 'delete') {
Changelog::delete($id, $errors);
success("Deleted successful.");
if (Changelog::delete($id, $errors)) {
success('Deleted successful.');
}
}
else if($action == 'edit')
{
Expand All @@ -68,13 +68,14 @@
$action = $body = '';
$type = $where = $player_id = $create_date = 0;

success("Updated successful.");
success('Updated successful.');
}
}
}
else if($action == 'hide') {
Changelog::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
if (Changelog::toggleHidden($id, $errors, $status)) {
success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
}
}

if(!empty($errors))
Expand Down Expand Up @@ -113,7 +114,7 @@
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.changelog.form.html.twig', array(
'action' => $action,
'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'new'),
'cl_link_form' => constant('ADMIN_URL').'?p=changelog',
'cl_id' => $id ?? null,
'body' => isset($body) ? escapeHtml($body) : '',
'create_date' => $create_date ?? '',
Expand All @@ -128,15 +129,3 @@
$twig->display('admin.changelog.html.twig', array(
'changelogs' => $changelogs,
));

?>
<script>
$(document).ready(function () {
$('#createdate').datetimepicker({format: "M d Y, H:i:s",});

$('.tb_datatable').DataTable({
"order": [[0, "desc"]],
"columnDefs": [{targets: [1, 2,4,5],orderable: false}]
});
});
</script>
6 changes: 4 additions & 2 deletions admin/pages/dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Dashboard';

if (isset($_GET['clear_cache'])) {
csrfProtect();

if (isset($_POST['clear_cache'])) {
if (clearCache()) {
success('Cache cleared.');
} else {
error('Error while clearing cache.');
}
}

if (isset($_GET['maintenance'])) {
if (isset($_POST['maintenance'])) {
$message = (!empty($_POST['message']) ? $_POST['message'] : null);
$_status = (isset($_POST['status']) && $_POST['status'] == 'true');
$_status = ($_status ? '0' : '1');
Expand Down
2 changes: 2 additions & 0 deletions admin/pages/login.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Login';

csrfProtect();

require PAGES . 'account/login.php';
if ($logged) {
header('Location: ' . (admin() ? ADMIN_URL : BASE_URL));
Expand Down
4 changes: 3 additions & 1 deletion admin/pages/mailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mailer';

csrfProtect();

if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
echo 'Access denied.';
return;
Expand All @@ -20,7 +22,7 @@
return;
}

$mail_to = isset($_REQUEST['mail_to']) ? stripslashes(trim($_REQUEST['mail_to'])) : null;
$mail_to = isset($_POST['mail_to']) ? stripslashes(trim($_POST['mail_to'])) : null;
$mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null;
$mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null;

Expand Down
2 changes: 2 additions & 0 deletions admin/pages/mass_account.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

$title = 'Mass Account Actions';

csrfProtect();

$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = $config['lua']['freePremium'];
Expand Down
2 changes: 2 additions & 0 deletions admin/pages/mass_teleport.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

$title = 'Mass Teleport Actions';

csrfProtect();

function admin_teleport_position($x, $y, $z) {
if (!Player::query()->update([
'posx' => $x, 'posy' => $y, 'posz' => $z
Expand Down
21 changes: 13 additions & 8 deletions admin/pages/menus.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus';

csrfProtect();

if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
echo 'Access denied.';
return;
}

if (isset($_REQUEST['template'])) {
$template = $_REQUEST['template'];
if (isset($_POST['template'])) {
$template = $_POST['template'];

if (isset($_REQUEST['menu'])) {
$post_menu = $_REQUEST['menu'];
$post_menu_link = $_REQUEST['menu_link'];
$post_menu_blank = $_REQUEST['menu_blank'];
$post_menu_color = $_REQUEST['menu_color'];
if (isset($_POST['menu'])) {
$post_menu = $_POST['menu'];
$post_menu_link = $_POST['menu_link'];
$post_menu_blank = $_POST['menu_blank'];
$post_menu_color = $_POST['menu_color'];
if (count($post_menu) != count($post_menu_link)) {
echo 'Menu count is not equal menu links. Something went wrong when sending form.';
return;
Expand Down Expand Up @@ -69,9 +71,10 @@
return;
}

if (isset($_REQUEST['reset_colors'])) {
if (isset($_GET['reset_colors'])) {
if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
success('Colors has been reset.');
}
else {
warning('There is no default color defined, cannot reset colors.');
Expand All @@ -93,6 +96,7 @@
</p>
<?php if (isset($config['menu_default_color'])) {?>
<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-danger">Reset Colors to default</button>
</form>
Expand All @@ -112,6 +116,7 @@
$last_id = array();
?>
<form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-info">Save</button><br/><br/>
<div class="row">
Expand Down
46 changes: 25 additions & 21 deletions admin/pages/modules/templates/web_status.twig
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
<div class="col-12 col-md-6">
<div class="card card-warning card-outline">
<form action="?p=dashboard&maintenance" method="post" class="form-horizontal">
<div class="card-header">
<span class="m-0">Website Status<span class="float-right">
<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success">
<input type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}>
<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label>
</div></span>
</span>
<div class="card-header">
<span class="m-0">Website Status<span class="float-right">
<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success">
<input form="maintenance-form" type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}>
<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label>
</div></span>
</span>
</div>
<div class="card-body p-2">
<div class="col-sm-12">
<label for="message" class="col-form-label">Maintenance Message</label>
<textarea form="maintenance-form" name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea>
<small>(only visible if closed)</small>
</div>
<div class="card-body p-2">
<div class="col-sm-12">
<label for="message" class="col-form-label">Maintenance Message</label>
<textarea name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea>
<small>(only visible if closed)</small>
</div>
</div>
<div class="card-footer">
</div>
<div class="card-footer">
<form id="maintenance-form" method="post" action="?p=dashboard" class="float-left">
{{ csrf() }}
<input type="hidden" name="maintenance" value="1" />
<button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button>
<a href="?p=dashboard&clear_cache" onclick="return confirm('Are you sure?');" class="float-right">
<span class="btn btn-danger"><i class="fas fa-clear"></i>Clear cache</span>
</a>
</div>
</form>
</form>
<form method="post" action="?p=dashboard" class="float-right">
{{ csrf() }}
<input type="hidden" name="clear_cache" value="1" />
<button type="submit" onclick="return confirm('Are you sure that you want to clear cache?');" class="btn btn-danger" title="Clear Cache"><i class="fas fa-clear"></i>Clear cache</button>
</form>
</div>
</div>
</div>

Expand Down
40 changes: 21 additions & 19 deletions admin/pages/news.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
*/
defined('MYAAC') or die('Direct access not allowed!');

require_once LIBS . 'forum.php';
require_once LIBS . 'news.php';

$title = 'News Panel';

csrfProtect();

$use_datatable = true;

require_once LIBS . 'forum.php';
require_once LIBS . 'news.php';

if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.';
return;
Expand All @@ -31,17 +34,17 @@
$name = $p_title = '';
if(!empty($action))
{
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$p_title = isset($_REQUEST['title']) ? $_REQUEST['title'] : null;
$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null;
$comments = isset($_REQUEST['comments']) ? $_REQUEST['comments'] : null;
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null;
$category = isset($_REQUEST['category']) ? (int)$_REQUEST['category'] : null;
$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null;
$article_text = isset($_REQUEST['article_text']) ? $_REQUEST['article_text'] : null;
$article_image = isset($_REQUEST['article_image']) ? $_REQUEST['article_image'] : null;
$forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null;
$errors = array();
$id = $_POST['id'] ?? null;
$p_title = $_POST['title'] ?? null;
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null;
$comments = $_POST['comments'] ?? null;
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : 1;
$category = isset($_POST['category']) ? (int)$_POST['category'] : null;
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null;
$article_text = $_POST['article_text'] ?? null;
$article_image = $_POST['article_image'] ?? null;
$forum_section = $_POST['forum_section'] ?? null;
$errors = [];

if($action == 'new') {
if(isset($forum_section) && $forum_section != '-1') {
Expand Down Expand Up @@ -88,8 +91,9 @@
}
}
else if($action == 'hide') {
News::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
if (News::toggleHidden($id, $errors, $status)) {
success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
}
}

if(!empty($errors))
Expand All @@ -115,12 +119,10 @@
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.news.form.html.twig', array(
'action' => $action,
'news_link' => getLink(PAGE),
'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'new'),
'news_id' => $id ?? null,
'title' => $p_title ?? '',
'body' => isset($body) ? escapeHtml($body) : '',
'type' => $type ?? null,
'type' => $type,
'player' => isset($player) && $player->isLoaded() ? $player : null,
'player_id' => $player_id ?? null,
'account_players' => $account_players,
Expand Down
Loading

0 comments on commit 790d85a

Please sign in to comment.