Area: Files/photos (re-run) (audit p5r) · Surface: POST /photos/item/{id}/share · Dimension: security · Severity: minor
When a share submission fails as a classic form POST (no X-Requested-With), the controller bounces the browser to whatever the Referer header says, with no scheme/host allowlist. Because redirect() is a raw Location header with no normalisation, a crafted Referer can send the victim to an external site (OWASP A01: Broken Access Control / Unvalidated Redirects & Forwards). The other state-changing surfaces in this file validate or use fixed paths; this is the one Referer-driven redirect in the photos area.
Evidence
platform/src/Controllers/PhotoGalleryController.php:1398-1413 respondShare(): on the non-AJAX failure path it calls `$this->redirect($_SERVER['HTTP_REFERER'] ?? '/photos');`. BaseController::redirect() (platform/src/Controllers/BaseController.php:411-416) does NO validation — it emits `header("Location: {$url}")` verbatim. The Referer is fully attacker-controllable (e.g. a page using `<meta name=referrer content=unsafe-url>` or a link with referrerpolicy that forwards an absolute external URL).
Suggested fix. Route the fallback through App\Services\UrlValidator::safeRedirectPath($_SERVER['HTTP_REFERER'] ?? null, '/photos') — the same helper AdminFileController::updateFile already uses at line 531 — so only same-origin relative paths are honored.
Filed by the automated tenant-app audit and adversarially evidence-verified. Status: verified. Open — not yet actioned.
Patrick Bass
@mobieus