Profilfoto: Upload nach Inhalt pruefen, Loeschen nur per POST

- Slim::storeCroppedImage() vertraute dem vom Client gemeldeten Typ und
  uebernahm die Endung aus dem Dateinamen; "shell.php" mit Typ image/png
  landete als .php im public-Disk. Jetzt entscheidet
  getimagesizefromstring() ueber die Bytes, die Endung kommt aus dem
  geprueften Typ.
- Foto loeschen war ein GET-Link und liess sich per fremdem <img src>
  ausloesen (CSRF); jetzt POST-Formular mit Token.
- Ohne Konto (users.account_id) bricht Upload/Loeschen mit 404 ab statt
  mit einem Fatal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kevin 2026-09-23 15:42:11 +00:00
parent 22dcc0f972
commit e009b11259
5 changed files with 90 additions and 14 deletions

View file

@ -21,6 +21,12 @@ class ProfileImageController extends Controller
{
$user = Auth::user();
// Das Foto haengt am Konto (users.account_id). Ohne Konto gibt es nichts
// zu speichern — sonst liefe der Zugriff darunter in einen Fatal.
if (! $user->account) {
abort(404);
}
if (! Request::get('profile_image_consent')) {
\Session()->flash('alert-danger', __('account.profile_image_consent_required'));
@ -66,7 +72,7 @@ class ProfileImageController extends Controller
{
$user = Auth::user();
if ($user->account->profile_image) {
if ($user->account?->profile_image) {
\Storage::disk('public')->delete('images/profile/'.$user->account->profile_image);
$user->account->profile_image = null;