Carry the CSRF token on fetch requests and put mutations behind POST

Unraid already enforces CSRF on every POST via auto_prepend, but its
injector is jQuery-only — the plugin's native fetch() calls carried no
token and were being terminated before the endpoint ran, silently,
because csrf_terminate exits with an empty body that r.json() swallows.
This commit is contained in:
Gmer4Lfe
2026-08-02 10:28:53 -04:00
parent 987313e7dc
commit c34224effa
16 changed files with 198 additions and 67 deletions
+13 -4
View File
@@ -49,8 +49,9 @@
// scripts write; nothing here triggers a scan, cleanup, or import.
//
// REQUEST
// GET cached (300s) full payload
// GET ?action=refresh_remote&host=host<n> re-run the partner cache writer for one host
// GET cached (300s) full payload
// POST action=refresh_remote host=host<n> re-run the partner cache writer for one host
// (POST, so Unraid's CSRF guard applies)
//
// RESPONSE
// normal vv_arrs_all() verbatim — local node live, remote nodes cached with cache_age
@@ -70,9 +71,17 @@ require_once dirname(__DIR__) . '/include/config.php';
define('VV_ARRS_REFRESH_TIMEOUT', 120);
// ── Manual remote refresh — runs remote_arr_cache_writer for one host ─────────
$_action = trim($_GET['action'] ?? '');
// POST only. The refresh executes a script, and Unraid's CSRF prepend validates POSTs while
// ignoring GETs entirely — so reaching this over GET would mean running it with no token
// check. A GET naming the action is refused rather than falling through to the cached read,
// so a stale caller fails visibly instead of silently appearing to succeed.
if (trim($_GET['action'] ?? '') === 'refresh_remote') {
http_response_code(405);
echo json_encode(['ok' => false, 'error' => 'POST only']); exit;
}
$_action = ($_SERVER['REQUEST_METHOD'] === 'POST') ? trim($_POST['action'] ?? '') : '';
if ($_action === 'refresh_remote') {
$host = strtolower(trim($_GET['host'] ?? ''));
$host = strtolower(trim($_POST['host'] ?? ''));
if (!preg_match('/^host\d+$/', $host)) {
echo json_encode(['ok' => false, 'error' => 'Invalid host']); exit;
}