Skip to content

Non-administrative users can list basic details about all servers on the Panel using Client API

Moderate
DaneEveritt published GHSA-6888-7f3w-92jx Jul 26, 2020

Package

app/Http/Controllers/Api/Client/ClientController.php

Affected versions

> 0.7.14

Patched versions

0.7.18

Description

Note: This bug impacts all users running Pterodactyl 0.7.15, 0.7.16, and 0.7.17. All other previous versions of the Panel are unaffected. This bug also impacts beta builds 1.0.0-beta.1 through 1.0.0-beta.6. However, the beta builds are not meant for production usage they are specifically being left out of this security advisory.

Impact

The Client API allows a user to list all of the servers that exist on their account, including those servers which they have access to because they are marked as a subuser of that server.

In version 0.7.15 the ability to have more granular control over what was returned was added. This made it possible to filter to return only servers a user could see because they were an administrator on the system, or only servers they could see because they were the owner of the server.

However, an unchecked code pathway would allow a user who was not an administrator to also list all servers on the system by modifying the filters they were passing. As a result, a malicious user could list all of the servers that exist on the Panel. The API response is fixed, meaning that no additional data can be returned other than the data already being returned by it. This is different than other endpoints we expose that allow users to request additional output be appended (such as allocations, nodes, user information, etc.).

As a result, the following information can be obtained for all servers:

  • UUID
  • Resource Limits (Memory, Disk, CPU, etc.) (usage cannot be obtained)
  • Whether or not the user making the call is the server owner (but not the actual identifier of the owner)
  • Server name & description
  • Limits on databases and allocations

A malicious user cannot obtain any information about the server's node, owner, or allocations. A user must be authenticated with the API in order to use this endpoint.

Patches

This bug has been addressed in 0.7.18. You may also manually apply the patch listed below in the Workarounds section.

CVSS Calculations

CVSS Base Score: 4.3
Impact Subscore: 1.4

Exploitability Subscore: 2.8
CVSS Temporal Score: 4.1
CVSS Environmental Score: 3.5
Modified Impact Subscore: 0.7

Overall CVSS Score: 3.5

Workarounds

You can manually apply the following git patch in order to address this vulnerability in systems with complex modifications where upgrading directly may not be feasible.

From 6d69f6ef479d076afd7e996f22939a675f393c8c Mon Sep 17 00:00:00 2001
From: Dane Everitt <dane@daneeveritt.com>
Date: Sun, 26 Jul 2020 11:40:48 -0700
Subject: [PATCH 1/1] Address security vulnerability when listing servers as a
 client

---
 .../Eloquent/ServerRepository.php             | 25 +++++++++++--------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php
index 820093cf..4612d86e 100644
--- a/app/Repositories/Eloquent/ServerRepository.php
+++ b/app/Repositories/Eloquent/ServerRepository.php
@@ -225,18 +225,23 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt
             $instance->where('owner_id', $user->id);
         }

-        // If set to all, display all servers they can access, including
-        // those they access as an admin. If set to subuser, only return
-        // the servers they can access because they are owner, or marked
-        // as a subuser of the server.
-        elseif (($level === User::FILTER_LEVEL_ALL && ! $user->root_admin) || $level === User::FILTER_LEVEL_SUBUSER) {
-            $instance->whereIn('id', $this->getUserAccessServers($user->id));
+        // Only allow these two filters if the user is an administrator.
+        elseif ($user->root_admin && in_array($level, [ User::FILTER_LEVEL_ALL, User::FILTER_LEVEL_ADMIN ])) {
+            // We specifically only match admin in here. If they request all servers and are a root admin
+            // we just won't append any filters to the builder and thus they'll be able to see everything
+            // since this will skip over that final else block.
+            if ($level === User::FILTER_LEVEL_ADMIN) {
+                $instance->whereNotIn('id', $this->getUserAccessServers($user->id));
+            }
         }

-        // If set to admin, only display the servers a user can access
-        // as an administrator (leaves out owned and subuser of).
-        elseif ($level === User::FILTER_LEVEL_ADMIN && $user->root_admin) {
-            $instance->whereNotIn('id', $this->getUserAccessServers($user->id));
+        // If we did not match on the user being an administrator and requesting all/admin only or the user
+        // is not an admin and requested those locked endpoints, just return all of the servers the user actually
+        // has access to.
+        //
+        // @see https://github.com/pterodactyl/panel/security/advisories/GHSA-6888-7f3w-92jx
+        else {
+            $instance->whereIn('id', $this->getUserAccessServers($user->id));
         }

         $instance->search($this->getSearchTerm());
--
2.17.2 (Apple Git-113)

References

The transformer that converts the Server model into an API representation can be found at the following link: https://github.com/pterodactyl/panel/blob/6d69f6ef479d076afd7e996f22939a675f393c8c/app/Transformers/Api/Client/ServerTransformer.php

For more information

If you have any questions or comments about this advisory please reach out via email to dane [ät] pterodactyl.io or Tactical Fish#8008 on Discord.

Severity

Moderate

CVE ID

No known CVE

Weaknesses

No CWEs

Credits