aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/include
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-02-17 14:00:53 +0100
committerGitHub Enterprise <[email protected]>2026-02-17 14:00:53 +0100
commit5e1e23e209eec75a396c18f8eee3d93a9e196bfc (patch)
tree31b2b3938468aacdb0621e8b932cb9e9738ee918 /src/zenhttp/include
parentmisc fixes brought over from sb/proto (#759) (diff)
downloadzen-5e1e23e209eec75a396c18f8eee3d93a9e196bfc.tar.xz
zen-5e1e23e209eec75a396c18f8eee3d93a9e196bfc.zip
add http server root password protection (#757)
- Feature: Added `--security-config-path` option to zenserver to configure security settings - Expects a path to a .json file - Default is an empty path resulting in no extra security settings and legacy behavior - Current support is a top level filter of incoming http requests restricted to the `password` type - `password` type will check the `Authorization` header and match it to the selected authorization strategy - Currently the security settings is very basic and configured to a fixed username+password at startup { "http" { "root": { "filter": { "type": "password", "config": { "password": { "username": "<username>", "password": "<password>" }, "protect-machine-local-requests": false, "unprotected-uris": [ "/health/", "/health/info", "/health/version" ] } } } } }
Diffstat (limited to 'src/zenhttp/include')
-rw-r--r--src/zenhttp/include/zenhttp/httpserver.h7
-rw-r--r--src/zenhttp/include/zenhttp/security/passwordsecurity.h38
-rw-r--r--src/zenhttp/include/zenhttp/security/passwordsecurityfilter.h51
3 files changed, 68 insertions, 28 deletions
diff --git a/src/zenhttp/include/zenhttp/httpserver.h b/src/zenhttp/include/zenhttp/httpserver.h
index cbac06cb6..350532126 100644
--- a/src/zenhttp/include/zenhttp/httpserver.h
+++ b/src/zenhttp/include/zenhttp/httpserver.h
@@ -101,7 +101,8 @@ public:
CbObject ReadPayloadObject();
CbPackage ReadPayloadPackage();
- virtual bool IsLocalMachineRequest() const = 0;
+ virtual bool IsLocalMachineRequest() const = 0;
+ virtual std::string_view GetAuthorizationHeader() const = 0;
/** Respond with payload
@@ -162,8 +163,10 @@ public:
virtual void OnRequestComplete() = 0;
};
-struct IHttpRequestFilter
+class IHttpRequestFilter
{
+public:
+ virtual ~IHttpRequestFilter() {}
enum class Result
{
Forbidden,
diff --git a/src/zenhttp/include/zenhttp/security/passwordsecurity.h b/src/zenhttp/include/zenhttp/security/passwordsecurity.h
index 026c2865b..6b2b548a6 100644
--- a/src/zenhttp/include/zenhttp/security/passwordsecurity.h
+++ b/src/zenhttp/include/zenhttp/security/passwordsecurity.h
@@ -10,43 +10,29 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
-struct PasswordSecurityConfiguration
-{
- std::string Password; // "password"
- bool ProtectMachineLocalRequests = false; // "protect-machine-local-requests"
- std::vector<std::string> UnprotectedUris; // "unprotected-urls"
-};
-
class PasswordSecurity
{
public:
- PasswordSecurity(const PasswordSecurityConfiguration& Config);
+ struct Configuration
+ {
+ std::string Password;
+ bool ProtectMachineLocalRequests = false;
+ std::vector<std::string> UnprotectedUris;
+ };
+
+ explicit PasswordSecurity(const Configuration& Config);
[[nodiscard]] inline std::string_view Password() const { return m_Config.Password; }
[[nodiscard]] inline bool ProtectMachineLocalRequests() const { return m_Config.ProtectMachineLocalRequests; }
- [[nodiscard]] bool IsUnprotectedUri(std::string_view Uri) const;
+ [[nodiscard]] bool IsUnprotectedUri(std::string_view BaseUri, std::string_view RelativeUri) const;
- bool IsAllowed(std::string_view Password, std::string_view Uri, bool IsMachineLocalRequest);
+ bool IsAllowed(std::string_view Password, std::string_view BaseUri, std::string_view RelativeUri, bool IsMachineLocalRequest);
private:
- const PasswordSecurityConfiguration m_Config;
- tsl::robin_map<uint32_t, uint32_t> m_UnprotectedUrlHashes;
+ const Configuration m_Config;
+ tsl::robin_map<uint32_t, uint32_t> m_UnprotectedUriHashes;
};
-/**
- * Expected format (Json)
- * {
- * "password\": \"1234\",
- * "protect-machine-local-requests\": false,
- * "unprotected-urls\": [
- * "/health\",
- * "/health/info\",
- * "/health/version\"
- * ]
- * }
- */
-PasswordSecurityConfiguration ReadPasswordSecurityConfiguration(CbObjectView ConfigObject);
-
void passwordsecurity_forcelink(); // internal
} // namespace zen
diff --git a/src/zenhttp/include/zenhttp/security/passwordsecurityfilter.h b/src/zenhttp/include/zenhttp/security/passwordsecurityfilter.h
new file mode 100644
index 000000000..c098f05ad
--- /dev/null
+++ b/src/zenhttp/include/zenhttp/security/passwordsecurityfilter.h
@@ -0,0 +1,51 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zenhttp/httpserver.h>
+#include <zenhttp/security/passwordsecurity.h>
+
+namespace zen {
+
+class PasswordHttpFilter : public IHttpRequestFilter
+{
+public:
+ static constexpr std::string_view TypeName = "password";
+
+ struct Configuration
+ {
+ PasswordSecurity::Configuration PasswordConfig;
+ std::string AuthenticationTypeString;
+ };
+
+ /**
+ * Expected format (Json)
+ * {
+ * "password": { # "Authorization: Basic <username:password base64 encoded>" style
+ * "username": "<username>",
+ * "password": "<password>"
+ * },
+ * "protect-machine-local-requests": false,
+ * "unprotected-uris": [
+ * "/health/",
+ * "/health/info",
+ * "/health/version"
+ * ]
+ * }
+ */
+ static Configuration ReadConfiguration(CbObjectView Config);
+
+ explicit PasswordHttpFilter(const PasswordHttpFilter::Configuration& Config)
+ : m_PasswordSecurity(Config.PasswordConfig)
+ , m_AuthenticationTypeString(Config.AuthenticationTypeString)
+ {
+ }
+
+ virtual Result FilterRequest(HttpServerRequest& Request) override;
+
+private:
+ PasswordSecurity m_PasswordSecurity;
+ const std::string m_AuthenticationTypeString;
+};
+
+} // namespace zen