browser-security/no-websocket-innerhtml
The rule provides **LLM-optimized error messages** (Compact 2-line format) with actionable security guidance:
🔒 Disallow using innerHTML with WebSocket message data
Error Message Format
The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:
⚠️ CWE-79 OWASP:A05 CVSS:6.1 | Cross-site Scripting (XSS) detected | MEDIUM [SOC2,PCI-DSS,GDPR,ISO27001]
Fix: Review and apply the recommended fix | https://owasp.org/Top10/A05_2021/Message Components
| Component | Purpose | Example |
|---|---|---|
| Risk Standards | Security benchmarks | CWE-79 OWASP:A05 CVSS:6.1 |
| Issue Description | Specific vulnerability | Cross-site Scripting (XSS) detected |
| Severity & Compliance | Impact assessment | MEDIUM [SOC2,PCI-DSS,GDPR,ISO27001] |
| Fix Instruction | Actionable remediation | Follow the remediation steps below |
| Technical Truth | Official reference | OWASP Top 10 |
Rule Details
This rule prevents using innerHTML, outerHTML, insertAdjacentHTML(), or document.write() with data received from WebSocket messages. This pattern enables XSS attacks if the WebSocket connection is compromised.
Why is this dangerous?
When you use innerHTML with WebSocket data:
- MITM attacks can inject malicious HTML (especially over ws://)
- Compromised servers can send crafted payloads
- Scripts execute in the context of your application
Examples
❌ Incorrect
// onmessage handler with innerHTML
ws.onmessage = (event) => {
chatBox.innerHTML = event.data;
};
// addEventListener pattern
socket.addEventListener('message', (event) => {
container.innerHTML = event.data.html;
});
// outerHTML
ws.onmessage = (event) => {
widget.outerHTML = event.data;
};
// insertAdjacentHTML
ws.onmessage = (event) => {
messageList.insertAdjacentHTML('beforeend', event.data);
};
// Function expression
websocket.onmessage = function (msg) {
panel.innerHTML = msg.data;
};✅ Correct
// Use textContent for plain text
ws.onmessage = (event) => {
messageEl.textContent = event.data;
};
// Sanitize before using innerHTML
ws.onmessage = (event) => {
const sanitized = DOMPurify.sanitize(event.data);
chatBox.innerHTML = sanitized;
};
// Parse and validate structured data
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (typeof data.message === 'string') {
messageEl.textContent = data.message;
}
};
// Use DOM APIs for safe rendering
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const li = document.createElement('li');
li.textContent = data.text;
messageList.appendChild(li);
};
// Use intermediate sanitized variable
ws.onmessage = (event) => {
const cleanHtml = DOMPurify.sanitize(event.data);
container.innerHTML = cleanHtml;
};Options
{
"browser-security/no-websocket-innerhtml": [
"error",
{
"allowInTests": true
}
]
}| Option | Type | Default | Description |
|---|---|---|---|
allowInTests | boolean | true | Skip checking in test files (_.test.ts, _.spec.ts) |
Detection Patterns
The rule detects:
ws.onmessagehandlers that use innerHTML with event.dataws.addEventListener('message', ...)handlers with innerHTML- Various DOM methods: innerHTML, outerHTML, insertAdjacentHTML, document.write
When Not To Use It
You may disable this rule if:
- You're rendering only non-HTML data (JSON, plain text)
- You have thorough sanitization that the rule can't detect
- The WebSocket connection is to a fully trusted internal service
However, always sanitize WebSocket data before rendering as HTML.
Related Rules
browser-security/require-websocket-wss- Require secure wss:// connectionsbrowser-security/no-innerhtml- General innerHTML prevention
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Event Data Stored in Variable
Why: Data stored in variables not traced.
// ❌ NOT DETECTED - Data stored first
ws.onmessage = (event) => {
const html = event.data;
container.innerHTML = html;
};Mitigation: Always sanitize before any assignment.
Separate Handler Function
Why: Handler internals not analyzed.
// ❌ NOT DETECTED - External handler
ws.onmessage = handleWebSocketMessage;Mitigation: Apply rule to handler implementations.
Custom Sanitizer
Why: Non-standard sanitizers may not be recognized.
// ❌ NOT DETECTED - Custom sanitizer
element.innerHTML = myHtmlCleaner(event.data);Mitigation: Configure trusted sanitizer names.
OWASP Mapping
| Category | ID |
|---|---|
| OWASP Top 10 2021 | A03:2021 - Injection |
| CWE | CWE-79 |
| CVSS | 8.1 (High) |