Concurrent bookmark capture can write after client timeout #210

Open
opened 2026-09-26 20:22:21 +00:00 by kayg · 1 comment
Owner

The adversarial probe found a response/write ambiguity in concurrent bookmark creation.

Reproduction from tests/adversarial/attack.py, section 19: send 16 concurrent POST requests to /api/v1/notes/bookmarks, each with a distinct public https://bookmark-storm-N.example/ URL and a 10 second client timeout. During one run on 2026-09-26, the result was 6 HTTP 201 responses and 10 client timeouts (-1 in the probe); only 6 IDs were returned. A later scan of that run's isolated Data directory found 7 matching Note files, so at least one timed-out request completed its write after the client stopped waiting. The server process remained alive.

The host had several other adversarial jobs running at the same time, so this does not isolate a low-load throughput limit. It does show that the client can see a timeout while the server still creates a Note. A caller that retries can create a duplicate. Please check bounded write concurrency and whether this action needs a request id for retry safety.

The adversarial probe found a response/write ambiguity in concurrent bookmark creation. Reproduction from `tests/adversarial/attack.py`, section 19: send 16 concurrent POST requests to `/api/v1/notes/bookmarks`, each with a distinct public `https://bookmark-storm-N.example/` URL and a 10 second client timeout. During one run on 2026-09-26, the result was 6 HTTP 201 responses and 10 client timeouts (`-1` in the probe); only 6 IDs were returned. A later scan of that run's isolated Data directory found 7 matching Note files, so at least one timed-out request completed its write after the client stopped waiting. The server process remained alive. The host had several other adversarial jobs running at the same time, so this does not isolate a low-load throughput limit. It does show that the client can see a timeout while the server still creates a Note. A caller that retries can create a duplicate. Please check bounded write concurrency and whether this action needs a request id for retry safety.
Author
Owner

Follow-up from the #191 final adversarial round on 6bbe93e9157c9efa85905924139581384f46bc9f.

tests/adversarial/attack.py sent 16 parallel POST /api/v1/notes/bookmarks requests with distinct URLs and 10-second timeouts. The statuses were [201, 201, 201, 201, 201, 201, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; the probe received only 6/16 unique IDs. The server was still alive at the end. This run shared the host with other worktree builds and adversarial probes. This is a second reproduction of the response/write ambiguity already tracked here; it does not establish whether the timed-out requests completed writes in this run.

Follow-up from the #191 final adversarial round on `6bbe93e9157c9efa85905924139581384f46bc9f`. `tests/adversarial/attack.py` sent 16 parallel `POST /api/v1/notes/bookmarks` requests with distinct URLs and 10-second timeouts. The statuses were `[201, 201, 201, 201, 201, 201, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]`; the probe received only 6/16 unique IDs. The server was still alive at the end. This run shared the host with other worktree builds and adversarial probes. This is a second reproduction of the response/write ambiguity already tracked here; it does not establish whether the timed-out requests completed writes in this run.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#210
No description provided.