mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 01:53:03 +02:00
Add admin-only route to open Interdit thesis files from backoffice:
- reliable tab title /favicon wrapper, - Content-Disposition filename, - admin media route hardened to thesis-file prefixes only (defense-in-depth)
This commit is contained in:
@@ -175,6 +175,43 @@ Files are never served directly from disk. All access goes through `MediaControl
|
||||
- Visibility gate: `access_type_id = 3` (Interdit) → HTTP 403
|
||||
- MIME allow-list check before serving
|
||||
|
||||
### Opening “Interdit” files from the backoffice
|
||||
|
||||
Publicly, an Interdit file's `/media?path=…` returns 403. The admin can still open
|
||||
one via a **dedicated admin-only route**: `/admin/media.php?path=…`.
|
||||
|
||||
- It is gated by `AdminAuth::requireLogin()` — served under `/admin` so the
|
||||
administrator's session cookie (scoped to `/admin`) is sent.
|
||||
- It calls `MediaController::handle(adminBypass: true)`, which lifts **only** the
|
||||
Interdit visibility gate. Path whitelist, `realpath()` jail and the MIME
|
||||
allow-list are still enforced — an admin cannot read arbitrary server files.
|
||||
- **Defence-in-depth:** on the admin route the requested `path` is additionally
|
||||
restricted to the five thesis-file prefixes (`tfe/`, `these/`, `frart/`,
|
||||
`documents/`, `theses/`) via `MediaController::isThesisFilePath()`. Any other
|
||||
storage path (`schema.sql`, `xamxam.db`, `tmp/`, `backups/`, `cache/`, …) is
|
||||
rejected with 403 before it even reaches the MIME check.
|
||||
- The backoffice recap page (`recapitulatif.php`) already emits the admin URL
|
||||
for files whose owning thesis is `access_type_id = 3`.
|
||||
|
||||
### Reliable tab title for opened files
|
||||
|
||||
The recap opens an Interdit file via `/admin/media-viewer.php?path=…`, a small
|
||||
HTML wrapper that sets a proper `<title>` (the original uploaded file name) and
|
||||
embeds the file through `/admin/media.php?path=…` in a full-viewport iframe.
|
||||
This gives a useful, consistent tab title across every file type. (Serving the
|
||||
raw PDF directly shows the URL, `media.php`, instead of the file name, because
|
||||
most PDFs carry no embedded `/Title` metadata that Chrome/Firefox's viewer
|
||||
would otherwise use.) The wrapper also re-declares the site's favicon
|
||||
(`/assets/favicon/…`) so the tab keeps the site icon even though it's a
|
||||
standalone page.
|
||||
|
||||
Every served file (admin route and public `/media`) sets `Content-Disposition`
|
||||
to `inline` together with the original uploaded filename (`thesis_files.file_name`),
|
||||
so the browser shows a meaningful tab title (e.g. `rapport_2024.pdf`) instead of
|
||||
`media.php`. The name is emitted safely as an ASCII `filename` fallback plus a
|
||||
UTF-8 `filename*=UTF-8''…` form for accented / international names (RFC 6266),
|
||||
with control chars / quotes / backslashes stripped to prevent header injection.
|
||||
|
||||
---
|
||||
|
||||
## Security notes
|
||||
|
||||
Reference in New Issue
Block a user