test(authz): bearer-authed admin cannot edit/cover NULL-uploader mangas (0.87.19)
0.87.10 followup from the rereview. The fix lacked a test for the specific axis it changed (admin authority via cookie only). New test mints a bearer for a promoted admin and asserts PATCH/PUT-cover/DELETE- cover all 403 on NULL-uploader rows. Mutation-confirmed. Also: `MultipartBuilder::finalize` now `pub` for bearer-multipart use; `admin_csrf_guard` rustdoc updated to describe the post-0.87.10 cookie-precedence rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1058,9 +1058,17 @@ const ADMIN_PATH_PREFIX: &str = "/api/v1/admin/";
|
||||
/// the configured allowlist. Safe methods (`GET`/`HEAD`/`OPTIONS`) are
|
||||
/// always allowed.
|
||||
///
|
||||
/// **Bearer-token requests** (`Authorization: Bearer …`) are bot API
|
||||
/// callers — they can't be a CSRF vector because the browser never
|
||||
/// attaches that header automatically. Skip the check for them.
|
||||
/// **Bearer-token-only requests** (`Authorization: Bearer …` with NO
|
||||
/// session cookie) are bot API callers — they can't be a CSRF vector
|
||||
/// because the browser never attaches the Authorization header
|
||||
/// automatically. Skip the check for them.
|
||||
///
|
||||
/// **Bearer + cookie (the "cookie-ride")** is treated as cookie-auth.
|
||||
/// An attacker page can mint `Authorization: Bearer junk` on a
|
||||
/// credentialed cross-site POST; the cookie carries the actual
|
||||
/// authority. Closing this hole means cookie precedence: as soon as a
|
||||
/// session cookie is present, the CSRF gate fires regardless of the
|
||||
/// Authorization header. (0.87.10 closed a 0.87.2 regression here.)
|
||||
///
|
||||
/// **Cookie-auth requests** must:
|
||||
/// * be from an allowed origin (`Origin` then `Referer`), AND
|
||||
@@ -1073,7 +1081,11 @@ const ADMIN_PATH_PREFIX: &str = "/api/v1/admin/";
|
||||
/// — this used to silently let everything through, so an operator who
|
||||
/// forgot to set `ADMIN_ALLOWED_ORIGINS` shipped an unguarded admin
|
||||
/// surface. Operators on a pure-bot-token deploy aren't impacted (their
|
||||
/// requests carry `Authorization: Bearer …` and skip the gate above).
|
||||
/// requests carry only `Authorization: Bearer …` with no session cookie
|
||||
/// and skip the gate via the bearer-only branch above).
|
||||
///
|
||||
/// **No auth at all** (no cookie, no bearer): bypass the CSRF gate so
|
||||
/// the auth extractor returns a clean 401 instead of a confusing 403.
|
||||
async fn admin_csrf_guard(
|
||||
State(state): State<AppState>,
|
||||
req: Request,
|
||||
|
||||
Reference in New Issue
Block a user