Pterodactyl /
Panel
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Pterodactyl - Panel |
||
| 4 | * Copyright (c) 2015 - 2017 Dane Everitt <[email protected]>. |
||
| 5 | * |
||
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
||
| 7 | * of this software and associated documentation files (the "Software"), to deal |
||
| 8 | * in the Software without restriction, including without limitation the rights |
||
| 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||
| 10 | * copies of the Software, and to permit persons to whom the Software is |
||
| 11 | * furnished to do so, subject to the following conditions: |
||
| 12 | * |
||
| 13 | * The above copyright notice and this permission notice shall be included in all |
||
| 14 | * copies or substantial portions of the Software. |
||
| 15 | * |
||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||
| 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
| 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||
| 22 | * SOFTWARE. |
||
| 23 | */ |
||
| 24 | |||
| 25 | namespace Pterodactyl\Models; |
||
| 26 | |||
| 27 | use Auth; |
||
| 28 | use Cache; |
||
| 29 | use Carbon; |
||
| 30 | use Schema; |
||
| 31 | use Javascript; |
||
| 32 | use Illuminate\Database\Eloquent\Model; |
||
| 33 | use Illuminate\Notifications\Notifiable; |
||
| 34 | use Nicolaslopezj\Searchable\SearchableTrait; |
||
| 35 | |||
| 36 | class Server extends Model |
||
| 37 | { |
||
| 38 | use Notifiable, SearchableTrait; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * The table associated with the model. |
||
| 42 | * |
||
| 43 | * @var string |
||
| 44 | */ |
||
| 45 | protected $table = 'servers'; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * The attributes excluded from the model's JSON form. |
||
| 49 | * |
||
| 50 | * @var array |
||
| 51 | */ |
||
| 52 | protected $hidden = ['daemonSecret', 'sftp_password']; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * The attributes that should be mutated to dates. |
||
| 56 | * |
||
| 57 | * @var array |
||
| 58 | */ |
||
| 59 | protected $dates = ['deleted_at']; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * Fields that are not mass assignable. |
||
| 63 | * |
||
| 64 | * @var array |
||
| 65 | */ |
||
| 66 | protected $guarded = ['id', 'installed', 'created_at', 'updated_at', 'deleted_at']; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * Cast values to correct type. |
||
| 70 | * |
||
| 71 | * @var array |
||
| 72 | */ |
||
| 73 | protected $casts = [ |
||
| 74 | 'node_id' => 'integer', |
||
| 75 | 'skip_scripts' => 'boolean', |
||
| 76 | 'suspended' => 'integer', |
||
| 77 | 'owner_id' => 'integer', |
||
| 78 | 'memory' => 'integer', |
||
| 79 | 'swap' => 'integer', |
||
| 80 | 'disk' => 'integer', |
||
| 81 | 'io' => 'integer', |
||
| 82 | 'cpu' => 'integer', |
||
| 83 | 'oom_disabled' => 'integer', |
||
| 84 | 'allocation_id' => 'integer', |
||
| 85 | 'service_id' => 'integer', |
||
| 86 | 'option_id' => 'integer', |
||
| 87 | 'pack_id' => 'integer', |
||
| 88 | 'installed' => 'integer', |
||
| 89 | ]; |
||
| 90 | |||
| 91 | /** |
||
| 92 | * Parameters for search querying. |
||
| 93 | * |
||
| 94 | * @var array |
||
| 95 | */ |
||
| 96 | protected $searchable = [ |
||
| 97 | 'columns' => [ |
||
| 98 | 'servers.name' => 10, |
||
| 99 | 'servers.username' => 10, |
||
| 100 | 'servers.uuidShort' => 9, |
||
| 101 | 'servers.uuid' => 8, |
||
| 102 | 'packs.name' => 7, |
||
| 103 | 'users.email' => 6, |
||
| 104 | 'users.username' => 6, |
||
| 105 | 'nodes.name' => 2, |
||
| 106 | ], |
||
| 107 | 'joins' => [ |
||
| 108 | 'packs' => ['packs.id', 'servers.pack_id'], |
||
| 109 | 'users' => ['users.id', 'servers.owner_id'], |
||
| 110 | 'nodes' => ['nodes.id', 'servers.node_id'], |
||
| 111 | ], |
||
| 112 | ]; |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Returns a single server specified by UUID. |
||
| 116 | * DO NOT USE THIS TO MODIFY SERVER DETAILS OR SAVE THOSE DETAILS. |
||
| 117 | * YOU WILL OVERWRITE THE SECRET KEY AND BREAK THINGS. |
||
| 118 | * |
||
| 119 | * @param string $uuid |
||
| 120 | * @param array $with |
||
| 121 | * @param array $withCount |
||
| 122 | * @return \Pterodactyl\Models\Server |
||
| 123 | * @todo Remove $with and $withCount due to cache issues, they aren't used anyways. |
||
| 124 | */ |
||
| 125 | public static function byUuid($uuid, array $with = [], array $withCount = []) |
||
| 126 | { |
||
| 127 | if (! Auth::check()) { |
||
| 128 | throw new \Exception('You must call Server:byUuid as an authenticated user.'); |
||
| 129 | } |
||
| 130 | |||
| 131 | // Results are cached because we call this functions a few times on page load. |
||
| 132 | $result = Cache::tags(['Model:Server', 'Model:Server:byUuid:' . $uuid])->remember('Model:Server:byUuid:' . $uuid . Auth::user()->uuid, Carbon::now()->addMinutes(15), function () use ($uuid) { |
||
| 133 | $query = self::with('service', 'node')->where(function ($q) use ($uuid) { |
||
|
0 ignored issues
–
show
|
|||
| 134 | $q->where('uuidShort', $uuid)->orWhere('uuid', $uuid); |
||
| 135 | }); |
||
| 136 | |||
| 137 | if (! Auth::user()->isRootAdmin()) { |
||
| 138 | $query->whereIn('id', Auth::user()->serverAccessArray()); |
||
| 139 | } |
||
| 140 | |||
| 141 | return $query->first(); |
||
| 142 | }); |
||
| 143 | |||
| 144 | if (! is_null($result)) { |
||
| 145 | $result->daemonSecret = Auth::user()->daemonToken($result); |
||
| 146 | } |
||
| 147 | |||
| 148 | return $result; |
||
| 149 | } |
||
| 150 | |||
| 151 | /** |
||
| 152 | * Returns non-administrative headers for accessing a server on the daemon. |
||
| 153 | * |
||
| 154 | * @param Pterodactyl\Models\User|null $user |
||
| 155 | * @return array |
||
| 156 | */ |
||
| 157 | public function guzzleHeaders(User $user = null) |
||
| 158 | { |
||
| 159 | // If no specific user is passed, see if we can find an active |
||
| 160 | // auth session to pull data from. |
||
| 161 | if (is_null($user) && Auth::check()) { |
||
| 162 | $user = Auth::user(); |
||
| 163 | } |
||
| 164 | |||
| 165 | return [ |
||
| 166 | 'X-Access-Server' => $this->uuid, |
||
| 167 | 'X-Access-Token' => ($user) ? $user->daemonToken($this) : $this->daemonSecret, |
||
| 168 | ]; |
||
| 169 | } |
||
| 170 | |||
| 171 | /** |
||
| 172 | * Return an instance of the Guzzle client for this specific server using defined access token. |
||
| 173 | * |
||
| 174 | * @param Pterodactyl\Models\User|null $user |
||
| 175 | * @return \GuzzleHttp\Client |
||
| 176 | */ |
||
| 177 | public function guzzleClient(User $user = null) |
||
| 178 | { |
||
| 179 | return $this->node->guzzleClient($this->guzzleHeaders($user)); |
||
| 180 | } |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Returns javascript object to be embedded on server view pages with relevant information. |
||
| 184 | * |
||
| 185 | * @param array|null $additional |
||
| 186 | * @param array|null $overwrite |
||
| 187 | * @return \Laracasts\Utilities\JavaScript\JavaScriptFacade |
||
| 188 | */ |
||
| 189 | public function js($additional = null, $overwrite = null) |
||
| 190 | { |
||
| 191 | $response = [ |
||
| 192 | 'server' => collect($this->makeVisible('daemonSecret'))->only([ |
||
| 193 | 'uuid', |
||
| 194 | 'uuidShort', |
||
| 195 | 'daemonSecret', |
||
| 196 | 'username', |
||
| 197 | ]), |
||
| 198 | 'node' => collect($this->node)->only([ |
||
| 199 | 'fqdn', |
||
| 200 | 'scheme', |
||
| 201 | 'daemonListen', |
||
| 202 | ]), |
||
| 203 | ]; |
||
| 204 | |||
| 205 | if (is_array($additional)) { |
||
| 206 | $response = array_merge($response, $additional); |
||
| 207 | } |
||
| 208 | |||
| 209 | if (is_array($overwrite)) { |
||
| 210 | $response = $overwrite; |
||
| 211 | } |
||
| 212 | |||
| 213 | return Javascript::put($response); |
||
| 214 | } |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Return the columns available for this table. |
||
| 218 | * |
||
| 219 | * @return array |
||
| 220 | */ |
||
| 221 | public function getTableColumns() |
||
| 222 | { |
||
| 223 | return Schema::getColumnListing($this->getTable()); |
||
| 224 | } |
||
| 225 | |||
| 226 | /** |
||
| 227 | * Gets the user who owns the server. |
||
| 228 | * |
||
| 229 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
| 230 | */ |
||
| 231 | public function user() |
||
| 232 | { |
||
| 233 | return $this->belongsTo(User::class, 'owner_id'); |
||
| 234 | } |
||
| 235 | |||
| 236 | /** |
||
| 237 | * Gets the subusers associated with a server. |
||
| 238 | * |
||
| 239 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
| 240 | */ |
||
| 241 | public function subusers() |
||
| 242 | { |
||
| 243 | return $this->hasMany(Subuser::class); |
||
| 244 | } |
||
| 245 | |||
| 246 | /** |
||
| 247 | * Gets the default allocation for a server. |
||
| 248 | * |
||
| 249 | * @return \Illuminate\Database\Eloquent\Relations\HasOne |
||
| 250 | */ |
||
| 251 | public function allocation() |
||
| 252 | { |
||
| 253 | return $this->hasOne(Allocation::class, 'id', 'allocation_id'); |
||
| 254 | } |
||
| 255 | |||
| 256 | /** |
||
| 257 | * Gets all allocations associated with this server. |
||
| 258 | * |
||
| 259 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
| 260 | */ |
||
| 261 | public function allocations() |
||
| 262 | { |
||
| 263 | return $this->hasMany(Allocation::class, 'server_id'); |
||
| 264 | } |
||
| 265 | |||
| 266 | /** |
||
| 267 | * Gets information for the pack associated with this server. |
||
| 268 | * |
||
| 269 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
| 270 | */ |
||
| 271 | public function pack() |
||
| 272 | { |
||
| 273 | return $this->belongsTo(Pack::class); |
||
| 274 | } |
||
| 275 | |||
| 276 | /** |
||
| 277 | * Gets information for the service associated with this server. |
||
| 278 | * |
||
| 279 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
| 280 | */ |
||
| 281 | public function service() |
||
| 282 | { |
||
| 283 | return $this->belongsTo(Service::class); |
||
| 284 | } |
||
| 285 | |||
| 286 | /** |
||
| 287 | * Gets information for the service option associated with this server. |
||
| 288 | * |
||
| 289 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
| 290 | */ |
||
| 291 | public function option() |
||
| 292 | { |
||
| 293 | return $this->belongsTo(ServiceOption::class); |
||
| 294 | } |
||
| 295 | |||
| 296 | /** |
||
| 297 | * Gets information for the service variables associated with this server. |
||
| 298 | * |
||
| 299 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
| 300 | */ |
||
| 301 | public function variables() |
||
| 302 | { |
||
| 303 | return $this->hasMany(ServerVariable::class); |
||
| 304 | } |
||
| 305 | |||
| 306 | /** |
||
| 307 | * Gets information for the node associated with this server. |
||
| 308 | * |
||
| 309 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
| 310 | */ |
||
| 311 | public function node() |
||
| 312 | { |
||
| 313 | return $this->belongsTo(Node::class); |
||
| 314 | } |
||
| 315 | |||
| 316 | /** |
||
| 317 | * Gets information for the tasks associated with this server. |
||
| 318 | * |
||
| 319 | * @TODO adjust server column in tasks to be server_id |
||
| 320 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
| 321 | */ |
||
| 322 | public function tasks() |
||
| 323 | { |
||
| 324 | return $this->hasMany(Task::class); |
||
| 325 | } |
||
| 326 | |||
| 327 | /** |
||
| 328 | * Gets all databases associated with a server. |
||
| 329 | * |
||
| 330 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
| 331 | */ |
||
| 332 | public function databases() |
||
| 333 | { |
||
| 334 | return $this->hasMany(Database::class); |
||
| 335 | } |
||
| 336 | |||
| 337 | /** |
||
| 338 | * Gets the location of the server. |
||
| 339 | * |
||
| 340 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
| 341 | */ |
||
| 342 | public function location() |
||
| 343 | { |
||
| 344 | return $this->node->location(); |
||
| 345 | } |
||
| 346 | } |
||
| 347 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: