From 3a09799e45e3460cdd9a54a73e9932f58eb50e56 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 6 Oct 2023 10:27:47 +0200 Subject: reject known bad bucket names in structured cache (#452) * added string_view helpers for ParseHexBytes/ParseHexNumber * reject known bad buckets in structured cache put handler (32-character hex bucket names are rejected) * also added bucket rejection logic to bucket discovery * added rejected_writes stat to HttpStructuredCache --- src/zenserver/cache/structuredcachestore.cpp | 35 ++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'src/zenserver/cache/structuredcachestore.cpp') diff --git a/src/zenserver/cache/structuredcachestore.cpp b/src/zenserver/cache/structuredcachestore.cpp index 1b6eeca3a..f7960f498 100644 --- a/src/zenserver/cache/structuredcachestore.cpp +++ b/src/zenserver/cache/structuredcachestore.cpp @@ -43,6 +43,21 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { +bool +IsKnownBadBucketName(std::string_view Bucket) +{ + if (Bucket.size() == 32) + { + uint8_t BucketHex[16]; + if (ParseHexBytes(Bucket, BucketHex)) + { + return true; + } + } + + return false; +} + ZenCacheNamespace::ZenCacheNamespace(GcManager& Gc, JobQueue& JobQueue, const std::filesystem::path& RootDir, @@ -459,6 +474,14 @@ ZenCacheStore::Put(const CacheRequestContext& Context, metrics::RequestStats::Scope $(m_PutOps, Value.Value.GetSize()); + // Ad hoc rejection of known bad usage patterns for DDC bucket names + + if (IsKnownBadBucketName(Bucket)) + { + m_RejectedWriteCount++; + return; + } + if (m_WriteLogEnabled) { ZEN_TRACE_CPU("Z$::Get::WriteLog"); @@ -485,6 +508,7 @@ ZenCacheStore::Put(const CacheRequestContext& Context, m_WriteCount++; return; } + ZEN_WARN("request for unknown namespace '{}' in ZenCacheStore::Put [{}] bucket '{}', key '{}'", Context, Namespace, @@ -662,11 +686,12 @@ ZenCacheStore::StorageSize() const ZenCacheStore::CacheStoreStats ZenCacheStore::Stats() { - ZenCacheStore::CacheStoreStats Result{.HitCount = m_HitCount, - .MissCount = m_MissCount, - .WriteCount = m_WriteCount, - .PutOps = m_PutOps.Snapshot(), - .GetOps = m_GetOps.Snapshot()}; + ZenCacheStore::CacheStoreStats Result{.HitCount = m_HitCount, + .MissCount = m_MissCount, + .WriteCount = m_WriteCount, + .RejectedWriteCount = m_RejectedWriteCount, + .PutOps = m_PutOps.Snapshot(), + .GetOps = m_GetOps.Snapshot()}; IterateNamespaces([&](std::string_view NamespaceName, ZenCacheNamespace& Store) { Result.NamespaceStats.emplace_back(NamedNamespaceStats{.NamespaceName = std::string(NamespaceName), .Stats = Store.Stats()}); }); -- cgit v1.2.3