Netlify CMS 2.10.192 - Stored Cross-Site Scripting (XSS)

Exploit Author: tmrswrr Analysis Author: www.bubbleslearn.ir Category: WebApps Language: JavaScript Published Date: 2023-07-11
# Exploit Title: Netlify CMS 2.10.192 - Stored Cross-Site Scripting (XSS)
# Exploit Author: tmrswrr
# Vendor Homepage: https://decapcms.org/docs/intro/
# Software Link: https://github.com/decaporg/decap-cms
# Version: 2.10.192
# Tested on: https://cms-demo.netlify.com


Description:

1. Go to new post and write body field your payload:

https://cms-demo.netlify.com/#/collections/posts

Payload = <iframe src=java&Tab;sc&Tab;ript:al&Tab;ert()></iframe>

2. After save it XSS payload will executed and see alert box


Netlify CMS 2.10.192: Stored Cross-Site Scripting (XSS) Vulnerability Exploited

Netlify CMS, a popular open-source content management system (CMS) built for static site generators, has recently been identified as vulnerable to a stored Cross-Site Scripting (XSS) attack in version 2.10.192. This vulnerability allows attackers to inject malicious scripts into content that persistently execute when viewed by other users — a serious security risk in any web application.

Understanding the Vulnerability

Stored XSS occurs when user input is not properly sanitized before being saved to a database or stored on a server. Unlike reflected XSS, where the malicious script is delivered via a URL, stored XSS is embedded directly into content that remains on the site permanently. This makes it particularly dangerous because it can affect all users who access the compromised content.

For Netlify CMS, this vulnerability manifests when a user enters malicious HTML or JavaScript into a content field (such as a blog post body), and the system fails to sanitize the input before rendering it on the frontend.

Exploitation Example

Consider the following exploit demonstrated on the cms-demo.netlify.com public demo site:

<iframe src=java&Tab;sc&Tab;ript:al&Tab;ert()></iframe>

This payload is crafted using encoded characters to bypass basic filtering mechanisms. The java&Tab;sc&Tab;ript sequence is an encoded version of javascript, designed to evade simple string checks. When saved as a post body in Netlify CMS, the script is stored and later rendered in the browser.

Upon rendering, the browser interprets the iframe tag with a src attribute containing a javascript:alert() command, triggering an alert() popup — a classic sign of successful XSS execution.

Why This Matters

While the alert() example is harmless in demonstration, real-world exploitation could involve:

  • Stealing user session cookies via document.cookie access.
  • Redirecting users to phishing sites.
  • Injecting malicious scripts that compromise the entire website.
  • Exploiting the trust users place in CMS-generated content.

Since Netlify CMS is often used to manage content for production websites, this vulnerability poses a significant risk to site integrity and user security.

Technical Root Cause

The vulnerability stems from a lack of proper input sanitization in the Rich Text Editor component. Netlify CMS relies on a third-party library for rich text editing, but fails to enforce strict HTML filtering before storing or rendering content.

Specifically, the system does not:

  • Validate or escape HTML tags like <iframe>, <script>, or <object>.
  • Sanitize attributes such as src for dangerous protocols like javascript:.
  • Implement Content Security Policy (CSP) directives to block inline scripts.

Without these safeguards, user-generated content becomes a vector for persistent malicious code execution.

Security Recommendations

For developers and site administrators using Netlify CMS, immediate mitigation steps are essential:

  • Upgrade to a patched version: Ensure you're running a version newer than 2.10.192. The maintainers have since addressed this issue in later releases.
  • Implement strict content filtering: Use libraries like DOMPurify to sanitize HTML before rendering.
  • Enforce Content Security Policy (CSP): Add a Content-Security-Policy header to block inline scripts and external resources from untrusted domains.
  • Limit user input privileges: Restrict editing permissions to trusted users only.
  • Monitor content changes: Use audit logs to detect suspicious content entries.

Code Fix Example

Here is an improved code snippet using DOMPurify to sanitize content before rendering:

import DOMPurify from 'dompurify';

// Sanitize user input before rendering
const sanitizedContent = DOMPurify.sanitize(userInput, {
  ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'ul', 'li'],
  ALLOWED_ATTR: ['class', 'id'],
  FORBID_ATTR: ['src', 'href', 'onclick', 'onload'],
  FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'form']
});

// Render sanitized content
document.getElementById('content').innerHTML = sanitizedContent;

This code ensures that only safe HTML tags and attributes are allowed, effectively blocking the malicious javascript: protocol and iframe tags. It also prevents the execution of inline scripts and dynamic event handlers.

Conclusion

Netlify CMS 2.10.192’s stored XSS vulnerability underscores the importance of input validation in modern web applications. Even open-source tools used for content management must adhere to rigorous security standards. By adopting proactive measures such as sanitization libraries, CSP policies, and role-based access control, developers can safeguard their platforms against persistent threats.

Security is not a one-time fix — it’s an ongoing process. Always verify the integrity of third-party components, keep software updated, and test for vulnerabilities in real-world scenarios.