]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Cap the maximum amount of HTTP headers on incoming queries
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 19 Feb 2026 11:02:15 +0000 (12:02 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 2 Apr 2026 07:29:45 +0000 (09:29 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-doh-common.hh
pdns/dnsdistdist/dnsdist-nghttp2-in.cc
pdns/dnsdistdist/doh3.cc

index a3f2bb70671d4389f66fc1b01c9a5ad816007162..0abd5e95247b3c4b5b5efb61ce35e980cf14e3ed 100644 (file)
@@ -37,6 +37,7 @@
 namespace dnsdist::doh
 {
 static constexpr uint32_t MAX_INCOMING_CONCURRENT_STREAMS{100U};
+static constexpr size_t MAX_INCOMING_HTTP_HEADERS{256U};
 
 std::optional<PacketBuffer> getPayloadFromPath(const std::string_view& path);
 }
index 2db6887af9f2176ca01b5475c5b88aa5f3d2d614..1bd69d6823d30ecda804f2048acaef9486643cab 100644 (file)
@@ -1170,6 +1170,12 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const
       if (!query.d_headers) {
         query.d_headers = std::make_unique<HeadersMap>();
       }
+      if (query.d_headers->size() >= dnsdist::doh::MAX_INCOMING_HTTP_HEADERS) {
+        /* be nice but not too nice */
+        VERBOSESLOG(infolog("Too many incoming DoH headers"),
+                    conn->getLogger()->info(Logr::Info, "Too many incoming DoH headers"));
+        return NGHTTP2_ERR_CALLBACK_FAILURE;
+      }
       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API
       query.d_headers->insert({std::string(reinterpret_cast<const char*>(name), nameLen), std::string(valueView)});
     }
index 4b435dc13d5ba80ae2fe34ca7da3b35f3a9c5cde..5c06491d3e477bc933ca050e4a8683c42a02810f 100644 (file)
@@ -761,6 +761,10 @@ static void processH3HeaderEvent(ClientState& clientState, DOH3Frontend& fronten
       std::string_view content(reinterpret_cast<char*>(value), value_len);
       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): Quiche API
       auto* headersptr = reinterpret_cast<dnsdist::doh3::h3_headers_t*>(argp);
+      if (headersptr->size() >= dnsdist::doh::MAX_INCOMING_HTTP_HEADERS) {
+        /* be nice but not too nice */
+        return 1;
+      }
       headersptr->emplace(key, content);
       return 0;
     },