]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
YaHTTP: Enforce max # of request fields and max request line size 14197/head
authorYour Name <remi.gacogne@powerdns.com>
Mon, 15 Apr 2024 13:45:38 +0000 (15:45 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 17 May 2024 12:48:02 +0000 (14:48 +0200)
The default values, 8192 bytes for the maximum request line size and
100 fields, are taken from the default settings of Apache HTTPd:
- https://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline
- https://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfields

Reported by OSS-Fuzz as a timeout in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=67993

ext/yahttp/yahttp/utility.hpp

index 1d5e41efea83faedfaebfbb8c5192897fb48b382..47457e313ae8349a5c4163d6b2daf93bd47a2cd1 100644 (file)
@@ -1,4 +1,13 @@
 #pragma once
+
+#ifndef YAHTTP_MAX_REQUEST_LINE_SIZE
+#define YAHTTP_MAX_REQUEST_LINE_SIZE 8192
+#endif
+
+#ifndef YAHTTP_MAX_REQUEST_FIELDS
+#define YAHTTP_MAX_REQUEST_FIELDS 100
+#endif
+
 namespace YaHTTP {
   static const char *MONTHS[] = {0,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",0}; //<! List of months 
   static const char *DAYS[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat",0}; //<! List of days
@@ -364,7 +373,10 @@ namespace YaHTTP {
        }
     }; //<! static HTTP codes to text mappings
 
-    static strstr_map_t parseUrlParameters(std::string parameters) {
+    static strstr_map_t parseUrlParameters(const std::string& parameters) {
+      if (parameters.size() > YAHTTP_MAX_REQUEST_LINE_SIZE) {
+        return {};
+      }
       std::string::size_type pos = 0;
       strstr_map_t parameter_map;
       while (pos != std::string::npos) {
@@ -390,13 +402,14 @@ namespace YaHTTP {
           // no parameters at all
           break;
         }
-        key = decodeURL(key);
-        value = decodeURL(value);
-        parameter_map[key] = std::move(value);
+        parameter_map[decodeURL(key)] = decodeURL(value);
         if (nextpos == std::string::npos) {
           // no more parameters left
           break;
         }
+        if (parameter_map.size() >= YAHTTP_MAX_REQUEST_FIELDS) {
+          break;
+        }
 
         pos = nextpos+1;
       }