fix: Reject oversized validator manifest before decoding

This commit is contained in:
Bart
2026-07-16 16:21:56 -04:00
committed by Ayaz Salikhov
parent 1dcaf4b54e
commit 7877ee42a0
5 changed files with 76 additions and 18 deletions

View File

@@ -76,24 +76,6 @@ getInverse()
return &kTab[0];
}
/**
* Returns max chars needed to encode a base64 string
*/
constexpr std::size_t
encodedSize(std::size_t n)
{
return 4 * ((n + 2) / 3);
}
/**
* Returns max bytes needed to decode a base64 string
*/
constexpr std::size_t
decodedSize(std::size_t n)
{
return ((n / 4) * 3) + 2;
}
/**
* Encode a series of octets as a padded, base64 string.
*

View File

@@ -62,6 +62,11 @@ deserializeManifest(Slice s, beast::Journal journal)
if (s.empty())
return std::nullopt;
// A valid manifest has a fixed maximum size, so reject anything larger
// before parsing it.
if (s.size() > kMaxManifestBytes)
return std::nullopt;
static SOTemplate const kManifestFormat{
// A manifest must include:
// - the master public key

View File

@@ -1127,6 +1127,15 @@ ValidatorList::applyList(
json::Value list;
auto const& manifest = localManifest ? *localManifest : globalManifest;
// Reject an oversized manifest before decoding it, so we do not allocate
// memory for an input that cannot be a valid manifest. deserializeManifest
// also enforces the decoded-byte limit, but checking here avoids the
// base64 decode entirely.
if (manifest.size() > kMaxManifestBase64)
{
JLOG(j_.warn()) << "UNL manifest exceeds maximum size";
return PublisherListStats{ListDisposition::Invalid};
}
auto m = deserializeManifest(base64Decode(manifest));
if (!m)
{