Interlace ESLint
ESLint Interlace
Browser SecurityRules

browser-security/no-postmessage-innerhtml

The rule provides **LLM-optimized error messages** (Compact 2-line format) with actionable security guidance:

🔒 Disallow using innerHTML with postMessage 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

ComponentPurposeExample
Risk StandardsSecurity benchmarksCWE-79 OWASP:A05 CVSS:6.1
Issue DescriptionSpecific vulnerabilityCross-site Scripting (XSS) detected
Severity & ComplianceImpact assessmentMEDIUM [SOC2,PCI-DSS,GDPR,ISO27001]
Fix InstructionActionable remediationFollow the remediation steps below
Technical TruthOfficial referenceOWASP Top 10

Rule Details

This rule prevents using innerHTML, outerHTML, insertAdjacentHTML(), or document.write() with data received from postMessage events. This pattern enables XSS attacks through malicious messages.

Why is this dangerous?

When you use innerHTML with postMessage data:

  1. Any window can send messages to your page
  2. Malicious HTML/scripts are executed when assigned to innerHTML
  3. Attackers can steal data, session tokens, and perform actions as the user

Examples

❌ Incorrect

// Direct innerHTML with event.data
window.addEventListener('message', (event) => {
  element.innerHTML = event.data;
});

// Nested property access
window.addEventListener('message', (event) => {
  container.innerHTML = event.data.content;
});

// outerHTML is equally dangerous
window.addEventListener('message', (event) => {
  widget.outerHTML = event.data.html;
});

// insertAdjacentHTML
window.addEventListener('message', (event) => {
  list.insertAdjacentHTML('beforeend', event.data);
});

// document.write (rare but dangerous)
window.addEventListener('message', (event) => {
  document.write(event.data);
});

✅ Correct

// Use textContent for plain text
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://trusted.com') return;
  element.textContent = event.data;
});

// Sanitize before using innerHTML
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://trusted.com') return;
  const sanitized = DOMPurify.sanitize(event.data);
  element.innerHTML = sanitized;
});

// Use intermediate variable (sanitized)
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://trusted.com') return;
  const safeHtml = DOMPurify.sanitize(event.data.content);
  container.innerHTML = safeHtml;
});

// Use DOM APIs instead
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://trusted.com') return;
  const text = document.createTextNode(event.data);
  element.appendChild(text);
});

Options

{
  "browser-security/no-postmessage-innerhtml": [
    "error",
    {
      "allowInTests": true
    }
  ]
}
OptionTypeDefaultDescription
allowInTestsbooleantrueSkip checking in test files (_.test.ts, _.spec.ts)

When Not To Use It

You may disable this rule if:

  • You're handling postMessage in a sandbox/isolated context
  • You have thorough sanitization that the rule can't detect

However, always sanitize postMessage data before rendering as HTML.

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
window.addEventListener('message', (event) => {
  const html = event.data;
  element.innerHTML = html;
});

Mitigation: Sanitize before any variable assignment.

Separate Handler Function

Why: Handler internals not analyzed.

// ❌ NOT DETECTED - External handler
window.addEventListener('message', handlePostMessage);

Mitigation: Apply rule to handler implementations.

Custom Sanitizer

Why: Non-standard sanitizers may not be recognized.

// ❌ NOT DETECTED - Custom sanitizer
element.innerHTML = mySanitizeFunc(event.data);

Mitigation: Configure trusted sanitizer names.

OWASP Mapping

CategoryID
OWASP Top 10 2021A03:2021 - Injection
CWECWE-79
CVSS8.8 (High)

On this page