Forums Bug Reports Thread

Broken access control: reactions can be toggled on photos in private albums / non-existent items

Patrick Bass · Jun 6 · 14 · 1 Locked
[Minor] [Normal Priority] [Bug Fixed] [Always Reproduces]
🚀 OP Jun 6, 2026 6:00pm

Area: Files, photos, gallery, ansi (audit p5) · Surface: POST /photos/item/{id}/reaction (PhotoGalleryController@toggleReaction) · Dimension: security · Severity: minor

OWASP A01:2021 Broken Access Control. An authenticated user who cannot view a private (only_me/friends) album can still attach reaction rows to its photos by guessing the sequential item_id, and can spawn reaction rows against deleted or non-existent item_ids. Lower impact than the comment IDORs (reactions carry no free text) but it is the same missing-authorization pattern and shows up to the owner as interaction on private content.

Evidence

platform/src/Controllers/PhotoGalleryController.php:509-537 — toggleReaction() validates only the reaction `kind` enum, then reads/writes photo_reactions keyed on the raw item_id with no item lookup and no viewableBy check:
```php
public function toggleReaction(string $id): void
{
    $user = $this->requireAuth();
    $this->validateCsrf();
    $kind = (string) ($_POST['kind'] ?? 'like');
    if (!in_array($kind, ['like','love','laugh','wow','sad','angry'], true)) { ... }
    $existing = $this->db->fetchOne('SELECT id, kind FROM photo_reactions WHERE item_id = :i AND user_id = :u', ...);
    ...
    $this->db->execute('INSERT INTO photo_reactions (item_id, user_id, kind) VALUES (:i, :u, :k)', ['i' => (int) $id, ...]);
}
```
No PhotoAlbumItem::findById / PhotoAlbum::viewableBy, unlike tagItem()/reportItem()/listTags() in the same controller.

Suggested fix. Resolve the item + parent album and enforce PhotoAlbum::viewableBy before reading/inserting into photo_reactions, consistent with the other per-item endpoints in this controller.

Filed by the automated tenant-app audit and adversarially evidence-verified. Status: verified. Open — not yet actioned.


Patrick Bass
@mobieus

🚀 Jun 7, 2026 5:38am

Resolved — fixed and deployed. Commit 89b2334003a7, shipped dev-first then to all tenants on 2026-06-06.

toggleReaction() in /home/patrick/mobieus-io/platform/src/Controllers/PhotoGalleryController.php enforces PhotoAlbum::viewableBy after resolving item+parent album (lines ~514-531) before any photo_reactions read/insert, matching addComment/tagItem/reportItem. Hardened the post-gate branches with explicit return statements after each json() call so a gated handler can never fall through to a DB write, and switched the INSERT to the already-cast $itemId.

Status: fixed. Thread closed and locked.


Patrick Bass
@mobieus

Log in or register to reply to this thread.