Skip to content

fix: prevent duplicate IDs on POST /:name#1733

Open
jara505 wants to merge 1 commit intotypicode:mainfrom
jara505:fix/prevent-duplicate-ids-on-create
Open

fix: prevent duplicate IDs on POST /:name#1733
jara505 wants to merge 1 commit intotypicode:mainfrom
jara505:fix/prevent-duplicate-ids-on-create

Conversation

@jara505
Copy link

@jara505 jara505 commented Mar 19, 2026

Fix: Prevent Duplicate ID Injection via POST

Closes #1732

Overview

Resolves a data integrity vulnerability where POST /:name accepted client-supplied id values and did not enforce uniqueness, allowing duplicate IDs to be inserted into collections. This caused ambiguous and potentially destructive behavior in item-level operations such as GET, PATCH, and DELETE.


Problem

As described in #1732, the create() method in src/service.ts constructed items as:

const item = { id: randomId(), ...data }

Because ...data came after id: randomId(), a client-supplied id in the request body would override the generated one. There was no uniqueness check before insertion.

Reproduction

With a collection containing { id: "victim", title: "original" }, sending:

POST /posts
{ "id": "victim", "title": "attacker" }

Results in two records sharing the same ID:

[
  { "id": "victim", "title": "original" },
  { "id": "victim", "title": "attacker" }
]

After that, GET /posts/victim and PATCH /posts/victim operate on the first match only, and DELETE /posts/victim removes one record while leaving the other behind.


Solution

Three changes were implemented:

  1. Strip client-supplied id — Destructure and discard any id from the client payload before creating the item.
  2. Enforce uniqueness — Verify the generated ID doesn't already exist in the collection; regenerate if a collision is detected.
  3. Increase ID entropy — Change randomBytes(2) (65,536 possible values) to randomBytes(8) (~3.4 × 10³⁸ possible values) to eliminate random collisions under high insert volume.

Key Changes

File Description
src/service.ts Modified create() to strip client id and add a uniqueness verification loop before insertion.
src/random-id.ts Increased entropy from 2 to 8 bytes.
src/service.test.ts Added 3 new test cases: client-supplied id rejection, duplicate ID prevention, and normal POST behavior.

Breaking Change

Clients that previously sent id in POST bodies will now have those values ignored. This is consistent with the documented behavior where IDs are auto-generated strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

POST accepts duplicate ids, causing ambiguous GET/PATCH/DELETE behavior

1 participant