sillsdev / sillsdev/TheCombine

[CombineHub, SignalRHub] Guard against malicious acknowledgement

Open
#4,124 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

backend bug frontend lowpriority security
Dominant language
TypeScript
Stars
22
Forks
10
Avg merge
2d 2h
Merged PRs (30d)
9

Description

Follow-up to #4122

Issue raised by coderabbitai:

⚠️ Potential issue | 🟠 Major

AcknowledgeMessage must validate the caller's identity against the intended recipient.

Any client can call AcknowledgeMessage(requestId) and mark a message as acknowledged, even if that message was intended for another user. Since requestId is broadcast via Clients.All, all connected clients know every requestId in the system. This allows a malicious or compromised client to acknowledge another user's messages and suppress retry attempts.

Modify AcknowledgeMessage to accept or infer the intended userId, store requestId → userId mappings in the tracker, and validate against Context.UserIdentifier before marking acknowledgment.

🤖 Prompt for AI Agents
In `@Backend/Helper/CombineHub.cs` around lines 6 - 22, Update AcknowledgeMessage
in CombineHub to validate that the caller is the intended recipient before
marking acknowledgment: change AcknowledgeMessage to either accept a userId
parameter or infer it and ensure IAcknowledgmentTracker (referenced as
_ackTracker) exposes methods to record the mapping and to validate ownership
(e.g., store requestId→userId when sending and add a tracker method like
TryMarkAcknowledged(requestId, userId) or GetOwner(requestId)); inside
AcknowledgeMessage, compare Context.UserIdentifier to the owner userId from the
tracker and only call _ackTracker.MarkAcknowledged(requestId) if they match,
otherwise ignore or log/deny the attempt. Ensure CombineHub uses
Context.UserIdentifier for the check and that the tracker stores the mapping
when you create/send messages so lookup succeeds.

[...] client-side controls are not sufficient for security validation.

Why client-side validation fails:

  • Browser DevTools: Users can open the console and directly call connection.invoke("AcknowledgeMessage", anyRequestId) with any requestId they observe from broadcasts
  • Custom clients: Attackers can write their own SignalR client that bypasses all UI logic
  • Public code: All JavaScript is visible and modifiable

The vulnerability:
Since requestId is broadcast via Clients.All, every connected client knows every active requestId in the system. A malicious client can acknowledge messages intended for other users, causing those messages to be marked as delivered when they weren't.

Security principle:

Never trust the client for security-critical operations

Required fix:
The server must validate Context.UserIdentifier matches the intended recipient before calling _ackTracker.MarkAcknowledged(). This requires:

  1. Store requestId → userId mapping when messages are sent
  2. Validate the caller's identity in AcknowledgeMessage before accepting the acknowledgment

The client-side checks are good for UX (preventing honest mistakes), but provide zero security against deliberate attacks.

Contributor guide

No contributing guide indexed for this repository

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 in Backend/Helper/CombineHub.cs by tracing AcknowledgeMessage and the send path, then inspect IAcknowledgmentTracker. Confirm where request IDs are created and broadcast, and add the required ownership mapping and Context.UserIdentifier check. Done means acknowledgments are accepted only for the intended recipient, while unauthorized attempts are ignored or denied.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.