sillsdev / sillsdev/TheCombine
[CombineHub, SignalRHub] Guard against malicious acknowledgement
Nobody has claimed this yet.
- 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 anyrequestIdthey 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:
- Store
requestId → userIdmapping when messages are sent - Validate the caller's identity in
AcknowledgeMessagebefore 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
- 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 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