From: Otto Moerbeek Date: Thu, 7 May 2026 12:20:38 +0000 (+0200) Subject: Move to a string instead of a boolean flag, as suggested by zeha X-Git-Tag: auth-5.1.0~75^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6ceabcfb984db49ab1fc36bcadd66cd52295f9e1;p=thirdparty%2Fpdns.git Move to a string instead of a boolean flag, as suggested by zeha Signed-off-by: Otto Moerbeek --- diff --git a/builder b/builder index 16bc1604c4..f2c8c68dcc 160000 --- a/builder +++ b/builder @@ -1 +1 @@ -Subproject commit 16bc1604c48821c12b708d7afa88d9612ebdd0da +Subproject commit f2c8c68dccb142152d8e2120b29e597e24222ddc diff --git a/docs/settings.rst b/docs/settings.rst index d9e0639096..aae2ba21bc 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -2261,10 +2261,10 @@ If the webserver should print arguments. ----------------------------------------- .. versionadded:: 5.1.0 -- Boolean -- Default: no +- String +- Default: empty -If the webserver should allow cross origin requests. +The value if the access-control-allow-origin HTTP header to include. This header is not inluded if the value is empty. .. _setting-write-pid: diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 0b8e72af1e..fd56d6e6ca 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -255,7 +255,7 @@ static void declareArguments() ::arg().set("webserver-max-concurrent-connections", "Webserver/API maximum concurrent connections allowed") = "100"; ::arg().set("webserver-connection-timeout", "Webserver/API request/response timeout in seconds") = "5"; ::arg().setSwitch("webserver-hash-plaintext-credentials", "Whether to hash passwords and api keys supplied in plaintext, to prevent keeping the plaintext version in memory at runtime") = "no"; - ::arg().setSwitch("webserver-allow-cross-origin-requests", "If the webserver should allow cross origin requests") = "no"; + ::arg().set("webserver-allow-cross-origin-requests", "Webserver cross origin request header value") = ""; ::arg().setSwitch("query-logging", "Hint backends that queries should be logged") = "no"; diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index 7431074c51..d16352ab4f 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -22,7 +22,7 @@ New settings - The :ref:`setting-yaml-outgoing.max_bytesperq` setting has been introduced to limit the amount of incoming bytes per client query. - The :ref:`setting-yaml-recordcache.max_entry_size` setting has been introduced to limit the maximum size of a stored record set. - The :ref:`setting-yaml-packetcache.max_entry_size` setting has been introduced to limit the maximum size of a packet cache entry. -- The :ref:`setting-yaml-webservice.allow_cross_origin_requests` setting has been introduced, default ``false``. This is a change of behaviour, as older versions do allow cross origin requests. +- The :ref:`setting-yaml-webservice.allow_cross_origin_requests` setting has been introduced, default is not set. This is a change of behaviour, as older versions do set the access-control-allow-origin header. 5.3.0 to 5.4.0 diff --git a/pdns/recursordist/rec-rust-lib/rust/src/web.rs b/pdns/recursordist/rec-rust-lib/rust/src/web.rs index 8cf5c29afc..9c49b5b461 100644 --- a/pdns/recursordist/rec-rust-lib/rust/src/web.rs +++ b/pdns/recursordist/rec-rust-lib/rust/src/web.rs @@ -176,11 +176,13 @@ fn api_wrapper( allow_password: bool, ) { // security headers - if ctx.allow_cross_origin_requests { - headers.insert( - header::ACCESS_CONTROL_ALLOW_ORIGIN, - header::HeaderValue::from_static("*"), - ); + if !ctx.allow_cross_origin_requests.is_empty() { + if let Ok(value) = header::HeaderValue::from_str(&ctx.allow_cross_origin_requests) { + headers.insert( + header::ACCESS_CONTROL_ALLOW_ORIGIN, + value, + ); + } } // XXX AUDIT! @@ -282,7 +284,7 @@ struct Context { logger: cxx::SharedPtr, loglevel: rustmisc::LogLevel, max_request_size: u64, - allow_cross_origin_requests: bool, + allow_cross_origin_requests: String, } // Serve a file @@ -458,10 +460,10 @@ fn collect_options( response.status = 200; methods.push(Method::OPTIONS.to_string()); - if ctx.allow_cross_origin_requests { + if !ctx.allow_cross_origin_requests.is_empty() { response.headers.push(rustweb::KeyValue { key: String::from("access-control-allow-origin"), - value: String::from("*"), + value: String::from(ctx.allow_cross_origin_requests.clone()), }); } @@ -949,7 +951,7 @@ pub fn serveweb( logger: cxx::SharedPtr, loglevel: rustmisc::LogLevel, max_request_size: u64, - allow_cross_origin_requests: bool, + allow_cross_origin_requests: String, ) -> Result<(), std::io::Error> { // Context, atomically reference counted let ctx = Arc::new(Context { @@ -1260,7 +1262,7 @@ mod rustweb { logger: SharedPtr, loglevel: LogLevel, max_request_size: u64, - allow_cross_origin_requests: bool, + allow_cross_origin_requests: String, ) -> Result<()>; } diff --git a/pdns/recursordist/rec-rust-lib/table.py b/pdns/recursordist/rec-rust-lib/table.py index 36b57286eb..e202369d0a 100644 --- a/pdns/recursordist/rec-rust-lib/table.py +++ b/pdns/recursordist/rec-rust-lib/table.py @@ -278,11 +278,11 @@ Static pre-shared authentication key for access to the REST API. Since 4.6.0 the { "name": "allow_cross_origin_requests", "section": "webservice", - "type": LType.Bool, - "default": "false", - "help": "Whether the webserver allows cross-origin HTTP requests", + "type": LType.String, + "default": "", + "help": "Value of access-control-allow-origin HTTP header", "doc": """ -Whether the webserver allows cross-origin HTTP requests. This might allow a malicious website to read metrics provided by the API if a user’s browser has valid credentials cached for the webserver while the user visits the malicious website. +Whether the webserver allows cross-origin HTTP requests. If set, the access-control-cross-origin HTTP header is included with the given value. This might allow a malicious website to read metrics provided by the API if a user’s browser has valid credentials cached for the webserver while the user visits the malicious website. """, "versionadded": "5.5.0", }, diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index a9cd69758b..bfb629d3d1 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -1203,7 +1203,7 @@ void serveRustWeb() // This function returns after having created the web server object that handles the requests. // That object and its runtime are associated with a Posix thread that waits until all tasks are // done, which normally never happens. See rec-rust-lib/rust/src/web.rs for details - pdns::rust::web::rec::serveweb(config, std::move(password), std::move(apikey), std::move(aclPtr), std::move(logPtr), loglevel, arg().asNum("webserver-max-request-size") * 1024ULL * 1024ULL, arg().mustDo("allow-cross-origin-requests")); + pdns::rust::web::rec::serveweb(config, std::move(password), std::move(apikey), std::move(aclPtr), std::move(logPtr), loglevel, arg().asNum("webserver-max-request-size") * 1024ULL * 1024ULL, arg()["allow-cross-origin-requests"]); } static void fromCxxToRust(const HttpResponse& cxxresp, pdns::rust::web::rec::Response& rustResponse) diff --git a/pdns/webserver.cc b/pdns/webserver.cc index 45fb68b5ca..2666334a52 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -147,8 +147,8 @@ void WebServer::registerBareHandler(const string& url, const HandlerFunction& ha void WebServer::apiWrapper(const WebServer::HandlerFunction& handler, HttpRequest* req, HttpResponse* resp, bool allowPassword) { - if (d_allow_cross_origin_requests) { - resp->headers["access-control-allow-origin"] = "*"; + if (!d_allow_cross_origin_requests.empty()) { + resp->headers["access-control-allow-origin"] = d_allow_cross_origin_requests; } if (!d_apikey) { @@ -629,8 +629,8 @@ WebServer::WebServer(std::shared_ptr ccm, string li return; } methods.emplace_back("OPTIONS"); - if (allowCors) { - resp->headers["access-control-allow-origin"] = "*"; + if (!allowCors.empty()) { + resp->headers["access-control-allow-origin"] = allowCors; } resp->headers["access-control-allow-headers"] = "Content-Type, X-API-Key"; resp->headers["access-control-allow-methods"] = boost::algorithm::join(methods, ", "); diff --git a/pdns/webserver.hh b/pdns/webserver.hh index f771bf2fb1..ef299a7593 100644 --- a/pdns/webserver.hh +++ b/pdns/webserver.hh @@ -284,7 +284,7 @@ public: return d_loglevel; }; - void setAllowCrossOriginRequests(bool value) + void setAllowCrossOriginRequests(const std::string& value) { d_allow_cross_origin_requests = value; } @@ -315,7 +315,7 @@ protected: int d_connectiontimeout{5}; // in seconds NetmaskGroup d_acl; - bool d_allow_cross_origin_requests{false}; + std::string d_allow_cross_origin_requests; const string d_logprefix = "[webserver] "; diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index d8b2d6abb0..92170b5e03 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -116,7 +116,7 @@ AuthWebServer::AuthWebServer() : d_ws->setMaxBodySize(::arg().asNum("webserver-max-bodysize")); d_ws->setConnectionTimeout(::arg().asNum("webserver-connection-timeout")); - d_ws->setAllowCrossOriginRequests(arg().mustDo("webserver-allow-cross-origin-requests")); + d_ws->setAllowCrossOriginRequests(arg()["webserver-allow-cross-origin-requests"]); d_ws->bind(); } }