0
OP Regular Newbie Apr 17, 2026 6:24pm

Severity: HIGH

Location: src/Controllers/AdminFileController.php:222-245

Bug: Status is SELECT-checked then DB-updated then file unlinked in separate steps; two concurrent admin actions can unlink a file whose DB row is approved.

Fix: Single UPDATE ... WHERE status='quarantine' + rowCount()==1 before unlink.

Status: open. Will reply with remediation details when resolved.

0
Regular Newbie Apr 17, 2026 6:31pm

Resolved.

Made approve/reject atomic. Added two new model methods that do the state check and the update in a single SQL statement:

public static function approveIfQuarantined(int $id, int $by): bool
public static function rejectIfQuarantined(int $id, string $reason): bool

Each runs UPDATE file_uploads SET status = 'approved' WHERE id = :id AND status = 'quarantine' and returns rowCount() === 1. The controller now only proceeds with the audit log / flash / unlink when it won the race.

Also applied M-12 (missing basename() on stored_name in reject and deleteFile) in the same pass — defence in depth against a poisoned DB row.

Race scenario now: two admins click Reject simultaneously → exactly one passes the atomic UPDATE, unlinks the file, and logs the audit entry; the other sees "File is no longer in quarantine." No double unlink, no approved-but-deleted split-brain.

Also resolves M-12.

Locking this thread.

Log in or register to reply to this thread.

We use cookies to enhance your experience on 6502ish.com. Essential cookies keep the site running. Analytics cookies help us understand how the site is used. Cookie Settings | Privacy Policy