mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-06-28 00:24:23 +00:00
@@ -57,6 +57,7 @@
|
||||
</style>
|
||||
|
||||
<form method="post" action="admin.php" style="margin:0">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input name="action" type="hidden" value="addVillage">
|
||||
<input name="uid" type="hidden" value="<?php echo $user['id'];?>">
|
||||
<table class="punish-box">
|
||||
|
||||
@@ -121,6 +121,7 @@ $banHistory = mysqli_query($database->dblink,"SELECT * FROM ".TB_PREFIX."banlist
|
||||
Add New Ban
|
||||
</h3>
|
||||
<form method="post" class="ban-form">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input type="hidden" name="action" value="addBan">
|
||||
<div class="row">
|
||||
<input type="number" name="uid" placeholder="User ID" required>
|
||||
@@ -174,6 +175,7 @@ $banHistory = mysqli_query($database->dblink,"SELECT * FROM ".TB_PREFIX."banlist
|
||||
Ban IP Address
|
||||
</h3>
|
||||
<form method="post" class="ban-form">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input type="hidden" name="action" value="addIpBan">
|
||||
<div class="row">
|
||||
<input type="text" name="ip" placeholder="IPv4 or IPv6" required>
|
||||
|
||||
@@ -60,6 +60,7 @@ if($maint['started_by'] > 0){
|
||||
<?php if(!empty($error)) echo '<div class="msg">'.$error.'</div>'; ?>
|
||||
|
||||
<form method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
<div class="maint-card">
|
||||
<div class="maint-head">Server Maintenance</div>
|
||||
<div class="maint-status <?= $maint['active'] ? 'on' : 'off' ?>">
|
||||
|
||||
@@ -130,6 +130,7 @@ body{margin:0;background:#f1f5f9;font-family:system-ui,-apple-system,Segoe UI,Ro
|
||||
</div>
|
||||
|
||||
<form id="show" action="admin.php?p=map" method="POST" class="map-filters">
|
||||
<?php echo csrf_field(); ?>
|
||||
<div class="filter-group">
|
||||
<input id="show1" name="show1" type="checkbox" <?php echo $check1;?> value="1">
|
||||
<label for="show1">Players</label>
|
||||
|
||||
@@ -69,7 +69,7 @@ function village_type_by_fieldtype_id($id){
|
||||
|
||||
function gen_map_tiles_select_list_form($is_ocuppied,$is_oasis,$oasis_type,$fieldtype,$x,$y){
|
||||
$not_ocuppied =!$is_ocuppied;
|
||||
$html = '<div class="tile-edit"><b>New Map Tile Type</b><form method="post" action="?p=map_tile&do_save"><select name="new_field_type" class="tile-select">';
|
||||
$html = '<div class="tile-edit"><b>New Map Tile Type</b><form method="post" action="?p=map_tile&do_save">' . csrf_field() . '<select name="new_field_type" class="tile-select">';
|
||||
if($is_oasis){
|
||||
for($i=1;$i<13;$i++){ $sel=($i==$oasis_type)?' selected':''; $html.='<option value="'.$i.'_0"'.$sel.'>['.$i.'] Oasis '.oasis_type_by_id($i).'</option>'; }
|
||||
if($not_ocuppied){ for($i=1;$i<13;$i++){ $html.='<option value="'.$i.'_1">['.$i.'] Valley '.village_type_by_fieldtype_id($i).'</option>'; } }
|
||||
@@ -158,6 +158,7 @@ elseif(isset($_GET['do_get']) && isset($_POST['x'])){
|
||||
|
||||
<div class="tile-wrapper">
|
||||
<form class="tile-form" method="post" action="?p=map_tile&do_get">
|
||||
<?php echo csrf_field(); ?>
|
||||
<div class="coord-wrap">
|
||||
<div class="coord-item">
|
||||
<b>X</b>
|
||||
|
||||
@@ -57,6 +57,7 @@ $deletedArtifacts = $database->getDeletedArtifacts();
|
||||
<h2>🏰 WW Villages</h2>
|
||||
<div class="body">
|
||||
<form method="post" action="../Admin/admin.php?action=addWWVillages">
|
||||
<?php echo csrf_field(); ?>
|
||||
<table class="nat-table">
|
||||
<tr><th>Number</th><th>Player ID</th><th></th></tr>
|
||||
<tr>
|
||||
@@ -74,6 +75,7 @@ $deletedArtifacts = $database->getDeletedArtifacts();
|
||||
<h2>✨ Add Artifacts</h2>
|
||||
<div class="body">
|
||||
<form method="post" action="../Admin/admin.php?action=addArtifacts">
|
||||
<?php echo csrf_field(); ?>
|
||||
<table class="nat-table">
|
||||
<tr><th>Icon</th><th>Type</th><th>Qty</th><th>Player</th><th></th></tr>
|
||||
<tr>
|
||||
|
||||
@@ -57,6 +57,7 @@ $active = $admin->getUserActive();
|
||||
<tbody>
|
||||
<tr><td>
|
||||
<form method="post" action="admin.php" style="margin:0">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input type="hidden" name="action" value="punish">
|
||||
<input type="hidden" name="uid" value="<?php echo $user['id'];?>">
|
||||
<input type="hidden" name="admid" value="<?php echo $_SESSION['id']; ?>">
|
||||
@@ -80,6 +81,7 @@ $active = $admin->getUserActive();
|
||||
|
||||
<tr><td>
|
||||
<form method="post" action="admin.php" style="margin:0">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input type="hidden" name="action" value="punish">
|
||||
<input type="hidden" name="uid" value="<?php echo $user['id'];?>">
|
||||
<input type="hidden" name="admid" value="<?php echo $_SESSION['id']; ?>">
|
||||
@@ -92,6 +94,7 @@ $active = $admin->getUserActive();
|
||||
|
||||
<tr><td>
|
||||
<form method="post" action="admin.php" style="margin:0">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input type="hidden" name="action" value="punish">
|
||||
<input type="hidden" name="uid" value="<?php echo $user['id'];?>">
|
||||
<input type="hidden" name="admid" value="<?php echo $_SESSION['id']; ?>">
|
||||
|
||||
@@ -62,6 +62,7 @@ $search = stripslashes($_POST['s']?? '');
|
||||
|
||||
<div class="search-card">
|
||||
<form action="" method="post" class="search-form" id="searchForm">
|
||||
<?php echo csrf_field(); ?>
|
||||
<select name="p" id="searchType">
|
||||
<?php foreach($types as $k=>$v){?>
|
||||
<option value="<?php echo $k;?>" <?php echo $current==$k?'selected':'';?>><?php echo $v[1].' '.$v[0];?></option>
|
||||
|
||||
@@ -43,6 +43,7 @@ foreach($varray as $vil) $totalpop += $vil['pop'];
|
||||
</style>
|
||||
|
||||
<form action="" method="post">
|
||||
<?php echo csrf_field(); ?>
|
||||
<table id="member" class="search-modern">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
+6
-42
@@ -30,12 +30,10 @@ if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// ─── CSRF TOKEN ───────────────────────────────────────────────────────────────
|
||||
// Generat o singură dată per sesiune și stocat în $_SESSION.
|
||||
// Toate request-urile POST trebuie să trimită acest token în câmpul _csrf_token.
|
||||
if (empty($_SESSION['_csrf_token'])) {
|
||||
$_SESSION['_csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
// ─── CSRF PROTECTION ──────────────────────────────────────────────────────────
|
||||
// Token init + csrf_token()/csrf_field()/csrf_verify() helpers, shared with the
|
||||
// admin Mods (which are POSTed to directly). See GameEngine/Admin/csrf.php.
|
||||
include_once("../GameEngine/Admin/csrf.php");
|
||||
|
||||
// ─── CORE INCLUDES ───────────────────────────────────────────────────────────
|
||||
include_once("../GameEngine/config.php");
|
||||
@@ -97,42 +95,8 @@ function admin_validated_page(string $raw): string
|
||||
return in_array($raw, $whitelist, true) ? $raw : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returnează token-ul CSRF curent ca string hex.
|
||||
* Folosit pentru injectare în câmpuri ascunse sau header-e AJAX.
|
||||
*/
|
||||
function csrf_token(): string
|
||||
{
|
||||
return $_SESSION['_csrf_token'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Emite un <input type="hidden"> gata de pus în orice <form> POST din template-uri.
|
||||
* Exemplu de utilizare în .tpl: <?php echo csrf_field(); ?>
|
||||
*/
|
||||
function csrf_field(): string
|
||||
{
|
||||
return '<input type="hidden" name="_csrf_token" value="' . htmlspecialchars(csrf_token(), ENT_QUOTES, 'UTF-8') . '">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifică token-ul CSRF dintr-un request POST.
|
||||
* Oprește execuția cu HTTP 403 dacă token-ul lipsește sau nu se potrivește.
|
||||
* Apelată automat pe orice $_POST — nu trebuie apelată manual în template-uri.
|
||||
*
|
||||
* Folosim hash_equals() în loc de === pentru a preveni timing attacks.
|
||||
*/
|
||||
function csrf_verify(): void
|
||||
{
|
||||
$submitted = isset($_POST['_csrf_token']) ? (string)$_POST['_csrf_token'] : '';
|
||||
$stored = csrf_token();
|
||||
|
||||
if ($stored === '' || !hash_equals($stored, $submitted)) {
|
||||
http_response_code(403);
|
||||
// Mesaj generic — nu dezvăluie detalii despre mecanism
|
||||
die('<h1>403 Forbidden</h1><p>Invalid or missing security token. Please go back and try again.</p>');
|
||||
}
|
||||
}
|
||||
// CSRF helpers — csrf_token() / csrf_field() / csrf_verify() — are defined in
|
||||
// GameEngine/Admin/csrf.php (included above), shared with the admin Mods.
|
||||
|
||||
/**
|
||||
* Look up a user row by ID using a prepared statement.
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* CSRF protection helpers (issue #139).
|
||||
*
|
||||
* Shared by Admin/admin.php and the admin Mods (GameEngine/Admin/Mods/*.php),
|
||||
* which are POSTed to directly and therefore cannot rely on admin.php's
|
||||
* formerly-inline helpers. Include this file after the session is started:
|
||||
*
|
||||
* - csrf_token(): current per-session token (hex string)
|
||||
* - csrf_field(): hidden <input> to drop into any POST <form>
|
||||
* - csrf_verify(): abort with HTTP 403 if the POSTed token is missing/invalid
|
||||
*/
|
||||
|
||||
// Defensive: callers normally start the session themselves, but make sure we
|
||||
// have one to store the token in.
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Generate the token once per session.
|
||||
if (empty($_SESSION['_csrf_token'])) {
|
||||
$_SESSION['_csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
if (!function_exists('csrf_token')) {
|
||||
/**
|
||||
* Return the current CSRF token as a hex string.
|
||||
*/
|
||||
function csrf_token(): string
|
||||
{
|
||||
return $_SESSION['_csrf_token'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a ready-to-use hidden <input> for any POST <form> in a template.
|
||||
* Usage in a .tpl: <?php echo csrf_field(); ?>
|
||||
*/
|
||||
function csrf_field(): string
|
||||
{
|
||||
return '<input type="hidden" name="_csrf_token" value="' . htmlspecialchars(csrf_token(), ENT_QUOTES, 'UTF-8') . '">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the CSRF token of a POST request.
|
||||
* Stops execution with HTTP 403 if the token is missing or does not match.
|
||||
* Uses hash_equals() instead of === to prevent timing attacks.
|
||||
*/
|
||||
function csrf_verify(): void
|
||||
{
|
||||
$submitted = isset($_POST['_csrf_token']) ? (string)$_POST['_csrf_token'] : '';
|
||||
$stored = csrf_token();
|
||||
|
||||
if ($stored === '' || !hash_equals($stored, $submitted)) {
|
||||
http_response_code(403);
|
||||
// Generic message — does not reveal details about the mechanism.
|
||||
die('<h1>403 Forbidden</h1><p>Invalid or missing security token. Please go back and try again.</p>');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user