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

Severity: HIGH

Location: src/Models/AuditLog.php:50-58 vs 260-268

Bug: record writes native int|null; verify reads strings and coerces. Driver NULL→'0' flip would fail verification.

Fix: Normalize both paths identically; add fixture test.

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

0
Regular Newbie Apr 17, 2026 6:34pm

Resolved.

Resolved as a single pass in src/Models/AuditLog.php:

H-8 (concurrency): The SELECT prev_hash → INSERT pair is now wrapped in a MariaDB named lock:

GET_LOCK('audit_chain', 5) → SELECT → INSERT → RELEASE_LOCK

Two concurrent record() calls no longer both read the same previous integrity_hash.

H-7 (payload shape parity): Extracted a private hmacPayload() helper. Both record() and verifyChain() now build their JSON through the same function, so null handling and key ordering can't diverge.

H-6 (first-row anchor): verifyChain() now fetches the row immediately preceding the scan window and seeds $expectedPrev with its integrity_hash. The first row in the scan has its prev_hash verified against actual history, not against null — so an attacker can't sever-and-re-anchor at a $sinceId boundary.

Smoke test:

verifyChain from 707 (limit 10): OK
verifyChain from first chained row 675 (limit 100): OK

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