Description
The authenticated POST /api/crypto/public-keys endpoint accepts an arbitrary-length user_ids array. It then performs a service-role user lookup and public-key RPC for every element, including duplicate IDs.
A single request containing thousands of IDs therefore causes thousands of sequential privileged database operations. Non-string and oversized IDs are also passed directly into lookup filters.
Reproduction
Send an authenticated request with a large or duplicate-filled array:
{
"user_ids": ["user-one", "user-one", "user-two"]
}
The current loop executes all three lookups instead of normalizing the two unique IDs. There is no upper bound on the array.
Expected
- cap the number of IDs accepted in one request
- reject malformed or non-string IDs with a 400 response
- trim and deduplicate valid IDs before service-role queries
Actual
Every supplied array element triggers lookup work, allowing request-to-database query amplification.
Description
The authenticated
POST /api/crypto/public-keysendpoint accepts an arbitrary-lengthuser_idsarray. It then performs a service-role user lookup and public-key RPC for every element, including duplicate IDs.A single request containing thousands of IDs therefore causes thousands of sequential privileged database operations. Non-string and oversized IDs are also passed directly into lookup filters.
Reproduction
Send an authenticated request with a large or duplicate-filled array:
{ "user_ids": ["user-one", "user-one", "user-two"] }The current loop executes all three lookups instead of normalizing the two unique IDs. There is no upper bound on the array.
Expected
Actual
Every supplied array element triggers lookup work, allowing request-to-database query amplification.