From 6f8c5097e5078f5edf4a22b9159f1694425641dd Mon Sep 17 00:00:00 2001 From: Andras Timar Date: Mon, 28 Oct 2024 11:41:48 +0100 Subject: [PATCH] Option to hide server signature in HTTP response Hiding the server signature reduces the likelihood of targeted attacks by making it harder for attackers to identify the server's configuration. In built-in default configuration security.server_signature is set to false. It is also set to false in coolwsd.xml packaged with production builds. HTTP response header is like: Server: COOLWSD HTTP Server In debug mode security.server_signature is set to true in coolwsd.xml. HTTP response header is like: Server: COOLWSD HTTP Server 24.04.9.1 Signed-off-by: Andras Timar Change-Id: Ie23c2dbc1514e46e2942f558ada2e27d0f108bea --- common/Unit.cpp | 11 +++++++++++ common/Unit.hpp | 3 +++ configure.ac | 4 ++++ coolwsd.xml.in | 1 + net/Socket.cpp | 10 +++++++++- test/HttpRequestTests.cpp | 1 + wsd/COOLWSD.cpp | 1 + 7 files changed, 30 insertions(+), 1 deletion(-) diff --git a/common/Unit.cpp b/common/Unit.cpp index 7b83dbdae4ab4..81384660989ba 100644 --- a/common/Unit.cpp +++ b/common/Unit.cpp @@ -47,6 +47,7 @@ namespace std::thread TimeoutThread; std::mutex TimeoutThreadMutex; std::condition_variable TimeoutConditionVariable; +bool CppunitTesting = false; } // namespace @@ -354,6 +355,16 @@ void UnitBase::rememberInstance(UnitType type, UnitBase* instance) } } +void UnitBase::setCppunitTesting(bool cppunitTesting) +{ + CppunitTesting = cppunitTesting; +} + +bool UnitBase::isCppunitTesting() +{ + return CppunitTesting; +} + int UnitBase::uninit() { // Only in debug builds do we support tests. diff --git a/common/Unit.hpp b/common/Unit.hpp index 21e0cd7ebe048..274d08de8c119 100644 --- a/common/Unit.hpp +++ b/common/Unit.hpp @@ -145,6 +145,9 @@ class UnitBase /// Returns 0 on success. static int uninit(); + static void setCppunitTesting(bool cppunitTesting); + static bool isCppunitTesting(); + /// Do we have a unit test library hooking things & loaded static bool isUnitTesting() { diff --git a/configure.ac b/configure.ac index 42dbacbf0b259..5957a74c7496f 100644 --- a/configure.ac +++ b/configure.ac @@ -421,6 +421,7 @@ bundle_msg="using uglified bundled JS and CSS" LOK_LOG_ASSERTIONS=0 log_asserts_msg="disabled" SSL_VERIFY="true" +SERVER_SIGNATURE="false" # a reasonable default NUM_PRESPAWN_CHILDREN=4 @@ -440,6 +441,7 @@ if test "$enable_debug" = "yes"; then BROWSER_LOGGING="true" debug_msg="low security debugging mode" SSL_VERIFY="false" + SERVER_SIGNATURE="true" # helps attaching to the right process NUM_PRESPAWN_CHILDREN=1 @@ -527,6 +529,8 @@ AC_MSG_RESULT([$SSL_VERIFY]) AC_DEFINE_UNQUOTED([SSL_VERIFY],["$SSL_VERIFY"],[Default SSL Verification mode]) AC_SUBST(SSL_VERIFY) +AC_SUBST(SERVER_SIGNATURE) + dnl check for a file at a path with an env-var with a given suffix AC_DEFUN([CHK_FILE_VAR], dnl env-var, suffix, file-to-match, msg [ diff --git a/coolwsd.xml.in b/coolwsd.xml.in index 25edc0741b5c9..f0b82e848d780 100644 --- a/coolwsd.xml.in +++ b/coolwsd.xml.in @@ -226,6 +226,7 @@ 1 false false + @SERVER_SIGNATURE@ diff --git a/net/Socket.cpp b/net/Socket.cpp index eaf2aaeedf388..57b0df557a71c 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -55,6 +55,8 @@ #include #include #include +#include +#include // Bug in pre C++17 where static constexpr must be defined. Fixed in C++17. constexpr std::chrono::microseconds SocketPoll::DefaultPollTimeoutMicroS; @@ -1732,7 +1734,13 @@ namespace http { std::string getAgentString() { return "COOLWSD HTTP Agent " + Util::getCoolVersion(); } -std::string getServerString() { return "COOLWSD HTTP Server " + Util::getCoolVersion(); } +std::string getServerString() +{ + if (!UnitBase::isCppunitTesting()) + if (config::getBool("security.server_signature", false)) + return "COOLWSD HTTP Server " + Util::getCoolVersion(); + return "COOLWSD HTTP Server"; +} } extern "C" { diff --git a/test/HttpRequestTests.cpp b/test/HttpRequestTests.cpp index f18eafe305727..3de3879e3b94e 100644 --- a/test/HttpRequestTests.cpp +++ b/test/HttpRequestTests.cpp @@ -108,6 +108,7 @@ class HttpRequestTests final : public CPPUNIT_NS::TestFixture = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, sslParams); Poco::Net::SSLManager::instance().initializeClient(nullptr, std::move(invalidCertHandler), std::move(sslContext)); #endif + UnitBase::setCppunitTesting(true); } ~HttpRequestTests() diff --git a/wsd/COOLWSD.cpp b/wsd/COOLWSD.cpp index 75c9e9e9a7bbd..20ce92bc21000 100644 --- a/wsd/COOLWSD.cpp +++ b/wsd/COOLWSD.cpp @@ -2084,6 +2084,7 @@ void COOLWSD::innerInitialize(Poco::Util::Application& self) { "security.seccomp", "true" }, { "security.jwt_expiry_secs", "1800" }, { "security.enable_metrics_unauthenticated", "false" }, + { "security.server_signature", "false" }, { "certificates.database_path", "" }, { "server_name", "" }, { "ssl.ca_file_path", COOLWSD_CONFIGDIR "/ca-chain.cert.pem" },