Adversarial Task-view storm omits mandatory If-Match and expects unconditional success #1272

Open
opened 2026-10-07 00:25:22 +00:00 by kayg · 1 comment
Owner

Evidence from adv31 / #1202

Product head 139d4378e. Round 2's saved Task-view probe creates and reads its owned view, checks foreign reads/writes and hostile IDs, then launches 48 PUT requests without If-Match. It requires every response to be 200. Actual statuses are [428]. The view identity remains stable; cross-User checks reported no leak.

The production update route explicitly requires the read's strong source ETag (#731, DESIGN §2; crates/plugins/notes/src/task_views.rs), and its OpenAPI responses include 428. Keep the established expectation. The owner must approve how to make this older concurrency probe exercise conditional writes and genuine conflicts instead of treating mandatory precondition enforcement as a failure. This is a safe rejection, not lost data or accepted hostile input.

## Evidence from adv31 / #1202 Product head 139d4378e. Round 2's saved Task-view probe creates and reads its owned view, checks foreign reads/writes and hostile IDs, then launches 48 PUT requests without If-Match. It requires every response to be 200. Actual statuses are [428]. The view identity remains stable; cross-User checks reported no leak. The production update route explicitly requires the read's strong source ETag (#731, DESIGN §2; crates/plugins/notes/src/task_views.rs), and its OpenAPI responses include 428. Keep the established expectation. The owner must approve how to make this older concurrency probe exercise conditional writes and genuine conflicts instead of treating mandatory precondition enforcement as a failure. This is a safe rejection, not lost data or accepted hostile input.
Author
Owner

#1202 continuation

The unconditional 200 expectation was stale. The route checks the complete source ETag (#731, DESIGN §2) and returns 428 without If-Match. Commit a6e2ae075 now checks that refusal and sends 48 different replacements against one retained ETag. Exactly one must succeed and 47 must return 412.

A fresh isolated Home passed this real-server check on release product 139d4378e:

server alive at end: True

==== ROUND 2 FINDINGS 0

==== ROUND 2 SLOW 0
python3 tests/adversarial/attack2.py exit=0

The retained large campaign Home timed out at the preceding POST create after the existing 30-second request bound. The conditional burst was not reached in that attempt. Its cause is not isolated; do not count that attempt as passing coverage or infer source loss. The fresh run proves the decided conditional-write contract, not large-Home performance.

# #1202 continuation The unconditional 200 expectation was stale. The route checks the complete source ETag (#731, DESIGN §2) and returns 428 without If-Match. Commit a6e2ae075 now checks that refusal and sends 48 different replacements against one retained ETag. Exactly one must succeed and 47 must return 412. A fresh isolated Home passed this real-server check on release product 139d4378e: ``` server alive at end: True ==== ROUND 2 FINDINGS 0 ==== ROUND 2 SLOW 0 python3 tests/adversarial/attack2.py exit=0 ``` The retained large campaign Home timed out at the preceding POST create after the existing 30-second request bound. The conditional burst was not reached in that attempt. Its cause is not isolated; do not count that attempt as passing coverage or infer source loss. The fresh run proves the decided conditional-write contract, not large-Home performance.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
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-v0#1272
No description provided.