58 lines
2.3 KiB
PHP
58 lines
2.3 KiB
PHP
<?php
|
|
// Guard de autenticación + CSRF para endpoints de admin.
|
|
// Include al inicio de cada endpoint (require_once __DIR__.'/auth_guard.php';)
|
|
|
|
// Los endpoints de admin SIEMPRE responden JSON: nunca emitir HTML de avisos/errores.
|
|
@ini_set('display_errors', '0');
|
|
@ini_set('display_startup_errors', '0');
|
|
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE);
|
|
|
|
// Descartar cualquier salida previa (BOM, espacios, avisos) antes del JSON.
|
|
if (ob_get_level() === 0) { @ob_start(); }
|
|
|
|
require_once dirname(__DIR__) . '/config.php';
|
|
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
session_name($CFG->sessionname);
|
|
session_start();
|
|
}
|
|
|
|
if (empty($_SESSION['usersession']) || empty($_SESSION['isadmin'])) {
|
|
while (ob_get_level() > 0) { @ob_end_clean(); }
|
|
http_response_code(403);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode(array('code' => '403', 'msg' => 'No autorizado'), JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// Cualquier salida accidental (avisos/notices) antes del JSON se descarta aquí.
|
|
while (ob_get_level() > 0) { @ob_end_clean(); }
|
|
ob_start();
|
|
|
|
// Excepciones no controladas (p. ej. mysqli_sql_exception en PHP 8+) deben
|
|
// responder JSON, nunca HTML con stack trace (evita el "Unexpected token '<'").
|
|
set_exception_handler(function ($e) {
|
|
while (ob_get_level() > 0) { @ob_end_clean(); }
|
|
error_log('admin endpoint: ' . $e->getMessage());
|
|
http_response_code(500);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode(array('code' => '500', 'msg' => 'Error interno del servidor', 'error' => $e->getMessage()), JSON_UNESCAPED_UNICODE);
|
|
});
|
|
|
|
if (empty($_SESSION['csrf'])) {
|
|
$_SESSION['csrf'] = bin2hex(random_bytes(32));
|
|
}
|
|
|
|
// Verificación CSRF en métodos que cambian estado
|
|
$metodo = isset($_SERVER['REQUEST_METHOD']) ? strtoupper($_SERVER['REQUEST_METHOD']) : 'GET';
|
|
if ($metodo === 'POST' || $metodo === 'PUT' || $metodo === 'DELETE') {
|
|
$token = isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '';
|
|
if ($token === '' && isset($_POST['csrf'])) { $token = $_POST['csrf']; }
|
|
if (!is_string($token) || !hash_equals($_SESSION['csrf'], $token)) {
|
|
http_response_code(403);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode(array('code' => '403', 'msg' => 'Token CSRF inválido'), JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
}
|