New Issue Checklist
Issue Description
With allowCustomObjectId: true, a create whose objectId is an operation envelope such as
{"__op":"Delete"} is accepted, and the row that results is unusable in three separate ways.
getType returns nothing for an operation envelope, so validateObject hits
if (!expected) { continue; } and never compares the value against the String type of the
objectId column. The value then reaches the database layer, where the driver generates its own
_id.
The outcome is a _User that:
- is stored under a Mongo-generated
_id such as 6a862fa06e17011e3f5a9c96, which is not a Parse
objectId and is not what the client was told,
- has
_rperm and _wperm of ["[object Object]"], because the owner ACL is keyed by stringifying
the same operation object, so the row is readable and writable by nobody,
- and is echoed back to the client with
"objectId": {"__op":"Delete"}, along with a working
session token for a user that session can never read.
A non-operation value behaves correctly and is refused with 111 INCORRECT_TYPE, so this is
specific to values whose type cannot be inferred.
Steps to reproduce
Start a server with allowCustomObjectId: true, then:
curl -s -X POST http://127.0.0.1:1337/parse/users \
-H 'X-Parse-Application-Id: myAppId' -H 'Content-Type: application/json' \
-d '{"objectId":{"__op":"Delete"},"username":"probe2","password":"pw"}'
Then look at the stored row, with the master key:
curl -s -G http://127.0.0.1:1337/parse/classes/_User \
-H 'X-Parse-Application-Id: myAppId' -H 'X-Parse-Master-Key: myMasterKey' \
--data-urlencode 'where={"username":"probe2"}'
For contrast, "objectId": 123 in the same body is refused as expected.
Actual Outcome
201 {"objectId":{"__op":"Delete"},"createdAt":"...","sessionToken":"r:..."}
and in MongoDB:
_id: "6a862fa06e17011e3f5a9c96"
_rperm: ["[object Object]"]
_wperm: ["[object Object]"]
An anonymous GET /classes/_User does not return the row, and neither does a query by another
authenticated user, so the account exists and is unreachable by everyone except the master key.
With "objectId": 123 instead: 400 {"code":111,...} and no row, which is the expected behaviour.
Expected Outcome
An objectId whose type cannot be inferred should be refused rather than skipped. Either the same
111 INCORRECT_TYPE that every other non-string value produces, or an explicit rejection of
operation envelopes in that position.
At minimum the response should not report an objectId that differs from the stored _id, since a
client cannot address the object it just created.
Environment
Server
- Parse Server version:
9.10.1-alpha.6 (commit ca75b1fe)
- Operating system:
macOS 26.5.2
- Local or remote host:
local
Database
- System (MongoDB or Postgres):
MongoDB
- Database version:
7.0.25
- Local or remote host:
local
Client
- SDK (iOS, Android, JavaScript, PHP, Unity, etc):
none, raw REST over HTTP
- SDK version:
n/a
Logs
No error is logged; the request succeeds.
Found while building a reimplementation and comparing behaviour against a server built at
ca75b1fe. The stored _id and permission columns above were read directly out of MongoDB rather
than inferred.
New Issue Checklist
Issue Description
With
allowCustomObjectId: true, a create whoseobjectIdis an operation envelope such as{"__op":"Delete"}is accepted, and the row that results is unusable in three separate ways.getTypereturns nothing for an operation envelope, sovalidateObjecthitsif (!expected) { continue; }and never compares the value against theStringtype of theobjectIdcolumn. The value then reaches the database layer, where the driver generates its own_id.The outcome is a
_Userthat:_idsuch as6a862fa06e17011e3f5a9c96, which is not a ParseobjectId and is not what the client was told,
_rpermand_wpermof["[object Object]"], because the owner ACL is keyed by stringifyingthe same operation object, so the row is readable and writable by nobody,
"objectId": {"__op":"Delete"}, along with a workingsession token for a user that session can never read.
A non-operation value behaves correctly and is refused with
111 INCORRECT_TYPE, so this isspecific to values whose type cannot be inferred.
Steps to reproduce
Start a server with
allowCustomObjectId: true, then:Then look at the stored row, with the master key:
For contrast,
"objectId": 123in the same body is refused as expected.Actual Outcome
and in MongoDB:
An anonymous
GET /classes/_Userdoes not return the row, and neither does a query by anotherauthenticated user, so the account exists and is unreachable by everyone except the master key.
With
"objectId": 123instead:400 {"code":111,...}and no row, which is the expected behaviour.Expected Outcome
An
objectIdwhose type cannot be inferred should be refused rather than skipped. Either the same111 INCORRECT_TYPEthat every other non-string value produces, or an explicit rejection ofoperation envelopes in that position.
At minimum the response should not report an
objectIdthat differs from the stored_id, since aclient cannot address the object it just created.
Environment
Server
9.10.1-alpha.6(commitca75b1fe)macOS 26.5.2localDatabase
MongoDB7.0.25localClient
none, raw REST over HTTPn/aLogs
No error is logged; the request succeeds.
Found while building a reimplementation and comparing behaviour against a server built at
ca75b1fe. The stored_idand permission columns above were read directly out of MongoDB ratherthan inferred.