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
+16 -9
View File
@@ -64,15 +64,22 @@
// Output is appended to a dedicated log with stdin detached, so a backgrounded handler
// cannot hold the request's file descriptors open.
//
// Known gap: this endpoint authenticates nothing.
// master.conf carries WEBHOOK_SECRET, and the standalone Node listener on WEBHOOK_PORT
// validates it — this WebGUI-hosted path does not. Anyone who can reach the URL can
// make it run the handler against any absolute path that passes validation. Injection
// is not the risk (the path is escaped); triggering work is. Left as-is deliberately
// rather than fixed in passing: adding a secret check here would break whichever arr
// instances are currently configured against this URL, and that is a change to make
// with the arr configs open, not as part of a documentation pass. See also the CSRF
// note in README-unraid.md.
// UNREACHABLE — this endpoint cannot currently be called by an arr at all.
// Two platform layers stand in front of it, and an arr satisfies neither. nginx applies
// `auth_request` to everything under /plugins/, so a request without a WebGUI session is
// redirected to the login page. And Unraid's auto_prepend terminates every POST that
// does not carry a valid CSRF token — which an arr has no way to obtain.
//
// The live path is the standalone Node listener, Arrs_Stack/webhook_listener.js, running
// on WEBHOOK_PORT outside nginx entirely and validating WEBHOOK_SECRET itself. That is
// what the arrs are pointed at, and it is why it exists.
//
// This file is therefore dead code kept for reference, not a second live entry point.
// Nothing here authenticates, because nothing here can be reached. Do not "fix" it by
// adding a secret check and re-pointing an arr at it — it would still be blocked by the
// two layers above. If it is ever wanted as a real entry point it needs to be served
// from outside /plugins/, at which point it needs WEBHOOK_SECRET validation first.
// Removing it outright is the other reasonable option. See README-unraid.md.
//
// REQUEST
// POST <arr webhook JSON body>