In this lesson, you will learn how to treat incoming SignalR hub data as untrusted input to prevent cross-site scripting (XSS) and resource exhaustion attacks.
When you expose a Hub method, you are effectively providing an entry point that accepts serialized data from the client. An attacker can craft malicious payloads—such as JavaScript snippets meant to execute in another user's browser (XSS) or massive objects designed to overwhelm your server's memory (Resource Exhaustion). Even though SignalR uses a typed hub, the content within those types must be validated with the same rigor as an HTTP POST request.
Mitigating XSS and Data Injection
Never trust data coming from Clients directly. If you broadcast a string received from a client back to other users, you must sanitize it to ensure it contains no executable code. Use a library like HtmlSanitizer to strip dangerous tags before processing or storing the data.
public async Task SendMessage(string user, string message)
{
// Sanitize the input to prevent XSS
var sanitizer = new HtmlSanitizer();
var sanitizedMessage = sanitizer.Sanitize(message);
await Clients.All.SendAsync("ReceiveMessage", user, sanitizedMessage);
}
Preventing Resource Exhaustion
Beyond XSS, attackers can attempt to crash your server by sending extremely large payloads that consume excessive memory during deserialization. You can protect your Hub by implementing strict constraints on input models:
- Use Data Annotations: Apply
[StringLength]and[Required]attributes to your DTOs to enforce boundary limits. - Payload Size Limits: Configure
HttpConnectionDispatcherOptions.MaximumReceiveMessageSizein yourStartup.csto set a global cap on how large a single message can be. - Validate Collections: If your Hub accepts an
IEnumerable, always check theCountproperty immediately to prevent "billion laughs" style amplification attacks where a small JSON payload expands into a massive object graph in memory.
By treating every hub invocation as a potential threat vector, you move from "trusting the pipeline" to "verifying the intent," ensuring that your real-time features remain both performant and secure.
Key Takeaway: Never broadcast or process raw client input without sanitizing for malicious scripts and enforcing strict schema validation to prevent memory-based denial-of-service attacks.