-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
Description:
The Layout_Home_Body admin setting (Administration → Layout → Content → Body) renders HTML via dangerouslySetInnerHTML without sanitization, allowing stored XSS. While CSP blocks execution in default deployments, malicious HTML still reaches the DOM and is exploitable in misconfigured instances or via direct database access.
Affected File: apps/meteor/client/views/home/CustomHomePageContent.tsx (line 8)
Vulnerability Type: Stored Cross-Site Scripting (XSS)
Steps to reproduce:
- Log in as an administrator
- Navigate to
Administration → Layout → Content(or/admin/layout) - Enable "Show custom content to homepage"
- In the Body textarea, paste:
<img src=x onerror="alert('XSS: ' + document.domain)">
- Save the settings
- Navigate to
/homeas any user - Open browser console
Expected behavior:
The onerror attribute should be stripped during sanitization. Only <img src="x"> should render as a broken image with no script execution attempt.
Actual behavior:
The raw HTML is injected into the DOM. The onerror handler is present and attempts to execute.
Browser Console Output:
Refused to execute inline event handler because it violates the following
Content Security Policy directive: "script-src 'self' ..."
The CSP violation proves the malicious attribute reached the DOM. CSP is not a substitute for input sanitization.
Root Cause:
// Current vulnerable code
const body = useSetting('Layout_Home_Body', '');
return <Box withRichContent dangerouslySetInnerHTML={{ __html: body }} {...props} />;No sanitization occurs between database retrieval and DOM insertion.
Proposed Fix:
import DOMPurify from 'dompurify';
const body = useSetting('Layout_Home_Body', '');
const sanitized = DOMPurify.sanitize(body, {
ADD_TAGS: ['iframe'],
ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'src'],
});
return <Box withRichContent dangerouslySetInnerHTML={{ __html: sanitized }} {...props} />;Server Setup Information:
- Version of Rocket.Chat Server: 8.2.0-develop
- License Type: Community
- Number of Users: N/A (development environment)
- Operating System: Windows 11
- Deployment Method: Development (local)
- Number of Running Instances: 1
- DB Replicaset Oplog: Enabled
- NodeJS Version: 22.18.0
- MongoDB Version: 8.0.19
Client Setup Information
- Desktop App or Browser Version: Chrome 132, Firefox 115
- Operating System: Windows 11
Additional context
Security Impact:
- Severity: High (requires admin access, affects all users)
- Attack Vectors: Compromised admin account, direct MongoDB write, malicious insider
- Scope: All users visiting
/homereceive unsanitized HTML - Mitigation:
dompurifyalready exists in project dependencies (packages/gazzodown)
Inconsistency in Codebase:
Other components correctly sanitize similar inputs (e.g., SidebarFooterDefault.tsx:35 uses DOMPurify.sanitize(logo)), indicating this is an oversight.
Relevant logs:
Browser Console (Chrome 132):
Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://cdn.rudderlabs.com https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.
Server Logs:
No server-side errors. The vulnerability is client-side DOM injection.