RocketChat / RocketChat/Rocket.Chat

Server-side missing input validation: Allows editing soft-deleted messages and sending empty strings via null bytes

Open
#40,779 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

type: bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.