HarperFast / HarperFast/harper

Commit-retry TOCTOU: authorized writes are not re-authorized when a conflict retry re-runs commit against a changed record

Open
#1,843 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

Split out of [#1842 (Record-scoped write authorization)](https://github.com/HarperFast/harper/pull/1842)'s cross-model review — a pre-existing gap across ALL authorization (single-record and record-scoped alike), not introduced or widened there.

## The gap

`allow*` hooks run before writes are staged, but optimistic-conflict handling re-runs write `commit` callbacks against the then-current entry (`DatabaseTransaction` retry; e.g. `Table.ts` `_writeDelete`'s `commit(txnTime, existingEntry, retry, ...)`). Sequence:

1. User A passes `allowUpdate`/`allowDelete` for a record they own.
2. A concurrent transaction changes the row's ownership to B and commits first.
3. The retry applies A's already-authorized write to B's version — no re-authorization.

Async hooks can't be re-run inside the synchronous commit handlers, so re-checking in place isn't an option.

## Direction (from the review)

Mark authorization-sensitive writes (those staged under an armed `checkPermission`) as non-retryable on conflict: abort, surface a conflict error, and let the outer request re-load and re-authorize. Needs care not to regress throughput for the internal/replication paths that never carry authorization.

Generated by KrAIs (Claude Fable 5) during #1842's review adjudication.

Contributor guide

Open the contributing guide

Research direction

Trace DatabaseTransaction conflict retries and Table.ts _writeDelete, especially the commit path and armed checkPermission state. Verify how authorized writes are marked and how internal or replication writes bypass authorization. Done means authorization-sensitive writes abort on conflict for the outer request to reload and re-authorize, without making unauthorized paths non-retryable.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
authorization, backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.