aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Mitchell <[email protected]>2026-03-04 17:52:54 -0800
committerLiam Mitchell <[email protected]>2026-03-04 17:52:54 -0800
commit1cd70d1e875c2331d8a3c57aa8b0fd7267a63973 (patch)
treea8a70a2e2dc775f76578d19b4cdc04f1a8824265
parentRestore debug logging in zenserver tests (diff)
downloadzen-1cd70d1e875c2331d8a3c57aa8b0fd7267a63973.tar.xz
zen-1cd70d1e875c2331d8a3c57aa8b0fd7267a63973.zip
Allow requests with invalid content-types unless specified in command line or config
-rw-r--r--src/zenserver/storage/projectstore/httpprojectstore.cpp21
-rw-r--r--src/zenserver/storage/projectstore/httpprojectstore.h4
-rw-r--r--src/zenserver/storage/storageconfig.cpp7
-rw-r--r--src/zenserver/storage/storageconfig.h1
-rw-r--r--src/zenserver/storage/zenstorageserver.cpp10
5 files changed, 35 insertions, 8 deletions
diff --git a/src/zenserver/storage/projectstore/httpprojectstore.cpp b/src/zenserver/storage/projectstore/httpprojectstore.cpp
index 575bf4354..fe32fa15b 100644
--- a/src/zenserver/storage/projectstore/httpprojectstore.cpp
+++ b/src/zenserver/storage/projectstore/httpprojectstore.cpp
@@ -535,7 +535,8 @@ HttpProjectService::HttpProjectService(CidStore& Store,
HttpStatsService& StatsService,
AuthMgr& AuthMgr,
OpenProcessCache& InOpenProcessCache,
- JobQueue& InJobQueue)
+ JobQueue& InJobQueue,
+ bool InRestrictContentTypes)
: m_Log(logging::Get("project"))
, m_CidStore(Store)
, m_ProjectStore(Projects)
@@ -544,6 +545,7 @@ HttpProjectService::HttpProjectService(CidStore& Store,
, m_AuthMgr(AuthMgr)
, m_OpenProcessCache(InOpenProcessCache)
, m_JobQueue(InJobQueue)
+, m_RestrictContentTypes(InRestrictContentTypes)
{
ZEN_MEMSCOPE(GetProjectHttpTag());
@@ -1867,8 +1869,8 @@ HttpProjectService::HandleOpLogRequest(HttpRouterRequest& Req)
return HttpReq.WriteResponse(HttpResponseCode::InsufficientStorage);
}
- if (HttpReq.RequestContentType() == HttpContentType::kText ||
- HttpReq.RequestContentType() == HttpContentType::kUnknownContentType)
+ if (m_RestrictContentTypes && (HttpReq.RequestContentType() == HttpContentType::kText ||
+ HttpReq.RequestContentType() == HttpContentType::kUnknownContentType))
{
m_ProjectStats.BadRequestCount++;
return HttpReq.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid request content type");
@@ -2164,8 +2166,8 @@ HttpProjectService::HandleProjectRequest(HttpRouterRequest& Req)
return HttpReq.WriteResponse(HttpResponseCode::InsufficientStorage);
}
- if (HttpReq.RequestContentType() == HttpContentType::kText ||
- HttpReq.RequestContentType() == HttpContentType::kUnknownContentType)
+ if (m_RestrictContentTypes && (HttpReq.RequestContentType() == HttpContentType::kText ||
+ HttpReq.RequestContentType() == HttpContentType::kUnknownContentType))
{
m_ProjectStats.BadRequestCount++;
return HttpReq.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid request content type");
@@ -2582,8 +2584,17 @@ HttpProjectService::HandleRpcRequest(HttpRouterRequest& Req)
CbObject Cb;
switch (PayloadContentType)
{
+ case HttpContentType::kText:
+ case HttpContentType::kUnknownContentType:
case HttpContentType::kJSON:
{
+ if (m_RestrictContentTypes &&
+ (PayloadContentType == HttpContentType::kText || PayloadContentType == HttpContentType::kUnknownContentType))
+ {
+ m_ProjectStats.BadRequestCount++;
+ return HttpReq.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid request content type");
+ }
+
std::string JsonText(reinterpret_cast<const char*>(Payload.GetData()), Payload.GetSize());
Cb = LoadCompactBinaryFromJson(JsonText).AsObject();
if (!Cb)
diff --git a/src/zenserver/storage/projectstore/httpprojectstore.h b/src/zenserver/storage/projectstore/httpprojectstore.h
index b742102a5..1d71329b1 100644
--- a/src/zenserver/storage/projectstore/httpprojectstore.h
+++ b/src/zenserver/storage/projectstore/httpprojectstore.h
@@ -44,7 +44,8 @@ public:
HttpStatsService& StatsService,
AuthMgr& AuthMgr,
OpenProcessCache& InOpenProcessCache,
- JobQueue& InJobQueue);
+ JobQueue& InJobQueue,
+ bool InRestrictContentTypes);
~HttpProjectService();
virtual const char* BaseUri() const override;
@@ -109,6 +110,7 @@ private:
metrics::OperationTiming m_HttpRequests;
RwLock m_ThreadWorkersLock;
Ref<TransferThreadWorkers> m_ThreadWorkers;
+ bool m_RestrictContentTypes;
Ref<TransferThreadWorkers> GetThreadWorkers(bool BoostWorkers, bool SingleThreaded);
};
diff --git a/src/zenserver/storage/storageconfig.cpp b/src/zenserver/storage/storageconfig.cpp
index 0f8ab1e98..99d0f89d7 100644
--- a/src/zenserver/storage/storageconfig.cpp
+++ b/src/zenserver/storage/storageconfig.cpp
@@ -496,6 +496,7 @@ ZenStorageServerConfigurator::AddConfigOptions(LuaConfig::Options& LuaOptions)
LuaOptions.AddOption("security.encryptionaeskey"sv, ServerOptions.EncryptionKey, "encryption-aes-key"sv);
LuaOptions.AddOption("security.encryptionaesiv"sv, ServerOptions.EncryptionIV, "encryption-aes-iv"sv);
LuaOptions.AddOption("security.openidproviders"sv, ServerOptions.AuthConfig);
+ LuaOptions.AddOption("security.restrictcontenttypes"sv, ServerOptions.RestrictContentTypes, "restrict-content-types"sv);
////// workspaces
LuaOptions.AddOption("workspaces.enabled"sv, ServerOptions.WorksSpacesConfig.Enabled, "workspaces-enabled"sv);
@@ -649,6 +650,12 @@ ZenStorageServerCmdLineOptions::AddSecurityOptions(cxxopts::Options& options, Ze
options.add_option("security", "", "openid-provider-url", "Open ID provider URL", cxxopts::value<std::string>(OpenIdProviderUrl), "");
options.add_option("security", "", "openid-client-id", "Open ID client ID", cxxopts::value<std::string>(OpenIdClientId), "");
+ options.add_option("security",
+ "",
+ "restrict-content-types",
+ "Restrict content-type in requests to content-types that are not allowed in CORS simple requests",
+ cxxopts::value<bool>(ServerOptions.RestrictContentTypes),
+ "");
}
void
diff --git a/src/zenserver/storage/storageconfig.h b/src/zenserver/storage/storageconfig.h
index d59d05cf6..bc2dc78c9 100644
--- a/src/zenserver/storage/storageconfig.h
+++ b/src/zenserver/storage/storageconfig.h
@@ -157,6 +157,7 @@ struct ZenStorageServerConfig : public ZenServerConfig
std::filesystem::path PluginsConfigFile; // Path to plugins config file
bool ObjectStoreEnabled = false;
std::string ScrubOptions;
+ bool RestrictContentTypes = false;
};
struct ZenStorageServerCmdLineOptions
diff --git a/src/zenserver/storage/zenstorageserver.cpp b/src/zenserver/storage/zenstorageserver.cpp
index b2cae6482..ea05bd155 100644
--- a/src/zenserver/storage/zenstorageserver.cpp
+++ b/src/zenserver/storage/zenstorageserver.cpp
@@ -205,8 +205,14 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
m_OpenProcessCache = std::make_unique<OpenProcessCache>();
m_ProjectStore = new ProjectStore(*m_CidStore, m_DataRoot / "projects", m_GcManager, ProjectStore::Configuration{});
- m_HttpProjectService.reset(
- new HttpProjectService{*m_CidStore, m_ProjectStore, m_StatusService, m_StatsService, *m_AuthMgr, *m_OpenProcessCache, *m_JobQueue});
+ m_HttpProjectService.reset(new HttpProjectService{*m_CidStore,
+ m_ProjectStore,
+ m_StatusService,
+ m_StatsService,
+ *m_AuthMgr,
+ *m_OpenProcessCache,
+ *m_JobQueue,
+ ServerOptions.RestrictContentTypes});
if (ServerOptions.WorksSpacesConfig.Enabled)
{