mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-07 01:23:52 +00:00
fix(content-pack): reject malicious WCP headers (oversize counts + path traversal)
Three security/robustness guards on unpackZone:
1. fileCount > 1M or infoSize > 16MB rejected upfront — would OOM on
the next allocation.
2. Per-file dataSize > 256MB rejected — single malicious entry could
exhaust memory mid-extraction.
3. Path traversal ('..' or absolute paths) rejected — would write
outside destDir/<zoneName>/ and clobber system files.
WCPs are user-shareable archives, so a hostile pack downloaded from a
forum should not be able to OOM the editor or write to /etc.
This commit is contained in:
parent
53780de6da
commit
c05d421c29
1 changed files with 21 additions and 0 deletions
|
|
@ -107,6 +107,14 @@ bool ContentPacker::unpackZone(const std::string& wcpPath, const std::string& de
|
|||
uint32_t fileCount, infoSize;
|
||||
in.read(reinterpret_cast<char*>(&fileCount), 4);
|
||||
in.read(reinterpret_cast<char*>(&infoSize), 4);
|
||||
// Sanity bounds: a zone with more than 1M files or a 16MB info block is
|
||||
// almost certainly corrupted. Reject early so we don't OOM on a malicious
|
||||
// header before reading the body.
|
||||
if (fileCount > 1'000'000 || infoSize > 16 * 1024 * 1024) {
|
||||
LOG_ERROR("WCP header rejected (fileCount=", fileCount,
|
||||
" infoSize=", infoSize, "): ", wcpPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the info JSON to extract the zone name. packZone stored files
|
||||
// relative to the zone subdirectory (e.g. "MyZone_32_32.adt"), so we
|
||||
|
|
@ -132,6 +140,19 @@ bool ContentPacker::unpackZone(const std::string& wcpPath, const std::string& de
|
|||
|
||||
uint32_t dataSize;
|
||||
in.read(reinterpret_cast<char*>(&dataSize), 4);
|
||||
// Cap individual file size to prevent OOM from a malicious entry.
|
||||
// 256MB per packed file is well above any legitimate content.
|
||||
if (dataSize > 256 * 1024 * 1024) {
|
||||
LOG_ERROR("WCP rejected file ", path, " size ", dataSize, " too large");
|
||||
return false;
|
||||
}
|
||||
// Reject path-traversal attempts. Files like "../../etc/passwd" would
|
||||
// write outside destDir/<zoneName>/ and clobber system files.
|
||||
if (path.find("..") != std::string::npos ||
|
||||
(!path.empty() && path[0] == '/')) {
|
||||
LOG_ERROR("WCP rejected suspicious path: ", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<char> data(dataSize);
|
||||
in.read(data.data(), dataSize);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue