RocketChat / RocketChat/Rocket.Chat
Server-side missing input validation: Allows editing soft-deleted messages and sending empty strings via null bytes
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 46.1k
- Forks
- 13.9k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 130
Description
Description:
Two server-side validation issues allow authenticated users to bypass normal client/UI restrictions by interacting directly with the REST API backend (chat.update and chat.sendMessage).
-
Post-Deletion Editing: Users can modify message contents after a message has already been deleted.
-
Empty Message Validation Bypass: The backend accepts control characters like the null byte (\u0000), allowing empty or invisible messages to be saved in room history.
Steps to reproduce:
Authenticate a session and send a message into a room to obtain a valid msgId and roomId.
Delete that message via the UI or API (its server state updates to a soft-delete status type "t": "rm").
Send a direct POST request to /api/v1/chat.update targeting that deleted msgId with new content.
Alternatively, send a POST request to /api/v1/chat.sendMessage with the text value containing only "\u0000".
Expected behavior:
The server should reject modifications to records flagged with a deleted type status ("t": "rm").
The server should strip control characters and sanitize input, rejecting empty payloads with a string validation error.
Actual behavior:
The server returns a 200 OK status for the update request, modifying the deleted record and adding editedAt / editedBy properties to a soft-deleted object.
The server processes the null byte into the markdown parser component array, saving an invisible message in the chat timeline.
Additional context
This was evaluated by the security triage team (Julio Araujo) who confirmed these behaviors should be tracked as standard software validation bugs rather than security vulnerabilities.
Relevant logs:
Snippet from chat.syncMessages showing data alteration on a removed ("t": "rm") message entry:
JSON
{
"_id": "3eQFH7ycuespBONEm",
"rid": "vawYxTfNfZtzA9cvt",
"msg": "",
"ts": "2026-06-03T10:52:25.221Z",
"unread": true,
"_updatedAt": "2026-06-03T10:52:33.453Z",
"editedAt": "2026-06-03T10:52:33.453Z",
"editedBy": {
"_id": "XWvbWyWc9qyhv96hQ",
"username": "g3rrtester"
},
"t": "rm"
}
Snippet showing raw validation pass on the null byte entity:
JSON
{
"_id": "t4TZmyjEKbe92wxVDS",
"rid": "vawYxTfNfZtzA9cvt",
"msg": "\u0000",
"ts": "2026-06-03T11:02:40.513Z",
"t": "rm",
"md": [
{
"type": "PARAGRAPH",
"value": [
{
"type": "PLAIN_TEXT",
"value": "\u0000"
}
]
}
]
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the server-side REST handlers for chat.update and chat.sendMessage, tracing how deleted messages and message text are validated. Done means updates to records with t: "rm" are rejected and control-only or empty message payloads fail validation instead of being stored.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100