Skip to main content
Vulnerability Database/CVE-2026-86177

CVE-2026-86177: Pterodactyl Panel Privilege Escalation

CVE-2026-86177 is a privilege escalation flaw in Pterodactyl Panel that lets subusers execute unauthorized console commands through scheduled tasks. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-86177 Overview

CVE-2026-86177 is a missing authorization vulnerability [CWE-862] in Pterodactyl Panel versions before 1.14.1. The panel fails to validate action-specific permissions when subusers create scheduled tasks. A subuser holding only the schedule.update permission can create and immediately trigger scheduled tasks that execute arbitrary game-server console commands, control server power state, or create backups. The flaw bypasses the granular permission model that separates schedule management from console, power, and backup actions. Pterodactyl released version 1.14.1 with commit 913b354 to introduce per-action authorization checks in the StoreTaskRequest handler.

Critical Impact

Authenticated subusers can escalate privileges to run arbitrary console commands and control server lifecycle operations without holding the corresponding action permissions.

Affected Products

  • Pterodactyl Panel versions prior to 1.14.1
  • Pterodactyl Panel v1.14.0 (confirmed vulnerable code paths in StoreTaskRequest.php and RunTaskJob.php)
  • Deployments using subuser role delegation with the schedule.update permission

Discovery Timeline

  • 2026-09-05 - CVE-2026-86177 published to NVD
  • 2026-09-08 - Last updated in NVD database

Technical Details for CVE-2026-86177

Vulnerability Analysis

Pterodactyl Panel exposes a scheduling API that allows server owners and delegated subusers to create recurring tasks. Each task specifies an action (such as command, power, or backup) and a payload. The panel enforces role-based access control through granular permission scopes, including control.console, control.start, control.stop, and backup.create. Task creation, however, only verified the caller's schedule.update permission. The StoreTaskRequest class documented this as intentional, noting: "There are no task specific permissions." This design contradicted the surrounding permission model. A subuser granted schedule.update for legitimate cron adjustments could author a task with action=command and any payload, then trigger it through the schedule endpoint. RunTaskJob dispatched the resulting command directly to the game-server daemon without re-validating the invoker's authorization.

Root Cause

The root cause is missing authorization [CWE-862] in the task-store request pipeline. The permission() method in StoreTaskRequest.php returned only Permission::ACTION_SCHEDULE_UPDATE and did not evaluate whether the caller was allowed to perform the concrete action embedded in the task payload. No secondary authorization gate existed inside RunTaskJob.php before command dispatch.

Attack Vector

An attacker requires an authenticated subuser account with the schedule.update permission on a target server. Using the client API, the attacker creates a schedule, adds a task with action=command and an arbitrary console payload, and then invokes the schedule execution endpoint. The task runs under the server context, granting effective command execution equivalent to a user holding control.console. The same technique works against power and backup actions.

php
// Pterodactyl patch: app/Http/Requests/Api/Client/Servers/Schedules/StoreTaskRequest.php
// Commit 913b354aff43ff04fce95357ed68a675a1dd0fa6 introduces per-action authorization.

namespace Pterodactyl\Http\Requests\Api\Client\Servers\Schedules;

use Pterodactyl\Models\Task;
use Pterodactyl\Models\Server;
use Illuminate\Validation\Rule;
use Pterodactyl\Models\Permission;

class StoreTaskRequest extends ViewScheduleRequest
{
    /**
     * Determine if the user is allowed to create or update a task for this schedule.
     */
    public function permission(): string
    {
        return Permission::ACTION_SCHEDULE_UPDATE;
    }

    public function authorize(): bool
    {
        if (!parent::authorize()) {
            return false;
        }

        $permission = Task::permissionForAction((string) $this->input('action'), $this->input('payload'));
        if (is_null($permission)) {
            return true;
        }
        // Additional per-action permission enforcement follows.
    }
}

Source: Pterodactyl Commit 913b354

Detection Methods for CVE-2026-86177

Indicators of Compromise

  • Newly created schedules containing tasks with action=command authored by subusers who were not previously issuing console commands.
  • Schedule execution timestamps that closely follow schedule creation timestamps, indicating create-then-trigger abuse patterns.
  • Wings daemon logs showing console commands originating from schedule jobs rather than the interactive console endpoint.

Detection Strategies

  • Query Pterodactyl activity logs for server:schedule.create and server:task.create events, then correlate with server:console.command executions initiated by the schedule runner.
  • Alert on subuser accounts that hold schedule.update but not control.console, control.start, control.stop, or backup.create yet produce task execution events for those actions.
  • Compare task action values against the invoking subuser's permission set through an out-of-band audit script until all instances are patched.

Monitoring Recommendations

  • Forward Pterodactyl Panel audit logs and Wings daemon logs to a centralized logging platform for correlation and long-term retention.
  • Monitor the /api/client/servers/{server}/schedules/{schedule}/tasks endpoint for unusual POST volume from non-administrative accounts.
  • Track additions or elevations to subuser permission sets, especially the schedule.update scope on production servers.

How to Mitigate CVE-2026-86177

Immediate Actions Required

  • Upgrade all Pterodactyl Panel instances to version 1.14.1 or later, which contains commit 913b354.
  • Audit existing subuser accounts and revoke schedule.update where it is not operationally required.
  • Review recent schedules and tasks for anomalous action=command, action=power, or action=backup entries created by subusers.

Patch Information

The fix ships in Pterodactyl Panel Release 1.14.1. It adds Task::permissionForAction() and enforces per-action authorization inside StoreTaskRequest::authorize(). See the VulnCheck Advisory for Pterodactyl for the complete vulnerability write-up and the Pterodactyl Panel Repository for release artifacts.

Workarounds

  • Remove the schedule.update permission from all subusers until the panel is upgraded.
  • Restrict subuser assignments to trusted operators and enforce least privilege on all server roles.
  • Place the panel behind an authenticated reverse proxy or IP allowlist to reduce exposure of the client API endpoints.
bash
# Upgrade Pterodactyl Panel to the patched release
cd /var/www/pterodactyl
php artisan down
curl -L https://github.com/pterodactyl/panel/releases/download/v1.14.1/panel.tar.gz | tar -xzv
chmod -R 755 storage/* bootstrap/cache
composer install --no-dev --optimize-autoloader
php artisan migrate --seed --force
php artisan queue:restart
php artisan up

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.