Mar 5, 2026·5 min read·33 visits
Ghost < 5.105.0 fails to bind One-Time Codes (OTCs) to specific sessions and lacks strict CSRF origin validation. Attackers can exploit this to bypass authentication challenges or hijack administrator accounts via malicious cross-origin requests.
Ghost, a popular open-source publishing platform, contains critical vulnerabilities in its authentication mechanisms affecting versions prior to 5.105.0. The platform failed to cryptographically bind One-Time Codes (OTCs) to the initiating browser session and implemented insufficient Cross-Site Request Forgery (CSRF) protections on sensitive endpoints. These architectural flaws allow attackers to potentially bypass authentication challenges or hijack administrator accounts by leveraging cross-origin requests and reusing valid OTCs across different sessions.
The Ghost content management system (CMS) utilizes One-Time Codes (OTCs) for critical authentication flows, including multi-factor authentication (2FA) and password resets. A security audit revealed that these OTCs were generated statelessly, meaning they were not tied to the specific browser session of the user requesting them. Additionally, the platform's CSRF protection middleware lacked strict validation of request origins.
This combination of flaws creates a high-severity authentication bypass vector. An attacker who can coerce a victim into visiting a malicious site can trigger cross-origin requests against the Ghost admin panel. Because the OTCs are not session-bound, a code generated in the victim's session could theoretically be accepted in an attacker's session if intercepted or if the authentication flow allows for state manipulation. The vulnerability is tracked as GHSA-9m84-wc28-w895 and addresses weaknesses mapped to CWE-352 (Cross-Site Request Forgery) and CWE-613 (Insufficient Session Expiration).
The vulnerability stems from two distinct but compounding implementation errors in ghost/core/core/server/services/auth.
1. Stateless OTC Generation (CWE-613)
Prior to the fix, the generation of One-Time Codes relied exclusively on a global admin_session_secret and the target userId. The Time-based One-Time Password (TOTP) generation logic did not include any session-specific entropy. Consequently, a valid OTC for a specific user was globally valid for that user across any browser or client. This lack of session binding meant that if an attacker could observe or predict an OTC, they could use it in a separate session to authenticate as the victim, bypassing the intended security model where an OTC should only verify the session that requested it.
2. Permissive CSRF Validation (CWE-352)
The cookieCsrfProtection middleware was responsible for verifying that requests to sensitive endpoints originated from trusted domains. However, the implementation was overly permissive. It checked for the presence of a session origin but failed to rigorously compare the HTTP Origin or Referer headers against the server's configured admin_url or site_url. This logic allowed cross-origin requests (such as those initiated via <form> submissions from malicious third-party sites) to reach authentication endpoints without being rejected, facilitating CSRF attacks.
The remediation introduced in commit ec065a774 enforces strict session binding and origin checking. The analysis below highlights the critical changes in the OTP service and CSRF middleware.
OTP Service Binding (otp.js)
The generate and verify functions were updated to accept a context parameter. This context is a session-specific challenge (e.g., req.session.auth_code_challenge), ensuring the generated code is mathematically bound to the user's current session.
// BEFORE: Code depends only on secret and userId
function generate(userId, secret) {
return totp.generate(`${secret}${userId}`);
}
// AFTER: Code depends on secret, userId, AND session context
function generate(userId, secret, context = '') {
// context is a random challenge stored in the session
return totp.generate(`${secret}${userId}${context}`);
}CSRF Middleware Hardening (session-service.js)
The middleware was refactored to explicitly validate the request origin against the configured admin URL. If the Origin header does not strictly match the expected adminOrigin, the request is immediately rejected.
// AFTER: Explicit Origin Check
function cookieCsrfProtection(req, session) {
const origin = getOriginOfRequest(req);
const adminUrl = urlUtils.getAdminUrl() || urlUtils.getSiteUrl();
const adminOrigin = new URL(adminUrl).origin;
// Strict equality check
if (origin !== adminOrigin) {
throw new BadRequestError({
message: `Request made from incorrect origin. Expected '${adminOrigin}' received '${origin}'.`
});
}
// ...
}To exploit these vulnerabilities, an attacker typically requires the victim (a Ghost administrator) to have an active session or to be in the process of authenticating. The attack flow leverages the lack of session binding.
/ghost/api/admin/session/verify or similar authentication endpoints.This vulnerability poses a High risk to Ghost installations. Successful exploitation leads to Account Takeover (ATO) of administrative users. An attacker with administrative access to Ghost can fully compromise the application.
The vulnerability is particularly dangerous because it bypasses the intended security controls of Multi-Factor Authentication (MFA) by decoupling the verification code from the session it was intended for.
| Product | Affected Versions | Fixed Version |
|---|---|---|
Ghost Ghost Foundation | < 5.105.0 | 5.105.0 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | CSRF & Session Fixation |
| CWE ID | CWE-352, CWE-613 |
| Attack Vector | Network (Web) |
| Severity | High |
| Exploit Status | Proof of Concept (Internal) |
| Component | core/server/services/auth |
A critical stored Cross-Site Scripting (XSS) vulnerability was identified in Froxlor server administration software panel before version 2.3.8. Authenticated customers with DNS editor privileges can inject malicious JavaScript into DNS TXT records. Because the application processes these values via a raw formatting callback without context-aware HTML entity encoding, the payload executes in the security context of administrative users who view the affected domain's DNS zones.
An authenticated administrator with privileges to manage admin accounts (such as change_serversettings) can execute arbitrary SQL commands via a second-order SQL injection vulnerability. The flaw resides in Froxlor's administrative API endpoints, specifically during the handling of IP address mapping parameters which are stored as serialized arrays and later interpolated without sanitization into active database queries. This vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.
CVE-2026-54543 is a DNS Resource Record (RR) Injection vulnerability in Froxlor, an open-source server administration control panel. Prior to version 2.3.8, the DomainZones.add API command failed to perform strict sanitization and validation on the user-controlled record (label) and type parameters before serializing them into BIND-compatible zone files. An authenticated customer with DNS zone management permissions can inject control characters, breaking out of the original record context to define unauthorized resource records within managed zones.
CVE-2026-42533 is a critical security vulnerability discovered in NGINX Open Source, NGINX Plus, NGINX Ingress Controller, and related products, referred to as the 'Two-Pass Capture-Clobbering' bug. The flaw is situated within NGINX's internal evaluation engine when handling complex variables, exposing a heap-based buffer overflow and information leak when a configuration chains regular expression-based map directives with numbered capture groups. An unauthenticated remote attacker can exploit this weakness by transmitting crafted HTTP requests to trigger remote code execution or defeat ASLR.
Froxlor prior to version 2.3.8 contains a high-severity architectural flaw where the standalone lib/ajax.php entry point bypasses the centralized request validation in lib/init.php. Unauthenticated remote attackers can leverage Cross-Site Request Forgery (CSRF) to induce authenticated administrators to submit forged requests that modify API key whitelists and expiration dates, potentially yielding persistent, out-of-band administrative control.
An insecure data retrieval flaw in the Froxlor server administration panel API allows authenticated remote attackers to retrieve unredacted bcrypt password hashes and Base32-encoded Time-Based One-Time Password (TOTP) seeds. Affected endpoints include several 'get' and 'listing' handlers for customers, administrators, and FTP accounts. Utilizing these leaked parameters, attackers can crack the password hashes offline and concurrently generate valid second-factor authentication codes to completely bypass access controls.