MongoDB has disclosed CVE-2025-14847. This vulnerability allows for up to 48MB of uninitialized heap memory to be leaked without authentication if the attacker has access to the MongoDB server on port 27017. Pritunl servers should never be configured with the MongoDB database open to the internet, even with a password. The Pritunl installation documentation has always instructed the database to be configured with a localhost bind. Assuming the installation instructions were followed, there will be no vulnerability. Having access to the Pritunl web console does not allow the MongoDB vulnerability to be exploited. This can only be exploited with direct access to the MongoDB server on port 27017.
Update the mongodb-org-server package, then run mongod --version and check the version against the patched versions: 8.2.3, 8.0.17, 7.0.28, 6.0.27, 5.0.32, or 4.4.30. If the database is older than 4.4, the mitigation must be used instead. If it is the correct version, run sudo systemctl restart mongod.service to verify the patched version is running. This will not disrupt VPN connections or server availability.
To mitigate the issue without updating the database, disable the vulnerable zlib compression by editing /etc/mongod.conf and adding the compressors option with zlib excluded as shown below. This should be done with caution, as adding an additional net section will result in the previous net section being ignored. With older versions of MongoDB that default the bindIp to 0.0.0.0, this would result in the database becoming open to the internet. For all single instance Pritunl configurations, the bindIp should be 127.0.0.1. Once this is done, run sudo systemctl restart mongod.service.
net:
port: 27017
bindIp: <VERIFY_BIND_IP_IS_INCLUDED>
compression:
compressors: snappy,zstd
The vulnerability is caused by using the buffer size return {output.length()} instead of the decompressed size return {length} set by the decompressor. This results in loading uninitialized memory up to the size of the buffer. The client controls the size of the buffer with compressionHeader.uncompressedSize with a maximum of 48MB set by MaxMessageSizeBytes.
StatusWith<std::size_t> ZlibMessageCompressor::decompressData(ConstDataRange input,
DataRange output) {
uLongf length = output.length();
int ret = ::uncompress(const_cast<Bytef*>(reinterpret_cast<const Bytef*>(output.data())),
&length,
reinterpret_cast<const Bytef*>(input.data()),
input.length());
if (ret != Z_OK) {
return Status{ErrorCodes::BadValue, "Compressed message was invalid or corrupted"};
}
counterHitDecompress(input.length(), output.length());
return {output.length()};
}