Atlassian issued an Advisory on October 4, 2023, for CVE-2023-22515, a critical severity vulnerability affecting Confluence Server and Data Center. According to the advisory, the vulnerability was initially published as a Privilege Escalation vulnerability but was later updated to a Broken Access Control Vulnerability, Atlassian has also rated the vulnerability with 10 CVSS score. On October 5, 2023, the vulnerability was included in “CISA’s Known Exploited Vulnerabilities Catalog”.
Qualys Web Application Scanning released two QIDs, 150725 & 150745, to address CVE-2023-22515.
QID 150725 was released with detection logic that detects the vulnerable version of the Confluence application based on the response to requests sent to the server.
QID 150745 is an intrusive detection that exploits vulnerable servers by sending requests to the vulnerable endpoint. Vulnerable and unpatched servers are flagged when application configuration alteration is confirmed. Subsequently, it verifies the accessibility of Administrator endpoints and finally leverages the same vulnerability to restore the application configuration.
CVE-2023-22515 is an unauthenticated critical severity vulnerability allowing remote attackers to create unauthorized Confluence Administrator accounts and access Confluence instances. Although the vulnerability is categorized as a Broken Access Control, the initial exploitation stage requires Injection which modifies the application’s configuration, granting unrestricted access to Administrator setup endpoints. The vulnerability affects Confluence versions 8.0.0, 8.0.1, 8.0.2, 8.0.3, 8.0.4, 8.1.0, 8.1.1, 8.1.3, 8.1.4, 8.2.0, 8.2.1, 8.2.2, 8.2.3, 8.3.0, 8.3.1, 8.3.2, 8.4.0, 8.4.1, 8.4.2, 8.5.0, 8.5.1 and is fixed in versions 8.3.3, 8.4.3 and 8.5.2 or later.
The Exploitation chain consists of three stages:
The initial request is sent to server-info action with bootstrapStatusProvider.applicationConfig.setupComplete=false as the payload parameter. When we access server-info.action endpoint without authentication returns a simple response with a “success” status message.
GET /server-info.action?bootstrapStatusProvider.applicationConfig.setupComplete=false
The ‘success’ response confirms that the server is operational and doesn’t expose sensitive or detailed information directly through this endpoint.
Analyzing ServerInfoAction code within the com.atlassian.confluence.core.actions package:
package com.atlassian.confluence.core.actions; import com.atlassian.annotations.security.XsrfProtectionExcluded; import com.atlassian.confluence.core.ConfluenceActionSupport; import com.atlassian.confluence.security.access.annotations.PublicAccess; import com.atlassian.xwork.HttpMethod; import com.atlassian.xwork.PermittedMethods; public class ServerInfoAction extends ConfluenceActionSupport { @PermittedMethods({HttpMethod.ANY_METHOD}) @XsrfProtectionExcluded @PublicAccess public String execute() throws Exception { return "success"; } }
The class ServerInfoAction extends the ConfluenceActionSupport class, which likely handles specific functionalities. Within this class, there’s a method named execute(). It’s designed to be invoked using any HTTP method, exempt from XSRF protection, and accessible to the public without requiring authentication. When the execute method is called, it returns the string “success” once the action was executed successfully.
Moving forward, we’ll examine the extended class ConfluenceActionSupport located at com.atlassian.confluence.core:
package com.atlassian.confluence.core; [..SNIP..] public class ConfluenceActionSupport extends ActionSupport implements LocaleProvider, WebInterface, MessageHolderAware { [..SNIP..] public BootstrapStatusProvider getBootstrapStatusProvider() { if (this.bootstrapStatusProvider == null) this.bootstrapStatusProvider = BootstrapStatusProviderImpl.getInstance(); return this.bootstrapStatusProvider; } [..SNIP..]
Inside the Java class ConfluenceActionSupport, we see a public method named getBootstrapStatusProvider returning an object bootstrapStatusProvider. If the bootstrapStatusProvider is null, it initializes by calling BootstrapStatusProviderImpl.getInstance(), where the getInstance() method appears to get an instance of the bootstrap status provider. Once the object bootstrapStatusProvider is created or already exists, the method returns it.
Following that, BootstrapStatusProviderImpl class at com.atlassian.confluence.impl.setup, comprises a public method named getApplicationConfig which returns the ApplicationConfiguration object.
package com.atlassian.confluence.impl.setup; [..SNIP..] public class BootstrapStatusProviderImpl implements BootstrapStatusProvider, BootstrapManagerInternal { private static final Supplier instance = (Supplier)Suppliers.memoize(BootstrapStatusProviderImpl::initialiseBootstrapStatusProvider); [..SNIP..] public ApplicationConfiguration getApplicationConfig() { return this.delegate.getApplicationConfig(); } [..SNIP..] }
Inside the getApplicationConfig method, the method call to this.delegate.getApplicationConfig(); is using delegation where getApplicationConfig() is delegating the task of fetching application configuration on another object referred to as delegate.
ApplicationConfiguration is an interface specifying multiple methods that any class can implement. Whichever class implements this interface will define the behavior of the methods.
public interface ApplicationConfiguration { String getApplicationHome(); void setApplicationHome(String paramString) throws ConfigurationException; boolean isApplicationHomeValid(); void setProperty(Object paramObject1, Object paramObject2); [..SNIP..] void setBuildNumber(String paramString); boolean isSetupComplete(); void setSetupComplete(boolean paramBoolean); // void setConfigurationPersister(ConfigurationPersister paramConfigurationPersister); [..SNIP..] void setConfigurationFileName(String paramString); }
Interestingly, it does have a method named setSetupComplete expecting one parameter of type Boolean.
ApplicationConfig class implements the ApplicationConfiguration interface, and we do find a synchronized method called setSetupComplete:
package com.atlassian.config; [..SNIP..] public class ApplicationConfig implements ApplicationConfiguration { [..SNIP..] public synchronized void setSetupComplete(boolean setupComplete) { this.setupComplete = setupComplete; } [..SNIP..] }
setSetupComplete method accepts a boolean parameter named setupComplete used to set the setup completion status.
The setupComplete variable of the class is assigned a value supplied as the parameter. The purpose of this parameter is to define or update the setup completion status of the Confluence application. The setup process is complete when we pass true as the setupComplete parameter. When we pass false, it indicates that the setup process is incomplete.
Unifying components from classes such as ConfluenceActionSupport, BootstrapStatusProviderImpl, and ApplicationConfig, we can chain method calls, including getBootstrapStatusProvider(), getApplicationConfig(), and setSetupComplete(), which we’ve explored thus far.
By chaining method calls, we efficiently set the setupComplete value to false using getBootstrapStatusProvider().getApplicationConfig().setSetupComplete(false);
Confluence uses the XWork2 framework, which manages actions, interceptors, and parameter binding, among other things. In XWork2, HTTP parameters are used to set properties in action classes, and the framework automatically maps these parameters to setter methods based on naming conventions.
Due to this, we can form an HTTP parameter that enables a series of method invocations.
bootstrapStatusProvider.applicationConfig.setupComplete=false
Using the payload against the server-info.action endpoint would adjust the setupComplete value to false, signifying that the setup process remains incomplete.
After the setupComplete attribute has been updated, the expected behavior would allow us to access the setup/setup administrator.action endpoint and create an Administrator account.
However, when we send a POST request to this endpoint, we receive a 403 Forbidden response status code and a response body containing the following message: ‘Your request could not be processed because a required security token was not present in the request. You may need to re-submit the form or reload the page.’
According to Atlassian’s Enable XSRF protection in your app guide for Confluence:
Scripts that access Confluence remotely may have trouble acquiring or returning a security token or maintaining an HTTP session with the server. To opt out of token checking, include the following HTTP header in the request: X-Atlassian-Token: no-check
Concerning the above guide, including X-Atlassian-Token: no-check in the HTTP Request Headers, we trigger the same request:
That worked! We have now gained unrestricted access to the endpoint, receiving a 200 status for the Configure System Administrator Account – Confluence page. All that’s left is to include the POST request body with the necessary parameters for the Administrator account.
A 302 redirect at the /setup/finishsetup.action endpoint is a sign of a successful request.
In the final step, we proceed with another POST request to the /setup/finishsetup.action endpoint, effectively exiting the setup wizard.
Logging in as Administrator coldfx
When this vulnerability was disclosed, Atlassian Security Advisory mentioned this as a Privilege Escalation Vulnerability. Following that, Qualys WAS had released the following QID:
150725: Atlassian Confluence Server and Data Center Privilege Escalation Vulnerability (CVE-2023-22515)
However, Later Atlassian Security Advisory updated the vulnerability to a Broken Access Control Vulnerability. Thereafter, Qualys WAS has also updated the QID title.
Customers can detect this vulnerability on the target Confluence application using QIDs:
Once the vulnerability is successfully detected, users shall see similar results in the vulnerability scan report for both the QIDs:
Due to the Vulnerability marked as Critical Severity and highlighted as CISA’s Known Exploited Vulnerabilities, organizations using the confluence application are strongly advised to upgrade to version 8.3.3, 8.4.3, 8.5.2, or later releases to remediate CVE-2023-22515 vulnerability.
For more patching and threat detection-related details, please refer to Atlassian Security Advisory.
Atlassian Security Advisory: https://confluence.atlassian.com/security/cve-2023-22515-privilege-escalation-vulnerability-in-confluence-data-center-and-server-1295682276.html
CVE Details: